错误:在63处访问输入缓冲区过滤器,该值超出维度2中的最大值(15)。

时间:2018-10-31 22:11:35

标签: halide

我想在提拉米苏编译器上测试用卤化物编写的算法
一旦我运行它,我就会收到类似这样的错误

Error: Input buffer filter is accessed at 63, which is beyond the max (15) in dimension 2
Aborted (core dumped)

所以我决定只测试方法的调用,即使我有相同的参数,但我得到相同的错误或类似

的错误
Error: Input buffer bias is accessed at 15, which is beyond the max (4) in dimension 0
Aborted (core dumped)

这是我的wrapper_vgg.h

    #ifndef HALIDE__build___wrapper_vgg_o_h
    #define HALIDE__build___wrapper_vgg_o_h

    #include <tiramisu/utils.h>

    #define RADIUS 3

    #ifdef __cplusplus
    extern "C" {
    #endif

    int vgg_tiramisu(halide_buffer_t *, halide_buffer_t *_b_input_buffer ,halide_buffer_t *filter,halide_buffer_t *bias,halide_buffer_t *conv,halide_buffer_t *filter2, halide_buffer_t *bias2 ,halide_buffer_t *conv2,halide_buffer_t *_b_output_buffer,halide_buffer_t *_negative_slope);
    int vgg_tiramisu_argv(void **args);


    int vgg_ref( halide_buffer_t *_b_input_buffer ,halide_buffer_t *filter,halide_buffer_t *bias,halide_buffer_t *filter2, halide_buffer_t *bias2 ,halide_buffer_t *_b_output_buffer);
    int vgg_ref_argv(void **args);

    // Result is never null and points to constant static data
    const struct halide_filter_metadata_t *vgg_tiramisu_metadata();
    const struct halide_filter_metadata_t *vgg_ref_metadata();

    #ifdef __cplusplus
    }  // extern "C"
    #endif

这是我的vgg_ref.cpp

#include "Halide.h"
#include "configure.h"

using namespace Halide;
int main(int argc, char **argv)
{ 
    ImageParam            input{Float(32), 4, "input"};
    ImageParam            filter{Float(32), 4, "filter"};
    ImageParam            bias{Float(32), 1, "bias"};
    ImageParam            filter2{Float(32), 4, "filter2"};
    ImageParam            bias2{Float(32), 1, "bias2"};
   /* THE ALGORITHM */

    Var x("x"), y("y"), z("z"), n("n");
    Func f_conv("conv"), f_conv2("conv2");
    Func f_ReLU("ReLU"), f_ReLU2("ReLU2") ;
    //Func f_Maxpool("Maxpool");
    Func f_vgg("vgg");

    RDom r(0, K+1, 0, K+1, 0, FIn);
    RDom r2(0, K+1, 0, K+1, 0, FOut);

    // First conv computations
    f_conv(x, y, z, n) = bias(z);
    f_conv(x, y, z, n) += filter(r.x, r.y, r.z, z) * input(x + r.x, y + r.y, r.z, n);

    //first relu
     f_ReLU(x, y, z, n) = max(0, f_conv(x, y, z, n));

        .....
        .....

    /* THE SCHEDULE */
     // Provide estimates on the input image
        .....
        .....


    f_vgg.compile_to_object("build/generated_fct_vgg_ref.o", {input, filter, bias, filter2, bias2}, "vgg_ref");
    f_vgg.compile_to_lowered_stmt("build/generated_fct_vgg_ref.txt", {input, filter, bias, filter2, bias2}, Text);

    return 0;
}

这是我调用vgg_ref方法的包装器

...

#include "configure.h"
#include "wrapper_vgg.h"
#include <tiramisu/utils.h>
using namespace std;

