I have a onnx case RoiAlign UT that can passed on onnxruntime. (The file is too big size, I put it on your FTP server path:to_verisilicon/shuliu/roialign.zip)
I add a UT for RoiAlign based on the onnx case : (need put the roialign folder under host_build/src/tim)
roi_align_test.cc
/****************************************************************************
*
* Copyright (c) 2022 Vivante Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#include "tim/vx/ops/roi_align.h"
#include "gtest/gtest.h"
#include "test_utils.h"
#include "tim/vx/context.h"
#include "tim/vx/graph.h"
#include "tim/vx/types.h"
#include <iostream>
#include <fstream>
#include <numeric>
TEST(ROI_Align, shape_25_25_256_1_float32) {
auto ctx = tim::vx::Context::Create();
auto graph = ctx->CreateGraph();
uint32_t height = 25;
uint32_t width = 25;
uint32_t channels = 256;
uint32_t batch = 1;
uint32_t num_rois = 1000;
uint32_t depth = channels;
int32_t out_height = 7;
int32_t out_width = 7;
float height_ratio = 0.3125f;
float width_ratio = 0.3125f;
int32_t height_sample_num = 2;
int32_t width_sample_num = 2;
tim::vx::ShapeType input_shape({width, height, channels, batch}); //whcn
tim::vx::ShapeType regions_shape({4, num_rois});
tim::vx::ShapeType batch_index_shape({num_rois});
tim::vx::ShapeType output_shape(
{(uint32_t)out_width, (uint32_t)out_height, depth, num_rois});
tim::vx::TensorSpec input_spec(tim::vx::DataType::FLOAT32, input_shape,
tim::vx::TensorAttribute::INPUT);
tim::vx::TensorSpec regions_spec(tim::vx::DataType::FLOAT32, regions_shape,
tim::vx::TensorAttribute::INPUT);
tim::vx::TensorSpec batch_index_spec(tim::vx::DataType::INT32,
batch_index_shape,
tim::vx::TensorAttribute::INPUT);
tim::vx::TensorSpec output_spec(tim::vx::DataType::FLOAT32, output_shape,
tim::vx::TensorAttribute::OUTPUT);
auto input_count = std::accumulate(input_shape.begin(),
input_shape.end(), 1, std::multiplies<int64_t>());
float *input_data = new float[input_count];
std::ifstream in("roialign/test_data_set_0/input_0.bin", std::ios::in | std::ios::binary);
if(in.is_open())
{
in.read((char *)input_data, input_count*sizeof(float));
std::cout<<"input data:"<<std::endl;
for(int i=0; i<10; i++)
{
std::cout<<input_data[i]<<" ";
}
std::cout<<std::endl;
for(int i=0; i<10; i++)
{
std::cout<<input_data[input_count-10+i]<<" ";
}
std::cout<<std::endl;
in.close();
}
else
{
std::cout<<"open input_0.bin fail!"<<std::endl;
}
auto regions_count = std::accumulate(regions_shape.begin(),
regions_shape.end(), 1, std::multiplies<int64_t>());
float *regions_data = new float[regions_count];
std::ifstream in1("roialign/test_data_set_0/input_1.bin", std::ios::in | std::ios::binary);
if(in1.is_open())
{
in1.read((char *)regions_data, regions_count*sizeof(float));
std::cout<<"regions data:"<<std::endl;
for(int i=0; i<10; i++)
{
std::cout<<regions_data[i]<<" ";
}
std::cout<<std::endl;
for(int i=0; i<10; i++)
{
std::cout<<regions_data[regions_count-10+i]<<" ";
}
std::cout<<std::endl;
in1.close();
}
else
{
std::cout<<"open input_1.bin fail!"<<std::endl;
}
auto batch_index_count = std::accumulate(batch_index_shape.begin(),
batch_index_shape.end(), 1, std::multiplies<int64_t>());
int64_t *batch_index_data = new int64_t[batch_index_count];
std::ifstream in2("roialign/test_data_set_0/input_2.bin", std::ios::in | std::ios::binary);
if(in2.is_open())
{
in2.read((char *)batch_index_data, batch_index_count*sizeof(int64_t));
std::cout<<"batch_index data:"<<std::endl;
for(int i=0; i<10; i++)
{
std::cout<<batch_index_data[i]<<" ";
}
std::cout<<std::endl;
for(int i=0; i<10; i++)
{
std::cout<<batch_index_data[batch_index_count-10+i]<<" ";
}
std::cout<<std::endl;
in2.close();
}
else
{
std::cout<<"open input_2.bin fail!"<<std::endl;
}
auto out_count = std::accumulate(output_shape.begin(),
output_shape.end(), 1, std::multiplies<int64_t>());
float *golden = new float[out_count];
std::vector<float> golden_float(out_count);
std::ifstream out("roialign/test_data_set_0/output_0.bin", std::ios::in | std::ios::binary);
if(out.is_open())
{
out.read((char *)golden, out_count*sizeof(float));
for(auto i=0; i<out_count; i++)
{
golden_float[i] = golden[i];
}
std::cout<<"output data:"<<std::endl;
for(int i=0; i<10; i++)
{
std::cout<<golden[i]<<" ";
}
std::cout<<std::endl;
for(int i=0; i<10; i++)
{
std::cout<<golden[out_count-10+i]<<" ";
}
std::cout<<std::endl;
out.close();
}
else
{
std::cout<<"open output_0.bin fail!"<<std::endl;
}
auto input_tensor = graph->CreateTensor(input_spec);
auto regions_tensor = graph->CreateTensor(regions_spec);
auto batch_index_tensor =
graph->CreateTensor(batch_index_spec);
auto output_tensor = graph->CreateTensor(output_spec);
auto roi_align = graph->CreateOperation<tim::vx::ops::ROI_Align>(
out_height, out_width, height_ratio, width_ratio, height_sample_num,
width_sample_num);
(*roi_align)
.BindInput(input_tensor)
.BindInput(regions_tensor)
.BindInput(batch_index_tensor)
.BindOutput(output_tensor);
EXPECT_TRUE(graph->Compile());
input_tensor->CopyDataToTensor(input_data, sizeof(input_data)*sizeof(float));
regions_tensor->CopyDataToTensor(regions_data, sizeof(regions_data)*sizeof(float));
batch_index_tensor->CopyDataToTensor(batch_index_data, sizeof(batch_index_data)*sizeof(float));
EXPECT_TRUE(graph->Run());
std::vector<float> output(num_rois * out_height * out_width * depth);
EXPECT_TRUE(output_tensor->CopyDataFromTensor(output.data()));
EXPECT_EQ(golden_float, output);
}
After running, it is inconsistent with the expected result.