开源 企业版 高校版 私有云 模力方舟 AI 队友
代码拉取完成,页面将自动刷新
捐赠
捐赠前请先登录
扫描微信二维码支付
取消
支付完成
支付提示
将跳转至支付宝完成支付
确定
取消
1 Star 0 Fork 3

xiongying/Halide

加入 Gitee
与超过 1400万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
已有帐号? 立即登录
文件
main
分支 (1093)
标签 (17)
main
xtensa-codegen
vksnk/dma-limit-channels
rootjalex/trs-codegen-cross
abadams/fix_7374
abadams/remove_hack_from_gpu_only_aottest
srj/gpu-cache
srj/generator_aot_gpu_multi_context_threaded
srj/xtensa-merge
abadams/vector_scan
abadams/fix_7365
darya-ver/ir-viz
vulkan-phase2-runtime
srj/param-map-deprecation
srj/rt-return-types
srj/main-vs2022
release/15.x
srj/param-map
abadams/ir_builder_unique_ptr
vksnk/restrict
v14.0.0
v13.0.4
v13.0.3
v13.0.2
v13.0.1
v13.0.0
v12.0.1
v12.0.0
v11.0.1
v11.0.0
v10.0.1
v10.0.0
release_2019_08_27
release_8.0.0
v8.0.0
release_2018_02_15
release_2013_11_11
main
分支 (1093)
标签 (17)
main
xtensa-codegen
vksnk/dma-limit-channels
rootjalex/trs-codegen-cross
abadams/fix_7374
abadams/remove_hack_from_gpu_only_aottest
srj/gpu-cache
srj/generator_aot_gpu_multi_context_threaded
srj/xtensa-merge
abadams/vector_scan
abadams/fix_7365
darya-ver/ir-viz
vulkan-phase2-runtime
srj/param-map-deprecation
srj/rt-return-types
srj/main-vs2022
release/15.x
srj/param-map
abadams/ir_builder_unique_ptr
vksnk/restrict
v14.0.0
v13.0.4
v13.0.3
v13.0.2
v13.0.1
v13.0.0
v12.0.1
v12.0.0
v11.0.1
v11.0.0
v10.0.1
v10.0.0
release_2019_08_27
release_8.0.0
v8.0.0
release_2018_02_15
release_2013_11_11
克隆/下载
克隆/下载
提示
下载代码请复制以下命令到终端执行
为确保你提交的代码身份被 Gitee 正确识别,请执行以下命令完成配置
初次使用 SSH 协议进行代码克隆、推送等操作时,需按下述提示完成 SSH 配置
1 生成 RSA 密钥
2 获取 RSA 公钥内容,并配置到 SSH公钥
在 Gitee 上使用 SVN,请访问 使用指南
使用 HTTPS 协议时,命令行会出现如下账号密码验证步骤。基于安全考虑,Gitee 建议 配置并使用私人令牌 替代登录密码进行克隆、推送等操作
Username for 'https://gitee.com': userName
Password for 'https://userName@gitee.com': # 私人令牌
main
分支 (1093)
标签 (17)
main
xtensa-codegen
vksnk/dma-limit-channels
rootjalex/trs-codegen-cross
abadams/fix_7374
abadams/remove_hack_from_gpu_only_aottest
srj/gpu-cache
srj/generator_aot_gpu_multi_context_threaded
srj/xtensa-merge
abadams/vector_scan
abadams/fix_7365
darya-ver/ir-viz
vulkan-phase2-runtime
srj/param-map-deprecation
srj/rt-return-types
srj/main-vs2022
release/15.x
srj/param-map
abadams/ir_builder_unique_ptr
vksnk/restrict
v14.0.0
v13.0.4
v13.0.3
v13.0.2
v13.0.1
v13.0.0
v12.0.1
v12.0.0
v11.0.1
v11.0.0
v10.0.1
v10.0.0
release_2019_08_27
release_8.0.0
v8.0.0
release_2018_02_15
release_2013_11_11
Halide
/
src
/
ApplySplit.cpp
Halide
/
src
/
ApplySplit.cpp
ApplySplit.cpp 9.32 KB
一键复制 编辑 原始数据 按行查看 历史
#include "ApplySplit.h"
#include "IR.h"
#include "IROperator.h"
#include "Simplify.h"
#include "Substitute.h"
namespace Halide {
namespace Internal {
using std::map;
using std::string;
using std::vector;
vector<ApplySplitResult> apply_split(const Split &split, bool is_update, const string &prefix,
map<string, Expr> &dim_extent_alignment) {
vector<ApplySplitResult> result;
Expr outer = Variable::make(Int(32), prefix + split.outer);
Expr outer_max = Variable::make(Int(32), prefix + split.outer + ".loop_max");
if (split.is_split()) {
Expr inner = Variable::make(Int(32), prefix + split.inner);
Expr old_max = Variable::make(Int(32), prefix + split.old_var + ".loop_max");
Expr old_min = Variable::make(Int(32), prefix + split.old_var + ".loop_min");
Expr old_extent = Variable::make(Int(32), prefix + split.old_var + ".loop_extent");
dim_extent_alignment[split.inner] = split.factor;
Expr base = outer * split.factor + old_min;
string base_name = prefix + split.inner + ".base";
Expr base_var = Variable::make(Int(32), base_name);
string old_var_name = prefix + split.old_var;
Expr old_var = Variable::make(Int(32), old_var_name);
map<string, Expr>::iterator iter = dim_extent_alignment.find(split.old_var);
TailStrategy tail = split.tail;
internal_assert(tail != TailStrategy::Auto)
<< "An explicit tail strategy should exist at this point\n";
if ((iter != dim_extent_alignment.end()) &&
is_const_zero(simplify(iter->second % split.factor))) {
// We have proved that the split factor divides the
// old extent. No need to adjust the base or add an if
// statement.
dim_extent_alignment[split.outer] = iter->second / split.factor;
} else if (is_negative_const(split.factor) || is_const_zero(split.factor)) {
user_error << "Can't split " << split.old_var << " by " << split.factor
<< ". Split factors must be strictly positive\n";
} else if (is_const_one(split.factor)) {
// The split factor trivially divides the old extent,
// but we know nothing new about the outer dimension.
} else if (tail == TailStrategy::GuardWithIf ||
tail == TailStrategy::Predicate ||
tail == TailStrategy::PredicateLoads ||
tail == TailStrategy::PredicateStores) {
// It's an exact split but we failed to prove that the
// extent divides the factor. Use predication to guard
// the calls and/or provides.
// Bounds inference has trouble exploiting an if
// condition. We'll directly tell it that the loop
// variable is bounded above by the original loop max by
// replacing the variable with a promise-clamped version
// of it. We don't also use the original loop min because
// it needlessly complicates the expressions and doesn't
// actually communicate anything new.
Expr guarded = promise_clamped(old_var, old_var, old_max);
string guarded_var_name = prefix + split.old_var + ".guarded";
Expr guarded_var = Variable::make(Int(32), guarded_var_name);
ApplySplitResult::Type predicate_type, substitution_type;
switch (tail) {
case TailStrategy::GuardWithIf:
substitution_type = ApplySplitResult::Substitution;
predicate_type = ApplySplitResult::Predicate;
break;
case TailStrategy::Predicate:
// This is identical to GuardWithIf, but maybe it makes
// sense to keep it anyways?
substitution_type = ApplySplitResult::Substitution;
predicate_type = ApplySplitResult::Predicate;
break;
case TailStrategy::PredicateLoads:
substitution_type = ApplySplitResult::SubstitutionInCalls;
predicate_type = ApplySplitResult::PredicateCalls;
break;
case TailStrategy::PredicateStores:
substitution_type = ApplySplitResult::SubstitutionInProvides;
predicate_type = ApplySplitResult::PredicateProvides;
break;
default:
break;
}
// Inject the if condition *after* doing the substitution
// for the guarded version.
result.emplace_back(prefix + split.old_var, guarded_var, substitution_type);
result.emplace_back(guarded_var_name, guarded, ApplySplitResult::LetStmt);
result.emplace_back(likely(old_var <= old_max), predicate_type);
} else if (tail == TailStrategy::ShiftInwards) {
// Adjust the base downwards to not compute off the
// end of the realization.
// We'll only mark the base as likely (triggering a loop
// partition) if we're at or inside the innermost
// non-trivial loop.
base = likely_if_innermost(base);
base = Min::make(base, old_max + (1 - split.factor));
} else {
internal_assert(tail == TailStrategy::RoundUp);
}
// Define the original variable as the base value computed above plus the inner loop variable.
result.emplace_back(old_var_name, base_var + inner, ApplySplitResult::LetStmt);
result.emplace_back(base_name, base, ApplySplitResult::LetStmt);
} else if (split.is_fuse()) {
// Define the inner and outer in terms of the fused var
Expr fused = Variable::make(Int(32), prefix + split.old_var);
Expr inner_min = Variable::make(Int(32), prefix + split.inner + ".loop_min");
Expr outer_min = Variable::make(Int(32), prefix + split.outer + ".loop_min");
Expr inner_extent = Variable::make(Int(32), prefix + split.inner + ".loop_extent");
const Expr &factor = inner_extent;
Expr inner = fused % factor + inner_min;
Expr outer = fused / factor + outer_min;
result.emplace_back(prefix + split.inner, inner, ApplySplitResult::Substitution);
result.emplace_back(prefix + split.outer, outer, ApplySplitResult::Substitution);
result.emplace_back(prefix + split.inner, inner, ApplySplitResult::LetStmt);
result.emplace_back(prefix + split.outer, outer, ApplySplitResult::LetStmt);
// Maintain the known size of the fused dim if
// possible. This is important for possible later splits.
map<string, Expr>::iterator inner_dim = dim_extent_alignment.find(split.inner);
map<string, Expr>::iterator outer_dim = dim_extent_alignment.find(split.outer);
if (inner_dim != dim_extent_alignment.end() &&
outer_dim != dim_extent_alignment.end()) {
dim_extent_alignment[split.old_var] = inner_dim->second * outer_dim->second;
}
} else {
// rename or purify
result.emplace_back(prefix + split.old_var, outer, ApplySplitResult::Substitution);
result.emplace_back(prefix + split.old_var, outer, ApplySplitResult::LetStmt);
}
return result;
}
vector<std::pair<string, Expr>> compute_loop_bounds_after_split(const Split &split, const string &prefix) {
// Define the bounds on the split dimensions using the bounds
// on the function args. If it is a purify, we should use the bounds
// from the dims instead.
vector<std::pair<string, Expr>> let_stmts;
Expr old_var_extent = Variable::make(Int(32), prefix + split.old_var + ".loop_extent");
Expr old_var_max = Variable::make(Int(32), prefix + split.old_var + ".loop_max");
Expr old_var_min = Variable::make(Int(32), prefix + split.old_var + ".loop_min");
if (split.is_split()) {
Expr inner_extent = split.factor;
Expr outer_extent = (old_var_max - old_var_min + split.factor) / split.factor;
let_stmts.emplace_back(prefix + split.inner + ".loop_min", 0);
let_stmts.emplace_back(prefix + split.inner + ".loop_max", inner_extent - 1);
let_stmts.emplace_back(prefix + split.inner + ".loop_extent", inner_extent);
let_stmts.emplace_back(prefix + split.outer + ".loop_min", 0);
let_stmts.emplace_back(prefix + split.outer + ".loop_max", outer_extent - 1);
let_stmts.emplace_back(prefix + split.outer + ".loop_extent", outer_extent);
} else if (split.is_fuse()) {
// Define bounds on the fused var using the bounds on the inner and outer
Expr inner_extent = Variable::make(Int(32), prefix + split.inner + ".loop_extent");
Expr outer_extent = Variable::make(Int(32), prefix + split.outer + ".loop_extent");
Expr fused_extent = inner_extent * outer_extent;
let_stmts.emplace_back(prefix + split.old_var + ".loop_min", 0);
let_stmts.emplace_back(prefix + split.old_var + ".loop_max", fused_extent - 1);
let_stmts.emplace_back(prefix + split.old_var + ".loop_extent", fused_extent);
} else if (split.is_rename()) {
let_stmts.emplace_back(prefix + split.outer + ".loop_min", old_var_min);
let_stmts.emplace_back(prefix + split.outer + ".loop_max", old_var_max);
let_stmts.emplace_back(prefix + split.outer + ".loop_extent", old_var_extent);
}
// Do nothing for purify
return let_stmts;
}
} // namespace Internal
} // namespace Halide
Loading...
举报
举报成功
我们将于2个工作日内通过站内信反馈结果给你!
请认真填写举报原因,尽可能描述详细。
请选择举报类型
取消
发送
误判申诉

此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。

如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。

取消
提交

简介

MIT计算机科学和人工智能实验室的研究人员创造出一种专门设计简化图像处理的程序语言Halide,源代码托管在GitHub上,目前二进制程序只支持Mac OS X和Ubuntu 12
取消

发行版

暂无发行版

贡献者

全部

近期动态

不能加载更多了
编辑仓库简介
简介内容
主页
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C/C++
1
https://gitee.com/VisionDeveloper/Halide.git
git@gitee.com:VisionDeveloper/Halide.git
VisionDeveloper
Halide
Halide
main
点此查找更多帮助

搜索帮助

评论
仓库举报
回到顶部
登录提示
该操作需登录 Gitee 帐号,请先登录后再操作。
立即登录
没有帐号,去注册

AltStyle によって変換されたページ (->オリジナル) /