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

[onert] Introduce metadata to model and loader #12294

Merged
merged 5 commits into from
Dec 19, 2023

Conversation

zetwhite
Copy link
Contributor

@zetwhite zetwhite commented Dec 14, 2023

This PR introduces a metadata field to ir::Model and related loading logic.

draft : #12152
issue : #11692

ONE-DCO-1.0-Signed-off-by: SeungHui Youn sseung.youn@samsung.com

This PR introduces a metadata field to ir::Model and related loading logic.

ONE-DCO-1.0-Signed-off-by: SeungHui Youn <sseung.youn@samsung.com>
@@ -47,6 +47,7 @@ template <typename LoaderDomain> class BaseLoader
using Buffer = typename LoaderDomain::Buffer;
using BuiltinOperator = typename LoaderDomain::BuiltinOperator;
using CustomOptionsFormat = typename LoaderDomain::CustomOptionsFormat;
using Metadata = typename LoaderDomain::Metadata;
Copy link
Contributor Author

@zetwhite zetwhite Dec 14, 2023

Choose a reason for hiding this comment

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

Since both tflite and circle have metadata, Let add Metadata and loadMetadata in base_loader.

@zetwhite zetwhite added the approval: 2 Require at least 2 approvals label Dec 14, 2023
@jyoungyun jyoungyun requested a review from a team December 14, 2023 05:38
@zetwhite zetwhite requested a review from a team December 14, 2023 06:32
@zetwhite zetwhite added the PR/ready for review It is ready to review. Please review it. label Dec 14, 2023
hseok-oh
hseok-oh previously approved these changes Dec 14, 2023
Copy link
Contributor

@hseok-oh hseok-oh left a comment

Choose a reason for hiding this comment

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

LGTM

ragmani
ragmani previously approved these changes Dec 18, 2023
Copy link
Contributor

@ragmani ragmani left a comment

Choose a reason for hiding this comment

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

LGTM

@glistening
Copy link
Contributor

I am waiting for is_metadata_exist is renamed.

ONE-DCO-1.0-Signed-off-by: SeungHui Youn <sseung.youn@samsung.com>
ONE-DCO-1.0-Signed-off-by: SeungHui Youn <sseung.youn@samsung.com>
@zetwhite
Copy link
Contributor Author

updated method name exists_metadata - 2eddc06
updated get_metadata to return unique_ptr - 2eddc06

throw std::out_of_range{"no meatdata named " + name};

auto data = std::move(m->second);
_metadatas.erase(m);
Copy link
Contributor

Choose a reason for hiding this comment

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

@zetwhite It doesn't look intuitive to erase the metadata after get_metadata. Do we need to return unique_ptr?

Copy link
Contributor Author

@zetwhite zetwhite Dec 18, 2023

Choose a reason for hiding this comment

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

Umm, I've also thought about returning const raw ptr instead of unique_ptr.

I think that returning unique_ptr is much safer.
I'm a little afraid that under situation happened with const raw ptr.

 // load model from file
std::unique_ptr<ir::Model> model = laodModel();
 
// get buffer
const ir::Data* metadata_buffer = model->get_metadata("CIRCLE_TRAINING"); 

// delete a model
// Since the model holds unique_ptr of metadata, all metadata are also deleted.
model.reset(); 

// access already freed memory space (use after free) 
auto base = metadata_buffer->base;

Copy link
Contributor Author

@zetwhite zetwhite Dec 18, 2023

Choose a reason for hiding this comment

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

Since ir::Model doesn't know how methods can be used, I thought it is better to use unique_ptr for safety.
If you have a better idea about this, plz let me know!

+) If erasing logic with a get_metadata is unintuitive, we could try other naming instead of get_metadata - 🤔 🤔 maybe extract_metadata?

Copy link
Contributor

@ragmani ragmani Dec 18, 2023

Choose a reason for hiding this comment

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

@zetwhite

+) If erasing metadata afterget_metadata is un-intutive, we could find a bettter naming instead of get_metadata- 🤔 🤔 maybe extract_metadata?

extract_metadata looks better to me.

Since ir::Model doesn't know how methods can be used, I thought it is better to use unique_ptr for safety.
Do you have better idea about this, plz let me know!

I also think unique_ptr is safer. But I'm not familiar with providing only functions for adding/extracting a data type in a class(ir::Model) without providing functions for getting/eliminating the data type(ir::Data).
How about introducing a class for metadata into onert? If so, you can prevent the problem you worried about by adjusting the introduced class (i.g. introducing getting const reference of metadata class into ir::Model and deleting copy constructor of metadata class). Furthermore, you can take advantage of easily adding functions related to metadata.

