[microNPU][4] Add the cascader Proposal generator - #9959

Merged
manupak merged 2 commits into
apache:mainfrom
mbaret:ethosu-cascader-7
Feb 24, 2022
Merged

[microNPU][4] Add the cascader Proposal generator#9959
manupak merged 2 commits into
apache:mainfrom
mbaret:ethosu-cascader-7

Conversation

@mbaret

@mbaretmbaret commented Jan 18, 2022

Copy link
Copy Markdown
Contributor

RFC: apache/tvm-rfcs#37
Issue: #9429

The Proposal generator takes optimal Plans and combines them to find optimal 'Proposals' - sets of disjoint Plans that cover every Part in a CascaderGraph. It ultimately produces a Pareto-frontier of 'optimal' Proposals in terms of estimated cycles and memory usage.

The Proposal generator takes optimal Plans and combines
them to find optimal 'Proposals' - sets of disjoint
Plans that cover every Part in a CascaderGraph. It
ultimately produces a Pareto-frontier of 'optimal'
Proposals in terms of estimated cycles and memory usage.
Change-Id: Id42099819a596496a5769bae22f08eeb75ec69b6
Change-Id: I4f5f2a298bd3bb379c7c8d179150358923b0dd66

@manupakmanupak 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 @mbaret .

I have let some comments; some questions, some for more docs and some for slight refactors.
Happy to take these in a follow up to allow reviews of other PRs stacked on top of this.

I think we should try to progress this PR.

std::sort(proposals.begin(), proposals.end(), [](const Proposal& a, const Proposal& b) -> bool {
return a->GetMemoryUsage() < b->GetMemoryUsage();
});
std::vector<std::array<float, 2>> costs;

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 future : it might be better to use a typed struct here

