- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试在 Halide 中实现归一化互相关。
下面的代码构建,Halide JIT 编译不会抛出任何错误。但是,Halide 似乎在 JIT 编译后挂起。无论我对不同的 Func 调用了多少次 trace_*
,都只会打印一条跟踪(在 Func 输出
上):
Begin realization normxcorr.0(0, 2028, 0, 2028)
Produce normxcorr.0(0, 2028, 0, 2028)
任何建议都会有所帮助。
这个算法相当于CV_TM_CCOEFF_NORMED in OpenCV , 和 normxcorr2 in MATLAB :
void normxcorr( Halide::ImageParam input,
Halide::ImageParam kernel,
Halide::Param<pixel_t> kernel_mean,
Halide::Param<pixel_t> kernel_var,
Halide::Func& output )
{
Halide::Var x, y;
Halide::RDom rk( kernel );
// reduction domain for cumulative sums
Halide::RDom ri( 1, input.width() - kernel.width() - 1,
1, input.height() - kernel.height() - 1 );
Halide::Func input_32( "input32" ),
bounded_input( "bounded_input"),
kernel_32( "kernel32" ),
knorm( "knorm" ),
conv( "conv" ),
normxcorr( "normxcorr_internal" ),
sq_sum_x( "sq_sum_x" ),
sq_sum_x_local( "sq_sum_x_local" ),
sq_sum_y( "sq_sum_y" ),
sq_sum_y_local( "sq_sum_y_local" ),
sum_x( "sum_x" ),
sum_x_local( "sum_x_local" ),
sum_y( "sum_y" ),
sum_y_local( "sum_y_local" ),
win_var( "win_var" ),
win_mean( "win_mean" );
Halide::Expr ksize = kernel.width() * kernel.height();
// accessing outside the input image always returns 0
bounded_input( x, y ) = Halide::BoundaryConditions::constant_exterior( input, 0 )( x, y );
// cast to 32-bit to make room for multiplication
input_32( x, y ) = Halide::cast<int32_t>( bounded_input( x, y ) );
kernel_32( x, y ) = Halide::cast<int32_t>( kernel( x, y ) );
// cumulative sum along each row
sum_x( x, y ) = input_32( x, y );
sum_x( ri.x, ri.y ) += sum_x( ri.x - 1, ri.y );
// sum of 1 x W strips
// (W is the width of the kernel)
sum_x_local( x, y ) = sum_x( x + kernel.width() - 1, y );
sum_x_local( x, y ) -= sum_x( x - 1, y );
// cumulative sums of the 1 x W strips along each column
sum_y( x, y ) = sum_x_local( x, y );
sum_y( ri.x, ri.y ) += sum_y( ri.x, ri.y - 1);
// sums up H strips (as above) to get the sum of an H x W rectangle
// (H is the height of the kernel)
sum_y_local( x, y ) = sum_y( x, y + kernel.height() - 1 );
sum_y_local( x, y ) -= sum_y( x, y - 1 );
// same as above, just with squared image values
sq_sum_x( x, y ) = input_32( x, y ) * input_32( x, y );
sq_sum_x( ri.x, ri.y ) += sq_sum_x( ri.x - 1, ri.y );
sq_sum_x_local( x, y ) = sq_sum_x( x + kernel.width() - 1, y );
sq_sum_x_local( x, y ) -= sq_sum_x( x - 1, y );
sq_sum_y( x, y ) = sq_sum_x_local( x, y );
sq_sum_y( ri.x, ri.y ) += sq_sum_y( ri.x, ri.y - 1);
sq_sum_y_local( x, y ) = sq_sum_y( x, y + kernel.height() - 1 );
sq_sum_y_local( x, y ) -= sq_sum_y( x, y - 1 );
// the mean value of each window
win_mean( x, y ) = sum_y_local( x, y ) / ksize;
// the variance of each window
win_var( x, y ) = sq_sum_y_local( x, y ) / ksize;
win_var( x, y) -= win_mean( x, y ) * win_mean( x, y );
// partially normalize the kernel
// (we'll divide by std. dev. at the end)
knorm( x, y ) = kernel_32( x, y ) - kernel_mean;
// convolve kernel and the input
conv( x, y ) = Halide::sum( knorm( rk.x, rk.y ) * input_32( x + rk.x, y + rk.y ) );
// calculate normxcorr, except scaled to 0 to 254 (for an 8-bit image)
normxcorr( x, y ) = conv( x, y ) * 127 / Halide::sqrt( kernel_var * win_var( x, y ) ) + 127;
// after scaling pixel values, it's safe to cast down to 8-bit
output( x, y ) = Halide::cast<pixel_t>( normxcorr( x, y ) );
}
最佳答案
我认为这里的问题很简单,就是您没有为您的任何函数指定任何时间表,所以一切都被内联,导致中间值的大量冗余计算。所以实际上这在技术上并不是挂起,而是简单地为每个像素做了大量的工作,因此未能在合理的时间内完成。
首先,尝试说每个函数都应该是 compute_root
(例如,sum_x.compute_root();
),最简单的方法是在函数末尾的一个 block 中功能。这应该以更合理的速度进行,应该一个接一个地打印每个函数(从输入开始),而不仅仅是 normxcore.0
,并且应该完成。
实际上,您的许多函数实际上只是对其输入进行逐点转换,因此这些输入可以保留为内联(而不是 compute_root
),这应该会进一步加快处理速度(尤其是在您开始并行化后并对某些阶段进行矢量化)。乍一看,[sq_]sum_{x,y}
可能不应该内联,但其他所有内容都可以内联。 knorm
和 input_32
是一个折腾,否则取决于你的目标和你的日程安排。
我添加了这个简单的时间表和一些其他小的清理,在此处进行了快速可运行的修订:
https://gist.github.com/d64823d754a732106a60
在我的测试中,它在一秒内以 2K^2 输入运行,没有任何花哨的东西。
顺便说一句,一个小提示:使用调试符号 (-g
) 编译生成器代码应该使您不必在所有 Func
声明中提供名称字符串。这在早期的实现中是一个不幸的缺陷,但我们现在能够合理地直接从 C++ 源符号名称设置这些名称,只要您在启用调试符号的情况下进行编译。
关于c++ - Halide 在归一化互相关期间挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31060974/
我有一张二值图像,我想使用 Halide 从图像的顶部开始为每一列找到第一个非零像素。 在 C++ 中,给定名为 mask 的图像,它看起来像这样: vector top_y; top_y.reser
我正在尝试使用增强的生成器类重新实现双边网格示例(例如使用 schedule() 和 generate()。但我在尝试编译代码时遇到错误。 g++ -std=c++11 -I ../../includ
我正在尝试使用增强的生成器类重新实现双边网格示例(例如使用 schedule() 和 generate()。但我在尝试编译代码时遇到错误。 g++ -std=c++11 -I ../../includ
是否可以在 Halide 中生成包含生成的 OpenCL 代码的文件?我试图从目标是 opencl 的 Halide 程序生成一个 c 文件,但我在那里没有看到任何 opencl 特定代码。 编辑1:
我主要是一名非常高级的程序员,因此思考 CPU 局部性等问题对我来说是非常新鲜的。 我正在研究一个基本的双线性去马赛克(用于 RGGB 传感器数据),并且我的算法是正确的(根据结果判断),但它的性能没
我正在尝试为基准 Halide 代码制定最佳时间表,但我可能会遗漏一些东西,因为计时结果对我来说意义不大。 我正在使用 AOT 编译,下面是代码的算法部分: ImageParam input1(typ
我已经尝试用 Halide 编写代码一段时间了,而且我总是自己编写时间表。然后我读了这篇论文:http://graphics.cs.cmu.edu/projects/halidesched/mulla
我想使用 Halide 生成多个输出缓冲区。 Func output; std::vector argsExpr( 4 ); argsExpr[ 0 ] = aOut( x, y ); argsExp
我正在尝试在 Halide 中实现归一化互相关。 下面的代码构建,Halide JIT 编译不会抛出任何错误。但是,Halide 似乎在 JIT 编译后挂起。无论我对不同的 Func 调用了多少次 t
我使用 AOT 编译来使用没有 Halide 库的 Halide 代码。 我在 HalideRuntime.h(在资源中可用)中看到我的 .o 文件中有许多可用的外部方法。 halide_dev_ma
我正在尝试开始使用一种名为 Halide 的用于图像处理的特定领域语言(C++ 扩展) . 在 Halide README 之后,这是我尝试过的: 下载了 Ubuntu 12.04 Halide bi
我正在尝试在 Halide 中实现 Meijster 距离变换算法。我已经重写了 this code到 C++(使用 openCV)并且工作正常。关于该算法的论文是here .现在我的 Halide
现在我正在尝试编写一些对图像进行子采样的 Halide 代码。基本上我希望图像的每 2 x 2 平方减少到一个包含最大值的像素。一个简单的例子是转换 1 2 3 4 5 6 7 8 9 0 1 2 4
是否有适用于使用 Halide 语言编写的代码的性能计数器?我想知道我的代码执行了多少加载、存储和 ALU 操作。 用于调度多阶段管道的 Halide 教程通过比较分配的内存量、加载、存储和对 hal
尝试加载灰度图像png格式以执行此代码时出现错误。我的程序是Halide Tutorial类(class)2的一部分。这是我的代码: #include #include "Halid
我正在尝试学习Halide,但我无法正确使用GPU,因为在安排GPU时它会生成黑色图像。对于CPU而言,它会产生良好的结果(注释掉brighter.gpu_tile(x,y,xo,yo,xi,yi,8
我正在尝试运行找到的 Halide FFT 实现 here用于针对 FTTW 进行基准测试。我能够按原样运行实现,但在深入挖掘时遇到了一些问题。该例程因 H 和 W 的不同值(随机输入图像的高度和宽度
我正在尝试将我的 Halide 程序编译为 jit,以便稍后在不同图像的代码中多次使用它。但是我想我做错了什么,有人可以纠正我吗?首先,我创建要运行的 Halide 函数: void m_gammaF
我正在尝试更改实现的缓冲区布局。我知道 Halide 的目的是允许“一次”定义算法,然后能够分别更改调度和存储布局等内容。 我已经尝试过 my_output_function.reorder_stor
几周来我一直在探索 Halide 的可能性,为了更好地了解 Halide 的作用,我想尝试使用 halide 分析器。假设我有一个 Func 测试。 (为了便于阅读,我省略了变量声明等。)f=函数(测
我是一名优秀的程序员,十分优秀!