int main(int, char**)
{
    Halide::Buffer<float> input(N+K, N+K, FIn, BATCH_SIZE);
    Halide::Buffer<float> filter(K+1, K+1, FIn, FOut);
    Halide::Buffer<float> bias(FOut);
    Halide::Buffer<float> conv(N, N, FOut, BATCH_SIZE);
    Halide::Buffer<float> filter2(K+1, K+1, FOut, FOut);
    Halide::Buffer<float> bias2(FOut);
    Halide::Buffer<float> conv2_tiramisu(N-K, N-K, FOut, BATCH_SIZE);
    Halide::Buffer<float> vgg_tiramisu_buff(N-2*K, N-2*K, FOut, BATCH_SIZE);
    Halide::Buffer<int> parameters(5);
    Halide::Buffer<float> negative_slope(1);negative_slope(0) = 1;
    // Buffer for Halide 
    Halide::Buffer<float> vgg_halide(N-2*K, N-2*K, FOut, BATCH_SIZE);

    std::vector<std::chrono::duration<double,std::milli>> duration_vector_1;
    std::vector<std::chrono::duration<double,std::milli>> duration_vector_2;

    /****************************************** Initialize Buffers *********************************************/
    ....
    ....
    ....

    std::cout << "\t\tBuffers initialized" << std::endl;

    /****************************************** Halide Part ********************************************************/

   for (int i=0; i<NB_TESTS; i++)
    {

        auto start1 = std::chrono::high_resolution_clock::now();
        vgg_ref(input.raw_buffer(), filter.raw_buffer(), bias.raw_buffer(), filter2.raw_buffer(), bias2.raw_buffer(), vgg_halide.raw_buffer());

        auto end1 = std::chrono::high_resolution_clock::now();
        std::chrono::duration<double,std::milli> duration = end1 - start1;
        duration_vector_2.push_back(duration);
    }

    std::cout << "\t\tHalide vgg duration" << ": " << median(duration_vector_1)/1000 << "; " << std::endl;
    std::cout << "\t\t Result" << ": ";

    /****************************************** Tiramisu Part ********************************************************/

   /* // Initialize parameters[]
    parameters(0) = N;
    parameters(1) = K;
    parameters(2) = FIn;
    parameters(3) = FOut;
    parameters(4) = BATCH_SIZE;


    for (int i=0; i<NB_TESTS; i++)
    {
       // srand (1);
        auto start1 = std::chrono::high_resolution_clock::now();
        vgg_tiramisu(parameters.raw_buffer(), input.raw_buffer(), filter.raw_buffer(), bias.raw_buffer(), conv.raw_buffer(), filter2.raw_buffer(), bias2.raw_buffer(), conv2_tiramisu.raw_buffer(),vgg_tiramisu_buff.raw_buffer(),negative_slope.raw_buffer());

        auto end1 = std::chrono::high_resolution_clock::now();
        std::chrono::duration<double,std::milli> duration = end1 - start1;
        duration_vector_1.push_back(duration);
    }

    std::cout << "\t\tTiramisu vgg duration" << ": " << median(duration_vector_2)/1000 << "; " << std::endl;
    std::cout << "\t\t Result" << ": ";
    */
}

我注意到,一旦我在卤化物部分中注释了此行,一切都会很好

  vgg_ref(input.raw_buffer(), filter.raw_buffer(), bias.raw_buffer(), filter2.raw_buffer(), bias2.raw_buffer(), vgg_halide.raw_buffer());

所以问题在于对卤化物函数“ vgg_ref”的调用。

但是我不知道这个错误与我试图只调用一个参数有关,我确实总是遇到同样的问题。我不知道如何解决。

感谢您分享任何建议或关注我的事情。 谢谢。

1 个答案:

答案 0 :(得分:0)

稍后我可以解决问题。

我想在这里注意的是,如果没有创建“。o” 文件,就不可能运行基准测试,因此如果没有这一行

 f_vgg.compile_to_object("build/generated_fct_vgg_ref.o", {input, filter, bias, filter2, bias2}, "vgg_ref");

但是在我的情况下运行它是怎么回事!!

好吧,这基本上是因为“ .o”文件是在上一次执行中生成的。

  

在这里要小心:旧的“ .o”的技巧应该反映出许多错误结果的问题,这是由于存在该对象文件的旧副本。

即使以后再注意,我仍然有相同的错误或类似的错误:(。

此错误指的是什么?这通常意味着在您的代码中,它们是一个索引,与包装程序中的定义不符。

因此,有两(02)件事需要验证以帮助解决此问题:

  • 验证函数的调用,它是参数:例如,如果函数需要放置5个参数,请验证是否放置5个或更多。
  • 验证所有索引的时间间隔。

我的问题出在这两行

RDom r(0, K, 0, K, 0, FIn);
RDom r2(0, K, 0, K, 0, FOut);

RDom(要在其上进行迭代的多维域)可帮助您浏览输入矩阵中的一个小矩阵,例如为输入应用过滤器。上面的RDom定义了滤波器矩阵的x,y和z的间隔。

在包装器中,我像这样定义过滤器的参数

 Halide::Buffer<float> filter(K+1, K+1, FIn, FOut);

所以在RDom中,我也不得不把x从 0更改为k + 1 ,但是我只有 k ,这就是为什么我在问题中看到了这个问题的原因。

所以应该这样

RDom r(0, K+1, 0, K+1, 0, FIn);
RDom r2(0, K+1, 0, K+1, 0, FOut);

那确实解决了我的问题。

因此,只需注意那些可能会破坏您的一天的小错误,就可以了,因为它可以帮助您了解更多。