namespace ethosu {
namespace cascader {

std::unordered_set<TensorConfig> GetPlanBoundaryConfigs(const Plan& plan) {

@manupakmanupakFeb 16, 2022

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.

Should we have docs for this function ?

return boundary_configs;
}

bool IsPlanCompatible(const Proposal& proposal, const std::vector<Part>& plan_part_group,

@manupakmanupakFeb 16, 2022

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.

Should we have docs for this function ?

return true;
}

std::unordered_map<Part, std::vector<Plan>, ObjectPtrHash, ObjectPtrEqual> CreatePlansByPart(

@manupakmanupakFeb 16, 2022

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.

Should we have docs for this function ?

return plans_by_part;
}

Proposal AddPlanToProposal(const Proposal& proposal, const Plan& plan,

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.

Should we have docs for this functions ?

return std::find(plan->GetPartGroup().begin(), plan->GetPartGroup().end(),
value) == plan->GetPartGroup().end();
});
// std::sort(residual_proposal_group.begin(), residual_proposal_group.end());

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.

remove ?

const CascaderGraph& graph, const HomeMap& home_map, const CascaderOptions options,
const std::unordered_map<Part, std::vector<Plan>, ObjectPtrHash, ObjectPtrEqual>& plans_by_part,
const std::vector<Part>& partial_proposal_group,
std::unordered_map<std::vector<Part>, std::vector<Proposal>>* proposals_by_group) {

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.

Just curious, what is the reasoning to use a pointer as opposed to references elsewhere ?

value) == plan->GetPartGroup().end();
});
// std::sort(residual_proposal_group.begin(), residual_proposal_group.end());
const auto& residual_proposals = GeneratePartialProposals(

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.

A comment would help here to differentiate between "residual_proposal_group" vs "residual_proposals"

value) == plan->GetPartGroup().end();
});
// std::sort(residual_proposal_group.begin(), residual_proposal_group.end());
const auto& residual_proposals = GeneratePartialProposals(

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.

It also feels like constant context data is passed onto the recursive call that does not change between calls.
Should we restructure this to be a class to hold such data (e.g. graph, home_map, proposals_by_group) ?

std::unordered_map<Tensor, std::vector<MemoryRegion>, ObjectPtrHash, ObjectPtrEqual>
mhome_map;
for (const auto& it : home_map) {
std::vector<MemoryRegion> home_regions;

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.

Did not we have a utility to convert Arrays to Vectors somewhere ?

@manupak

Copy link
Copy Markdown
Contributor

We can unblock the reviews of the next PR, if we could address the comments of this PR in a seperate follow up PR.
WDYT @mbaret ?

@manupakmanupak added the status: need update need update based on feedbacks label Feb 23, 2022
@mbaret

Copy link
Copy Markdown
ContributorAuthor

Yup, happy to take it as a follow up.

@manupakmanupak 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! (bar the comments that is deffered to the follow up)

@manupak
manupak merged commit f1ff61a into apache:mainFeb 24, 2022
@manupak

Copy link
Copy Markdown
Contributor

Thanks! @mbaret

pfk-beta pushed a commit to pfk-beta/tvm that referenced this pull request Apr 11, 2022
* [microNPU][4] Add the cascader Proposal generator
The Proposal generator takes optimal Plans and combines
them to find optimal 'Proposals' - sets of disjoint
Plans that cover every Part in a CascaderGraph. It
ultimately produces a Pareto-frontier of 'optimal'
Proposals in terms of estimated cycles and memory usage.
Change-Id: Id42099819a596496a5769bae22f08eeb75ec69b6
* Fixes
Change-Id: I4f5f2a298bd3bb379c7c8d179150358923b0dd66
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status: need updateneed update based on feedbacks

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@mbaret@manupak
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

[microNPU][4] Add the cascader Proposal generator - #9959

Merged
manupak merged 2 commits into
apache:mainfrom
mbaret:ethosu-cascader-7
Feb 24, 2022
Merged

[microNPU][4] Add the cascader Proposal generator#9959
manupak merged 2 commits into
apache:mainfrom
mbaret:ethosu-cascader-7

Conversation

@mbaret

@mbaretmbaret commented Jan 18, 2022

Copy link
Copy Markdown
Contributor

RFC: apache/tvm-rfcs#37
Issue: #9429

The Proposal generator takes optimal Plans and combines them to find optimal 'Proposals' - sets of disjoint Plans that cover every Part in a CascaderGraph. It ultimately produces a Pareto-frontier of 'optimal' Proposals in terms of estimated cycles and memory usage.

The Proposal generator takes optimal Plans and combines
them to find optimal 'Proposals' - sets of disjoint
Plans that cover every Part in a CascaderGraph. It
ultimately produces a Pareto-frontier of 'optimal'
Proposals in terms of estimated cycles and memory usage.
Change-Id: Id42099819a596496a5769bae22f08eeb75ec69b6
Change-Id: I4f5f2a298bd3bb379c7c8d179150358923b0dd66

@manupakmanupak 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 @mbaret .

I have let some comments; some questions, some for more docs and some for slight refactors.
Happy to take these in a follow up to allow reviews of other PRs stacked on top of this.

I think we should try to progress this PR.

std::sort(proposals.begin(), proposals.end(), [](const Proposal& a, const Proposal& b) -> bool {
return a->GetMemoryUsage() < b->GetMemoryUsage();
});
std::vector<std::array<float, 2>> costs;

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 future : it might be better to use a typed struct here

namespace ethosu {
namespace cascader {

std::unordered_set<TensorConfig> GetPlanBoundaryConfigs(const Plan& plan) {

@manupakmanupakFeb 16, 2022

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.

Should we have docs for this function ?

return boundary_configs;
}

bool IsPlanCompatible(const Proposal& proposal, const std::vector<Part>& plan_part_group,

@manupakmanupakFeb 16, 2022

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.

Should we have docs for this function ?

return true;
}

std::unordered_map<Part, std::vector<Plan>, ObjectPtrHash, ObjectPtrEqual> CreatePlansByPart(

@manupakmanupakFeb 16, 2022

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.

Should we have docs for this function ?

return plans_by_part;
}

Proposal AddPlanToProposal(const Proposal& proposal, const Plan& plan,

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.

Should we have docs for this functions ?

return std::find(plan->GetPartGroup().begin(), plan->GetPartGroup().end(),
value) == plan->GetPartGroup().end();
});
// std::sort(residual_proposal_group.begin(), residual_proposal_group.end());

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.

remove ?

const CascaderGraph& graph, const HomeMap& home_map, const CascaderOptions options,
const std::unordered_map<Part, std::vector<Plan>, ObjectPtrHash, ObjectPtrEqual>& plans_by_part,
const std::vector<Part>& partial_proposal_group,
std::unordered_map<std::vector<Part>, std::vector<Proposal>>* proposals_by_group) {

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.

Just curious, what is the reasoning to use a pointer as opposed to references elsewhere ?

value) == plan->GetPartGroup().end();
});
// std::sort(residual_proposal_group.begin(), residual_proposal_group.end());
const auto& residual_proposals = GeneratePartialProposals(

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.

A comment would help here to differentiate between "residual_proposal_group" vs "residual_proposals"

value) == plan->GetPartGroup().end();
});
// std::sort(residual_proposal_group.begin(), residual_proposal_group.end());
const auto& residual_proposals = GeneratePartialProposals(

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.

It also feels like constant context data is passed onto the recursive call that does not change between calls.
Should we restructure this to be a class to hold such data (e.g. graph, home_map, proposals_by_group) ?

std::unordered_map<Tensor, std::vector<MemoryRegion>, ObjectPtrHash, ObjectPtrEqual>
mhome_map;
for (const auto& it : home_map) {
std::vector<MemoryRegion> home_regions;

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.

Did not we have a utility to convert Arrays to Vectors somewhere ?

@manupak

Copy link
Copy Markdown
Contributor

We can unblock the reviews of the next PR, if we could address the comments of this PR in a seperate follow up PR.
WDYT @mbaret ?

@manupakmanupak added the status: need update need update based on feedbacks label Feb 23, 2022
@mbaret

Copy link
Copy Markdown
ContributorAuthor

Yup, happy to take it as a follow up.

@manupakmanupak 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! (bar the comments that is deffered to the follow up)

@manupak
manupak merged commit f1ff61a into apache:mainFeb 24, 2022
@manupak

Copy link
Copy Markdown
Contributor

Thanks! @mbaret

pfk-beta pushed a commit to pfk-beta/tvm that referenced this pull request Apr 11, 2022
* [microNPU][4] Add the cascader Proposal generator
The Proposal generator takes optimal Plans and combines
them to find optimal 'Proposals' - sets of disjoint
Plans that cover every Part in a CascaderGraph. It
ultimately produces a Pareto-frontier of 'optimal'
Proposals in terms of estimated cycles and memory usage.
Change-Id: Id42099819a596496a5769bae22f08eeb75ec69b6
* Fixes
Change-Id: I4f5f2a298bd3bb379c7c8d179150358923b0dd66
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status: need updateneed update based on feedbacks

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@mbaret@manupak
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

[microNPU][4] Add the cascader Proposal generator - #9959

Merged
manupak merged 2 commits into
apache:mainfrom
mbaret:ethosu-cascader-7
Feb 24, 2022
Merged

[microNPU][4] Add the cascader Proposal generator#9959
manupak merged 2 commits into
apache:mainfrom
mbaret:ethosu-cascader-7

Conversation

@mbaret

@mbaretmbaret commented Jan 18, 2022

Copy link
Copy Markdown
Contributor

RFC: apache/tvm-rfcs#37
Issue: #9429

The Proposal generator takes optimal Plans and combines them to find optimal 'Proposals' - sets of disjoint Plans that cover every Part in a CascaderGraph. It ultimately produces a Pareto-frontier of 'optimal' Proposals in terms of estimated cycles and memory usage.

The Proposal generator takes optimal Plans and combines
them to find optimal 'Proposals' - sets of disjoint
Plans that cover every Part in a CascaderGraph. It
ultimately produces a Pareto-frontier of 'optimal'
Proposals in terms of estimated cycles and memory usage.
Change-Id: Id42099819a596496a5769bae22f08eeb75ec69b6
Change-Id: I4f5f2a298bd3bb379c7c8d179150358923b0dd66

@manupakmanupak 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 @mbaret .

I have let some comments; some questions, some for more docs and some for slight refactors.
Happy to take these in a follow up to allow reviews of other PRs stacked on top of this.

I think we should try to progress this PR.

std::sort(proposals.begin(), proposals.end(), [](const Proposal& a, const Proposal& b) -> bool {
return a->GetMemoryUsage() < b->GetMemoryUsage();
});
std::vector<std::array<float, 2>> costs;

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 future : it might be better to use a typed struct here

namespace ethosu {
namespace cascader {

std::unordered_set<TensorConfig> GetPlanBoundaryConfigs(const Plan& plan) {

@manupakmanupakFeb 16, 2022

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.

Should we have docs for this function ?

return boundary_configs;
}

bool IsPlanCompatible(const Proposal& proposal, const std::vector<Part>& plan_part_group,

@manupakmanupakFeb 16, 2022

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.

Should we have docs for this function ?

return true;
}

std::unordered_map<Part, std::vector<Plan>, ObjectPtrHash, ObjectPtrEqual> CreatePlansByPart(

@manupakmanupakFeb 16, 2022

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.

Should we have docs for this function ?

return plans_by_part;
}

Proposal AddPlanToProposal(const Proposal& proposal, const Plan& plan,

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.

Should we have docs for this functions ?

return std::find(plan->GetPartGroup().begin(), plan->GetPartGroup().end(),
value) == plan->GetPartGroup().end();
});
// std::sort(residual_proposal_group.begin(), residual_proposal_group.end());

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.

remove ?

const CascaderGraph& graph, const HomeMap& home_map, const CascaderOptions options,
const std::unordered_map<Part, std::vector<Plan>, ObjectPtrHash, ObjectPtrEqual>& plans_by_part,
const std::vector<Part>& partial_proposal_group,
std::unordered_map<std::vector<Part>, std::vector<Proposal>>* proposals_by_group) {

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.

Just curious, what is the reasoning to use a pointer as opposed to references elsewhere ?

value) == plan->GetPartGroup().end();
});
// std::sort(residual_proposal_group.begin(), residual_proposal_group.end());
const auto& residual_proposals = GeneratePartialProposals(

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.

A comment would help here to differentiate between "residual_proposal_group" vs "residual_proposals"

value) == plan->GetPartGroup().end();
});
// std::sort(residual_proposal_group.begin(), residual_proposal_group.end());
const auto& residual_proposals = GeneratePartialProposals(

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.

It also feels like constant context data is passed onto the recursive call that does not change between calls.
Should we restructure this to be a class to hold such data (e.g. graph, home_map, proposals_by_group) ?

std::unordered_map<Tensor, std::vector<MemoryRegion>, ObjectPtrHash, ObjectPtrEqual>
mhome_map;
for (const auto& it : home_map) {
std::vector<MemoryRegion> home_regions;

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.

Did not we have a utility to convert Arrays to Vectors somewhere ?

@manupak

Copy link
Copy Markdown
Contributor

We can unblock the reviews of the next PR, if we could address the comments of this PR in a seperate follow up PR.
WDYT @mbaret ?

@manupakmanupak added the status: need update need update based on feedbacks label Feb 23, 2022
@mbaret

Copy link
Copy Markdown
ContributorAuthor

Yup, happy to take it as a follow up.

@manupakmanupak 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! (bar the comments that is deffered to the follow up)

@manupak
manupak merged commit f1ff61a into apache:mainFeb 24, 2022
@manupak

Copy link
Copy Markdown
Contributor

Thanks! @mbaret

pfk-beta pushed a commit to pfk-beta/tvm that referenced this pull request Apr 11, 2022
* [microNPU][4] Add the cascader Proposal generator
The Proposal generator takes optimal Plans and combines
them to find optimal 'Proposals' - sets of disjoint
Plans that cover every Part in a CascaderGraph. It
ultimately produces a Pareto-frontier of 'optimal'
Proposals in terms of estimated cycles and memory usage.
Change-Id: Id42099819a596496a5769bae22f08eeb75ec69b6
* Fixes
Change-Id: I4f5f2a298bd3bb379c7c8d179150358923b0dd66
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status: need updateneed update based on feedbacks

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@mbaret@manupak
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

[microNPU][4] Add the cascader Proposal generator - #9959

Merged
manupak merged 2 commits into
apache:mainfrom
mbaret:ethosu-cascader-7
Feb 24, 2022
Merged

[microNPU][4] Add the cascader Proposal generator#9959
manupak merged 2 commits into
apache:mainfrom
mbaret:ethosu-cascader-7

Conversation

@mbaret

@mbaretmbaret commented Jan 18, 2022

Copy link
Copy Markdown
Contributor

RFC: apache/tvm-rfcs#37
Issue: #9429

The Proposal generator takes optimal Plans and combines them to find optimal 'Proposals' - sets of disjoint Plans that cover every Part in a CascaderGraph. It ultimately produces a Pareto-frontier of 'optimal' Proposals in terms of estimated cycles and memory usage.

The Proposal generator takes optimal Plans and combines
them to find optimal 'Proposals' - sets of disjoint
Plans that cover every Part in a CascaderGraph. It
ultimately produces a Pareto-frontier of 'optimal'
Proposals in terms of estimated cycles and memory usage.
Change-Id: Id42099819a596496a5769bae22f08eeb75ec69b6
Change-Id: I4f5f2a298bd3bb379c7c8d179150358923b0dd66

@manupakmanupak 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 @mbaret .

I have let some comments; some questions, some for more docs and some for slight refactors.
Happy to take these in a follow up to allow reviews of other PRs stacked on top of this.

I think we should try to progress this PR.

std::sort(proposals.begin(), proposals.end(), [](const Proposal& a, const Proposal& b) -> bool {
return a->GetMemoryUsage() < b->GetMemoryUsage();
});
std::vector<std::array<float, 2>> costs;

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 future : it might be better to use a typed struct here

namespace ethosu {
namespace cascader {

std::unordered_set<TensorConfig> GetPlanBoundaryConfigs(const Plan& plan) {

@manupakmanupakFeb 16, 2022

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.

Should we have docs for this function ?

return boundary_configs;
}

bool IsPlanCompatible(const Proposal& proposal, const std::vector<Part>& plan_part_group,

@manupakmanupakFeb 16, 2022

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.

Should we have docs for this function ?

return true;
}

std::unordered_map<Part, std::vector<Plan>, ObjectPtrHash, ObjectPtrEqual> CreatePlansByPart(

@manupakmanupakFeb 16, 2022

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.

Should we have docs for this function ?

return plans_by_part;
}

Proposal AddPlanToProposal(const Proposal& proposal, const Plan& plan,

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.

Should we have docs for this functions ?

return std::find(plan->GetPartGroup().begin(), plan->GetPartGroup().end(),
value) == plan->GetPartGroup().end();
});
// std::sort(residual_proposal_group.begin(), residual_proposal_group.end());

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.

remove ?

const CascaderGraph& graph, const HomeMap& home_map, const CascaderOptions options,
const std::unordered_map<Part, std::vector<Plan>, ObjectPtrHash, ObjectPtrEqual>& plans_by_part,
const std::vector<Part>& partial_proposal_group,
std::unordered_map<std::vector<Part>, std::vector<Proposal>>* proposals_by_group) {

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.

Just curious, what is the reasoning to use a pointer as opposed to references elsewhere ?

value) == plan->GetPartGroup().end();
});
// std::sort(residual_proposal_group.begin(), residual_proposal_group.end());
const auto& residual_proposals = GeneratePartialProposals(

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.

A comment would help here to differentiate between "residual_proposal_group" vs "residual_proposals"

value) == plan->GetPartGroup().end();
});
// std::sort(residual_proposal_group.begin(), residual_proposal_group.end());
const auto& residual_proposals = GeneratePartialProposals(

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.

It also feels like constant context data is passed onto the recursive call that does not change between calls.
Should we restructure this to be a class to hold such data (e.g. graph, home_map, proposals_by_group) ?

std::unordered_map<Tensor, std::vector<MemoryRegion>, ObjectPtrHash, ObjectPtrEqual>
mhome_map;
for (const auto& it : home_map) {
std::vector<MemoryRegion> home_regions;

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.

Did not we have a utility to convert Arrays to Vectors somewhere ?

@manupak

Copy link
Copy Markdown
Contributor

We can unblock the reviews of the next PR, if we could address the comments of this PR in a seperate follow up PR.
WDYT @mbaret ?

@manupakmanupak added the status: need update need update based on feedbacks label Feb 23, 2022
@mbaret

Copy link
Copy Markdown
ContributorAuthor

Yup, happy to take it as a follow up.

@manupakmanupak 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! (bar the comments that is deffered to the follow up)

@manupak
manupak merged commit f1ff61a into apache:mainFeb 24, 2022
@manupak

Copy link
Copy Markdown
Contributor

Thanks! @mbaret

pfk-beta pushed a commit to pfk-beta/tvm that referenced this pull request Apr 11, 2022
* [microNPU][4] Add the cascader Proposal generator
The Proposal generator takes optimal Plans and combines
them to find optimal 'Proposals' - sets of disjoint
Plans that cover every Part in a CascaderGraph. It
ultimately produces a Pareto-frontier of 'optimal'
Proposals in terms of estimated cycles and memory usage.
Change-Id: Id42099819a596496a5769bae22f08eeb75ec69b6
* Fixes
Change-Id: I4f5f2a298bd3bb379c7c8d179150358923b0dd66
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status: need updateneed update based on feedbacks

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@mbaret@manupak
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

[microNPU][4] Add the cascader Proposal generator - #9959

Merged
manupak merged 2 commits into
apache:mainfrom
mbaret:ethosu-cascader-7
Feb 24, 2022
Merged

[microNPU][4] Add the cascader Proposal generator#9959
manupak merged 2 commits into
apache:mainfrom
mbaret:ethosu-cascader-7

Conversation

@mbaret

@mbaretmbaret commented Jan 18, 2022

Copy link
Copy Markdown
Contributor

RFC: apache/tvm-rfcs#37
Issue: #9429

The Proposal generator takes optimal Plans and combines them to find optimal 'Proposals' - sets of disjoint Plans that cover every Part in a CascaderGraph. It ultimately produces a Pareto-frontier of 'optimal' Proposals in terms of estimated cycles and memory usage.

The Proposal generator takes optimal Plans and combines
them to find optimal 'Proposals' - sets of disjoint
Plans that cover every Part in a CascaderGraph. It
ultimately produces a Pareto-frontier of 'optimal'
Proposals in terms of estimated cycles and memory usage.
Change-Id: Id42099819a596496a5769bae22f08eeb75ec69b6
Change-Id: I4f5f2a298bd3bb379c7c8d179150358923b0dd66

@manupakmanupak 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 @mbaret .

I have let some comments; some questions, some for more docs and some for slight refactors.
Happy to take these in a follow up to allow reviews of other PRs stacked on top of this.

I think we should try to progress this PR.

std::sort(proposals.begin(), proposals.end(), [](const Proposal& a, const Proposal& b) -> bool {
return a->GetMemoryUsage() < b->GetMemoryUsage();
});
std::vector<std::array<float, 2>> costs;

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 future : it might be better to use a typed struct here

namespace ethosu {
namespace cascader {

std::unordered_set<TensorConfig> GetPlanBoundaryConfigs(const Plan& plan) {

@manupakmanupakFeb 16, 2022

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.

Should we have docs for this function ?

return boundary_configs;
}

bool IsPlanCompatible(const Proposal& proposal, const std::vector<Part>& plan_part_group,

@manupakmanupakFeb 16, 2022

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.

Should we have docs for this function ?

return true;
}

std::unordered_map<Part, std::vector<Plan>, ObjectPtrHash, ObjectPtrEqual> CreatePlansByPart(

@manupakmanupakFeb 16, 2022

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.

Should we have docs for this function ?

return plans_by_part;
}

Proposal AddPlanToProposal(const Proposal& proposal, const Plan& plan,

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.

Should we have docs for this functions ?

return std::find(plan->GetPartGroup().begin(), plan->GetPartGroup().end(),
value) == plan->GetPartGroup().end();
});
// std::sort(residual_proposal_group.begin(), residual_proposal_group.end());

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.

remove ?

const CascaderGraph& graph, const HomeMap& home_map, const CascaderOptions options,
const std::unordered_map<Part, std::vector<Plan>, ObjectPtrHash, ObjectPtrEqual>& plans_by_part,
const std::vector<Part>& partial_proposal_group,
std::unordered_map<std::vector<Part>, std::vector<Proposal>>* proposals_by_group) {

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.

Just curious, what is the reasoning to use a pointer as opposed to references elsewhere ?

value) == plan->GetPartGroup().end();
});
// std::sort(residual_proposal_group.begin(), residual_proposal_group.end());
const auto& residual_proposals = GeneratePartialProposals(

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.

A comment would help here to differentiate between "residual_proposal_group" vs "residual_proposals"

value) == plan->GetPartGroup().end();
});
// std::sort(residual_proposal_group.begin(), residual_proposal_group.end());
const auto& residual_proposals = GeneratePartialProposals(

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.

It also feels like constant context data is passed onto the recursive call that does not change between calls.
Should we restructure this to be a class to hold such data (e.g. graph, home_map, proposals_by_group) ?

std::unordered_map<Tensor, std::vector<MemoryRegion>, ObjectPtrHash, ObjectPtrEqual>
mhome_map;
for (const auto& it : home_map) {
std::vector<MemoryRegion> home_regions;

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.

Did not we have a utility to convert Arrays to Vectors somewhere ?

@manupak

Copy link
Copy Markdown
Contributor

We can unblock the reviews of the next PR, if we could address the comments of this PR in a seperate follow up PR.
WDYT @mbaret ?

@manupakmanupak added the status: need update need update based on feedbacks label Feb 23, 2022
@mbaret

Copy link
Copy Markdown
ContributorAuthor

Yup, happy to take it as a follow up.

@manupakmanupak 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! (bar the comments that is deffered to the follow up)

@manupak
manupak merged commit f1ff61a into apache:mainFeb 24, 2022
@manupak

Copy link
Copy Markdown
Contributor

Thanks! @mbaret

pfk-beta pushed a commit to pfk-beta/tvm that referenced this pull request Apr 11, 2022
* [microNPU][4] Add the cascader Proposal generator
The Proposal generator takes optimal Plans and combines
them to find optimal 'Proposals' - sets of disjoint
Plans that cover every Part in a CascaderGraph. It
ultimately produces a Pareto-frontier of 'optimal'
Proposals in terms of estimated cycles and memory usage.
Change-Id: Id42099819a596496a5769bae22f08eeb75ec69b6
* Fixes
Change-Id: I4f5f2a298bd3bb379c7c8d179150358923b0dd66
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status: need updateneed update based on feedbacks

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@mbaret@manupak
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

[microNPU][4] Add the cascader Proposal generator - #9959

Merged
manupak merged 2 commits into
apache:mainfrom
mbaret:ethosu-cascader-7
Feb 24, 2022
Merged

[microNPU][4] Add the cascader Proposal generator#9959
manupak merged 2 commits into
apache:mainfrom
mbaret:ethosu-cascader-7

Conversation

@mbaret

@mbaretmbaret commented Jan 18, 2022

Copy link
Copy Markdown
Contributor

RFC: apache/tvm-rfcs#37
Issue: #9429

The Proposal generator takes optimal Plans and combines them to find optimal 'Proposals' - sets of disjoint Plans that cover every Part in a CascaderGraph. It ultimately produces a Pareto-frontier of 'optimal' Proposals in terms of estimated cycles and memory usage.

The Proposal generator takes optimal Plans and combines
them to find optimal 'Proposals' - sets of disjoint
Plans that cover every Part in a CascaderGraph. It
ultimately produces a Pareto-frontier of 'optimal'
Proposals in terms of estimated cycles and memory usage.
Change-Id: Id42099819a596496a5769bae22f08eeb75ec69b6
Change-Id: I4f5f2a298bd3bb379c7c8d179150358923b0dd66

@manupakmanupak 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 @mbaret .

I have let some comments; some questions, some for more docs and some for slight refactors.
Happy to take these in a follow up to allow reviews of other PRs stacked on top of this.

I think we should try to progress this PR.

std::sort(proposals.begin(), proposals.end(), [](const Proposal& a, const Proposal& b) -> bool {
return a->GetMemoryUsage() < b->GetMemoryUsage();
});
std::vector<std::array<float, 2>> costs;

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 future : it might be better to use a typed struct here

namespace ethosu {
namespace cascader {

std::unordered_set<TensorConfig> GetPlanBoundaryConfigs(const Plan& plan) {

@manupakmanupakFeb 16, 2022

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.

Should we have docs for this function ?

return boundary_configs;
}

bool IsPlanCompatible(const Proposal& proposal, const std::vector<Part>& plan_part_group,

@manupakmanupakFeb 16, 2022

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.

Should we have docs for this function ?

return true;
}

std::unordered_map<Part, std::vector<Plan>, ObjectPtrHash, ObjectPtrEqual> CreatePlansByPart(

@manupakmanupakFeb 16, 2022

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.

Should we have docs for this function ?

return plans_by_part;
}

Proposal AddPlanToProposal(const Proposal& proposal, const Plan& plan,

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.

Should we have docs for this functions ?

return std::find(plan->GetPartGroup().begin(), plan->GetPartGroup().end(),
value) == plan->GetPartGroup().end();
});
// std::sort(residual_proposal_group.begin(), residual_proposal_group.end());

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.

remove ?

const CascaderGraph& graph, const HomeMap& home_map, const CascaderOptions options,
const std::unordered_map<Part, std::vector<Plan>, ObjectPtrHash, ObjectPtrEqual>& plans_by_part,
const std::vector<Part>& partial_proposal_group,
std::unordered_map<std::vector<Part>, std::vector<Proposal>>* proposals_by_group) {

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.

Just curious, what is the reasoning to use a pointer as opposed to references elsewhere ?

value) == plan->GetPartGroup().end();
});
// std::sort(residual_proposal_group.begin(), residual_proposal_group.end());
const auto& residual_proposals = GeneratePartialProposals(

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.

A comment would help here to differentiate between "residual_proposal_group" vs "residual_proposals"

value) == plan->GetPartGroup().end();
});
// std::sort(residual_proposal_group.begin(), residual_proposal_group.end());
const auto& residual_proposals = GeneratePartialProposals(

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.

It also feels like constant context data is passed onto the recursive call that does not change between calls.
Should we restructure this to be a class to hold such data (e.g. graph, home_map, proposals_by_group) ?

std::unordered_map<Tensor, std::vector<MemoryRegion>, ObjectPtrHash, ObjectPtrEqual>
mhome_map;
for (const auto& it : home_map) {
std::vector<MemoryRegion> home_regions;

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.

Did not we have a utility to convert Arrays to Vectors somewhere ?

@manupak

Copy link
Copy Markdown
Contributor

We can unblock the reviews of the next PR, if we could address the comments of this PR in a seperate follow up PR.
WDYT @mbaret ?

@manupakmanupak added the status: need update need update based on feedbacks label Feb 23, 2022
@mbaret

Copy link
Copy Markdown
ContributorAuthor

Yup, happy to take it as a follow up.

@manupakmanupak 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! (bar the comments that is deffered to the follow up)

@manupak
manupak merged commit f1ff61a into apache:mainFeb 24, 2022
@manupak

Copy link
Copy Markdown
Contributor

Thanks! @mbaret

pfk-beta pushed a commit to pfk-beta/tvm that referenced this pull request Apr 11, 2022
* [microNPU][4] Add the cascader Proposal generator
The Proposal generator takes optimal Plans and combines
them to find optimal 'Proposals' - sets of disjoint
Plans that cover every Part in a CascaderGraph. It
ultimately produces a Pareto-frontier of 'optimal'
Proposals in terms of estimated cycles and memory usage.
Change-Id: Id42099819a596496a5769bae22f08eeb75ec69b6
* Fixes
Change-Id: I4f5f2a298bd3bb379c7c8d179150358923b0dd66
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status: need updateneed update based on feedbacks

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@mbaret@manupak
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

[microNPU][4] Add the cascader Proposal generator - #9959

Merged
manupak merged 2 commits into
apache:mainfrom
mbaret:ethosu-cascader-7
Feb 24, 2022
Merged

[microNPU][4] Add the cascader Proposal generator#9959
manupak merged 2 commits into
apache:mainfrom
mbaret:ethosu-cascader-7

Conversation

@mbaret

@mbaretmbaret commented Jan 18, 2022

Copy link
Copy Markdown
Contributor

RFC: apache/tvm-rfcs#37
Issue: #9429

The Proposal generator takes optimal Plans and combines them to find optimal 'Proposals' - sets of disjoint Plans that cover every Part in a CascaderGraph. It ultimately produces a Pareto-frontier of 'optimal' Proposals in terms of estimated cycles and memory usage.

The Proposal generator takes optimal Plans and combines
them to find optimal 'Proposals' - sets of disjoint
Plans that cover every Part in a CascaderGraph. It
ultimately produces a Pareto-frontier of 'optimal'
Proposals in terms of estimated cycles and memory usage.
Change-Id: Id42099819a596496a5769bae22f08eeb75ec69b6
Change-Id: I4f5f2a298bd3bb379c7c8d179150358923b0dd66

@manupakmanupak 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 @mbaret .

I have let some comments; some questions, some for more docs and some for slight refactors.
Happy to take these in a follow up to allow reviews of other PRs stacked on top of this.

I think we should try to progress this PR.

std::sort(proposals.begin(), proposals.end(), [](const Proposal& a, const Proposal& b) -> bool {
return a->GetMemoryUsage() < b->GetMemoryUsage();
});
std::vector<std::array<float, 2>> costs;

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 future : it might be better to use a typed struct here

namespace ethosu {
namespace cascader {

std::unordered_set<TensorConfig> GetPlanBoundaryConfigs(const Plan& plan) {

@manupakmanupakFeb 16, 2022

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.

Should we have docs for this function ?

return boundary_configs;
}

bool IsPlanCompatible(const Proposal& proposal, const std::vector<Part>& plan_part_group,

@manupakmanupakFeb 16, 2022

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.

Should we have docs for this function ?

return true;
}

std::unordered_map<Part, std::vector<Plan>, ObjectPtrHash, ObjectPtrEqual> CreatePlansByPart(

@manupakmanupakFeb 16, 2022

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.

Should we have docs for this function ?

return plans_by_part;
}

Proposal AddPlanToProposal(const Proposal& proposal, const Plan& plan,

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.

Should we have docs for this functions ?

return std::find(plan->GetPartGroup().begin(), plan->GetPartGroup().end(),
value) == plan->GetPartGroup().end();
});
// std::sort(residual_proposal_group.begin(), residual_proposal_group.end());

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.

remove ?

const CascaderGraph& graph, const HomeMap& home_map, const CascaderOptions options,
const std::unordered_map<Part, std::vector<Plan>, ObjectPtrHash, ObjectPtrEqual>& plans_by_part,
const std::vector<Part>& partial_proposal_group,
std::unordered_map<std::vector<Part>, std::vector<Proposal>>* proposals_by_group) {

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.

Just curious, what is the reasoning to use a pointer as opposed to references elsewhere ?

value) == plan->GetPartGroup().end();
});
// std::sort(residual_proposal_group.begin(), residual_proposal_group.end());
const auto& residual_proposals = GeneratePartialProposals(

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.

A comment would help here to differentiate between "residual_proposal_group" vs "residual_proposals"

value) == plan->GetPartGroup().end();
});
// std::sort(residual_proposal_group.begin(), residual_proposal_group.end());
const auto& residual_proposals = GeneratePartialProposals(

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.

It also feels like constant context data is passed onto the recursive call that does not change between calls.
Should we restructure this to be a class to hold such data (e.g. graph, home_map, proposals_by_group) ?

std::unordered_map<Tensor, std::vector<MemoryRegion>, ObjectPtrHash, ObjectPtrEqual>
mhome_map;
for (const auto& it : home_map) {
std::vector<MemoryRegion> home_regions;

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.

Did not we have a utility to convert Arrays to Vectors somewhere ?

@manupak

Copy link
Copy Markdown
Contributor

We can unblock the reviews of the next PR, if we could address the comments of this PR in a seperate follow up PR.
WDYT @mbaret ?

@manupakmanupak added the status: need update need update based on feedbacks label Feb 23, 2022
@mbaret

Copy link
Copy Markdown
ContributorAuthor

Yup, happy to take it as a follow up.

@manupakmanupak 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! (bar the comments that is deffered to the follow up)

@manupak
manupak merged commit f1ff61a into apache:mainFeb 24, 2022
@manupak

Copy link
Copy Markdown
Contributor

Thanks! @mbaret

pfk-beta pushed a commit to pfk-beta/tvm that referenced this pull request Apr 11, 2022
* [microNPU][4] Add the cascader Proposal generator
The Proposal generator takes optimal Plans and combines
them to find optimal 'Proposals' - sets of disjoint
Plans that cover every Part in a CascaderGraph. It
ultimately produces a Pareto-frontier of 'optimal'
Proposals in terms of estimated cycles and memory usage.
Change-Id: Id42099819a596496a5769bae22f08eeb75ec69b6
* Fixes
Change-Id: I4f5f2a298bd3bb379c7c8d179150358923b0dd66
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status: need updateneed update based on feedbacks

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@mbaret@manupak
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

[microNPU][4] Add the cascader Proposal generator - #9959

Merged
manupak merged 2 commits into
apache:mainfrom
mbaret:ethosu-cascader-7
Feb 24, 2022
Merged

[microNPU][4] Add the cascader Proposal generator#9959
manupak merged 2 commits into
apache:mainfrom
mbaret:ethosu-cascader-7

Conversation

@mbaret

@mbaretmbaret commented Jan 18, 2022

Copy link
Copy Markdown
Contributor

RFC: apache/tvm-rfcs#37
Issue: #9429

The Proposal generator takes optimal Plans and combines them to find optimal 'Proposals' - sets of disjoint Plans that cover every Part in a CascaderGraph. It ultimately produces a Pareto-frontier of 'optimal' Proposals in terms of estimated cycles and memory usage.

The Proposal generator takes optimal Plans and combines
them to find optimal 'Proposals' - sets of disjoint
Plans that cover every Part in a CascaderGraph. It
ultimately produces a Pareto-frontier of 'optimal'
Proposals in terms of estimated cycles and memory usage.
Change-Id: Id42099819a596496a5769bae22f08eeb75ec69b6
Change-Id: I4f5f2a298bd3bb379c7c8d179150358923b0dd66

@manupakmanupak 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 @mbaret .

I have let some comments; some questions, some for more docs and some for slight refactors.
Happy to take these in a follow up to allow reviews of other PRs stacked on top of this.

I think we should try to progress this PR.

std::sort(proposals.begin(), proposals.end(), [](const Proposal& a, const Proposal& b) -> bool {
return a->GetMemoryUsage() < b->GetMemoryUsage();
});
std::vector<std::array<float, 2>> costs;

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 future : it might be better to use a typed struct here

namespace ethosu {
namespace cascader {

std::unordered_set<TensorConfig> GetPlanBoundaryConfigs(const Plan& plan) {

@manupakmanupakFeb 16, 2022

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.

Should we have docs for this function ?

return boundary_configs;
}

bool IsPlanCompatible(const Proposal& proposal, const std::vector<Part>& plan_part_group,

@manupakmanupakFeb 16, 2022

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.

Should we have docs for this function ?

return true;
}

std::unordered_map<Part, std::vector<Plan>, ObjectPtrHash, ObjectPtrEqual> CreatePlansByPart(

@manupakmanupakFeb 16, 2022

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.

Should we have docs for this function ?

return plans_by_part;
}

Proposal AddPlanToProposal(const Proposal& proposal, const Plan& plan,

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.

Should we have docs for this functions ?

return std::find(plan->GetPartGroup().begin(), plan->GetPartGroup().end(),
value) == plan->GetPartGroup().end();
});
// std::sort(residual_proposal_group.begin(), residual_proposal_group.end());

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.

remove ?

const CascaderGraph& graph, const HomeMap& home_map, const CascaderOptions options,
const std::unordered_map<Part, std::vector<Plan>, ObjectPtrHash, ObjectPtrEqual>& plans_by_part,
const std::vector<Part>& partial_proposal_group,
std::unordered_map<std::vector<Part>, std::vector<Proposal>>* proposals_by_group) {

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.

Just curious, what is the reasoning to use a pointer as opposed to references elsewhere ?

value) == plan->GetPartGroup().end();
});
// std::sort(residual_proposal_group.begin(), residual_proposal_group.end());
const auto& residual_proposals = GeneratePartialProposals(

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.

A comment would help here to differentiate between "residual_proposal_group" vs "residual_proposals"

value) == plan->GetPartGroup().end();
});
// std::sort(residual_proposal_group.begin(), residual_proposal_group.end());
const auto& residual_proposals = GeneratePartialProposals(

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.

It also feels like constant context data is passed onto the recursive call that does not change between calls.
Should we restructure this to be a class to hold such data (e.g. graph, home_map, proposals_by_group) ?

std::unordered_map<Tensor, std::vector<MemoryRegion>, ObjectPtrHash, ObjectPtrEqual>
mhome_map;
for (const auto& it : home_map) {
std::vector<MemoryRegion> home_regions;

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.

Did not we have a utility to convert Arrays to Vectors somewhere ?

@manupak

Copy link
Copy Markdown
Contributor

We can unblock the reviews of the next PR, if we could address the comments of this PR in a seperate follow up PR.
WDYT @mbaret ?

@manupakmanupak added the status: need update need update based on feedbacks label Feb 23, 2022
@mbaret

Copy link
Copy Markdown
ContributorAuthor

Yup, happy to take it as a follow up.

@manupakmanupak 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! (bar the comments that is deffered to the follow up)

@manupak
manupak merged commit f1ff61a into apache:mainFeb 24, 2022
@manupak

Copy link
Copy Markdown
Contributor

Thanks! @mbaret

pfk-beta pushed a commit to pfk-beta/tvm that referenced this pull request Apr 11, 2022
* [microNPU][4] Add the cascader Proposal generator
The Proposal generator takes optimal Plans and combines
them to find optimal 'Proposals' - sets of disjoint
Plans that cover every Part in a CascaderGraph. It
ultimately produces a Pareto-frontier of 'optimal'
Proposals in terms of estimated cycles and memory usage.
Change-Id: Id42099819a596496a5769bae22f08eeb75ec69b6
* Fixes
Change-Id: I4f5f2a298bd3bb379c7c8d179150358923b0dd66
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status: need updateneed update based on feedbacks

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@mbaret@manupak