Copy link
Contributor

@glistening glistening Dec 19, 2023

Choose a reason for hiding this comment

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

I don't object to use unique_ptr. unique_ptr is good thing to prevent memory leak. I just don't want to get the user surprised the metadata is removed after get_metadata. If you choose to remove metadata (though I don't like it), it would be better to rename which says clearly the metadata will not be available once you get it. At least for me, extract does not say. I tried to find more appropriate word (release, move, transfer, ...), but these are not clear also.

Once again, I don't oppose this PR if it gets two approvals. It will be merged.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

How about introducing a class for metadata into onert? If so, you can prevent the problem you worried about by adjusting the introduced class (i.g. introducing getting const reference of metadata class into ir::Model and deleting copy constructor of metadata class). Furthermore, you can take advantage of easily adding functions related to metadata.

@ragmani Thanks for thinking together. I failed to fully understand your suggestion.
If we return a 'const reference of metadata' from get_metadata, Does it extend the lifetime of metadata, even if the model instance is deleted?

Furthermore, you can take advantage of easily adding functions related to metadata.

(not important, but for sharing opinion)
Umm.. I think there are not many functions needed for metadata. Since metadata in a model is just a buffer(not parsed yet), there aren't many common things between metadata.
So, This advantage is not very attractive to me.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For now, I'd like to rename get_metadata to extract_metadata and add some comments for ir::Model user.

If I could get 2 approvals, let it proceed.
Or Let me try to find another solution.

(note) I get the word extract from c++17 std.

unlinks the node that contains the element pointed to by position and returns a node handle that owns it.
(https://en.cppreference.com/w/cpp/container/map/extract)

Copy link
Contributor

Choose a reason for hiding this comment

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

Wow, I didn't know map.extract(). Then, we may replace the body of extract_metadata:

    auto m = _metadatas.find(name);

    if (m == _metadatas.end())
      throw std::out_of_range{"no meatdata named " + name};

    auto data = std::move(m->second);
    _metadatas.erase(m);
    return data;

with:

   // After c++17
   return std::move(_metadatas.extract(name).mapped());

Copy link
Contributor

Choose a reason for hiding this comment

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

If we return a 'const reference of metadata' from get_metadata, Does it extend the lifetime of metadata, even if the model instance is deleted?

No, it does not extend lifetime of metadata. If the reference exists and the model instance is deleted, the reference is a dangling reference.

(not important, but for sharing opinion)
Umm.. I think there are not many functions needed for metadata. Since metadata in a model is just a buffer(not parsed yet), there aren't many common things between metadata.
So, This advantage is not very attractive to me.

I see, it was just a suggestion.

hseok-oh
hseok-oh previously approved these changes Dec 18, 2023
ONE-DCO-1.0-Signed-off-by: SeungHui Youn <sseung.youn@samsung.com>

// Since metadata is not access often in inference/training time, always use mmaped-data
// Ref : https://github.com/Samsung/ONE/issues/3961#issuecomment-681750231
return std::make_unique<ir::MMapedData>(_fd, page_start, mapping_size, offset_start, data_size);
Copy link
Contributor

Choose a reason for hiding this comment

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

_fd must outlive returned std::unique_ptr<ir::Data>. Currently @zetwhite is going to convert ir::Data to TrainingInfo in model loading phase. Thus, it will be safe at this moment.

Copy link
Contributor Author

@zetwhite zetwhite Dec 19, 2023

Choose a reason for hiding this comment

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

Ah, I also worried about this part.

As I searched, there is no need to keep _fd(file descriptor) open after mmaped.


I refered this : https://stackoverflow.com/questions/17490033/do-i-need-to-keep-a-file-open-after-calling-mmap-on-it

  • From Posix manpage ref

The mmap() function adds an extra reference to the file associated with the file descriptor fildes which is not removed by a subsequent close() on that file descriptor. This reference is removed when there are no more mappings to the file.

  • From Linux manpage ref

On the other hand, closing the file descriptor does not unmap the region.

Copy link
Contributor

@glistening glistening left a comment

Choose a reason for hiding this comment

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

LGTM 👍

Copy link
Contributor

@ragmani ragmani left a comment

Choose a reason for hiding this comment

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

LGTM

@glistening glistening merged commit 53f62ea into Samsung:master Dec 19, 2023
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approval: 2 Require at least 2 approvals PR/ready for review It is ready to review. Please review it.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants