Tencent / Tencent/ncnn

Top blob addressing issue with width and heights equal to 1

Open
#705 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C++
Stars
23.8k
Forks
4.5k
Avg merge
2d 20h
Merged PRs (30d)
37

Description

I am not sure if it is an isolated problem to Pooling and Convolutions, but if the input or output blob has a width and height of 1
then channel() returns the incorrect address and hence the result is corrupt, for example in pooling.cpp:

else if (pooling_type == PoolMethod_AVE)
{
#pragma omp parallel for num_threads(opt.num_threads)

    for (int q=0; q<channels; q++)
    {
        const Mat m = bottom_blob_bordered.channel(q);
        float* outptr = top_blob.channel(q);  //<----  Incorrect address returned

However: is row() is used then the correct address is returned.

float* outptr = (outh == 1 && outw == 1) ? top_blob.row(q) : top_blob.channel(q);

Maybe this case is better handled in the mat.cpp?

Update:
My crude fix in mat.h

inline Mat Mat::channel(int c)
{
if (( w % 2 ==1 && (unsigned)wc !=cstep ) || (w==1 && h==1))
return Mat(w, h, (unsigned char
)data + (w * h *c elemsize) , elemsize, allocator);
else
return Mat(w, h, (unsigned char
)data + cstep * c * elemsize, elemsize, allocator);
}

inline const Mat Mat::channel(int c) const
{

if (( w % 2 ==1 && (unsigned)wc !=cstep ) || (w==1 && h==1))
return Mat(w, h, (unsigned char
)data + (w * h *c elemsize) , elemsize, allocator);
else
return Mat(w, h, (unsigned char
)data + cstep * c * elemsize, elemsize, allocator);
}

Regards,

Simon

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in mat.h by inspecting Mat::channel and compare its address calculation with row() when width and height are 1. Then trace the average-pooling path in pooling.cpp and reproduce the corruption for single-element spatial dimensions. Done means channel() returns the correct address without breaking other dimensions, with pooling and convolution cases checked.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
backend, machine-learning
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.