Skip to content

Commit f10cc6d

Browse files
nihuiEEEEEEYuechoxiexyZr2223
authored
initial data structure changes for 3dcnn, conv3d, pooling3d (Tencent#3378)
Co-authored-by: ElvisYu <[email protected]> Co-authored-by: 余浩文 <[email protected]> Co-authored-by: Zr2223 <[email protected]>
1 parent 14c587e commit f10cc6d

File tree

120 files changed

+7543
-462
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

120 files changed

+7543
-462
lines changed

docs/developer-guide/operators.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -865,8 +865,7 @@ y = wrap_packing(x)
865865

866866
# Padding
867867
```
868-
if pads != -233/-234 y = pad(x, pads)
869-
else y = pad(x0, pads param from x1)
868+
y = pad(x, pads)
870869
```
871870

872871
| param id | name | type | default | description |

python/src/main.cpp

Lines changed: 176 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -214,12 +214,14 @@ PYBIND11_MODULE(ncnn, m)
214214
mat = new Mat(shape[0].cast<int>(), shape[1].cast<int>(), elemsize, elempack, allocator);
215215
break;
216216
case 3:
217-
mat = new Mat(shape[0].cast<int>(), shape[1].cast<int>(), shape[2].cast<int>(),
218-
elemsize, elempack, allocator);
217+
mat = new Mat(shape[0].cast<int>(), shape[1].cast<int>(), shape[2].cast<int>(), elemsize, elempack, allocator);
218+
break;
219+
case 4:
220+
mat = new Mat(shape[0].cast<int>(), shape[1].cast<int>(), shape[2].cast<int>(), shape[3].cast<int>(), elemsize, elempack, allocator);
219221
break;
220222
default:
221223
std::stringstream ss;
222-
ss << "shape must be 1, 2 or 3 dims, not " << shape.size();
224+
ss << "shape must be 1, 2, 3 or 4 dims, not " << shape.size();
223225
pybind11::pybind11_fail(ss.str());
224226
}
225227
return mat;
@@ -235,15 +237,18 @@ PYBIND11_MODULE(ncnn, m)
235237
.def(py::init<int, int, int, size_t, int, Allocator*>(),
236238
py::arg("w"), py::arg("h"), py::arg("c"), py::kw_only(),
237239
py::arg("elemsize") = 4, py::arg("elempack") = 1, py::arg("allocator") = nullptr)
240+
.def(py::init<int, int, int, int, size_t, int, Allocator*>(),
241+
py::arg("w"), py::arg("h"), py::arg("d"), py::arg("c"), py::kw_only(),
242+
py::arg("elemsize") = 4, py::arg("elempack") = 1, py::arg("allocator") = nullptr)
238243

239244
.def(py::init<const Mat&>(), py::arg("m"))
240245

241246
.def(py::init([](py::buffer const b) {
242247
py::buffer_info info = b.request();
243-
if (info.ndim > 3)
248+
if (info.ndim > 4)
244249
{
245250
std::stringstream ss;
246-
ss << "convert numpy.ndarray to ncnn.Mat only dims <=3 support now, but given " << info.ndim;
251+
ss << "convert numpy.ndarray to ncnn.Mat only dims <=4 support now, but given " << info.ndim;
247252
pybind11::pybind11_fail(ss.str());
248253
}
249254

@@ -283,6 +288,15 @@ PYBIND11_MODULE(ncnn, m)
283288
// so we set the cstep as numpy's cstep
284289
v->cstep = (int)info.shape[2] * (int)info.shape[1];
285290
}
291+
else if (info.ndim == 4)
292+
{
293+
v = new Mat((int)info.shape[3], (int)info.shape[2], (int)info.shape[1], (int)info.shape[0], info.ptr, elemsize);
294+
295+
// in ncnn, buffer to construct ncnn::Mat need align to ncnn::alignSize
296+
// with (w * h * d elemsize, 16) / elemsize, but the buffer from numpy not
297+
// so we set the cstep as numpy's cstep
298+
v->cstep = (int)info.shape[3] * (int)info.shape[2] * (int)info.shape[1];
299+
}
286300
return v;
287301
}),
288302
py::arg("array"))
@@ -323,6 +337,17 @@ PYBIND11_MODULE(ncnn, m)
323337
strides.push_back(m.w * m.elemsize);
324338
strides.push_back(m.elemsize);
325339
}
340+
else if (m.dims == 4)
341+
{
342+
shape.push_back(m.c);
343+
shape.push_back(m.d);
344+
shape.push_back(m.h);
345+
shape.push_back(m.w);
346+
strides.push_back(m.cstep * m.elemsize);
347+
strides.push_back(m.w * m.h * m.elemsize);
348+
strides.push_back(m.w * m.elemsize);
349+
strides.push_back(m.elemsize);
350+
}
326351
return py::buffer_info(
327352
m.data, /* Pointer to buffer */
328353
m.elemsize, /* Size of one scalar */
@@ -347,9 +372,11 @@ PYBIND11_MODULE(ncnn, m)
347372
return mat.reshape(shape[0].cast<int>(), shape[1].cast<int>(), allocator);
348373
case 3:
349374
return mat.reshape(shape[0].cast<int>(), shape[1].cast<int>(), shape[2].cast<int>(), allocator);
375+
case 4:
376+
return mat.reshape(shape[0].cast<int>(), shape[1].cast<int>(), shape[2].cast<int>(), shape[3].cast<int>(), allocator);
350377
default:
351378
std::stringstream ss;
352-
ss << "shape must be 1, 2 or 3 dims, not " << shape.size();
379+
ss << "shape must be 1, 2, 3 or 4 dims, not " << shape.size();
353380
pybind11::pybind11_fail(ss.str());
354381
}
355382
return Mat();
@@ -361,6 +388,8 @@ PYBIND11_MODULE(ncnn, m)
361388
py::arg("w"), py::arg("h"), py::kw_only(), py::arg("allocator") = nullptr)
362389
.def("reshape", (Mat(Mat::*)(int, int, int, Allocator*) const) & Mat::reshape,
363390
py::arg("w"), py::arg("h"), py::arg("c"), py::kw_only(), py::arg("allocator") = nullptr)
391+
.def("reshape", (Mat(Mat::*)(int, int, int, int, Allocator*) const) & Mat::reshape,
392+
py::arg("w"), py::arg("h"), py::arg("d"), py::arg("c"), py::kw_only(), py::arg("allocator") = nullptr)
364393

365394
.def(
366395
"create",
@@ -372,11 +401,12 @@ PYBIND11_MODULE(ncnn, m)
372401
case 2:
373402
return mat.create(shape[0].cast<int>(), shape[1].cast<int>(), elemsize, elempack, allocator);
374403
case 3:
375-
return mat.create(shape[0].cast<int>(), shape[1].cast<int>(), shape[2].cast<int>(),
376-
elemsize, elempack, allocator);
404+
return mat.create(shape[0].cast<int>(), shape[1].cast<int>(), shape[2].cast<int>(), elemsize, elempack, allocator);
405+
case 4:
406+
return mat.create(shape[0].cast<int>(), shape[1].cast<int>(), shape[2].cast<int>(), shape[3].cast<int>(), elemsize, elempack, allocator);
377407
default:
378408
std::stringstream ss;
379-
ss << "shape must be 1, 2 or 3 dims, not " << shape.size();
409+
ss << "shape must be 1, 2, 3 or 4 dims, not " << shape.size();
380410
pybind11::pybind11_fail(ss.str());
381411
}
382412
return;
@@ -393,6 +423,9 @@ PYBIND11_MODULE(ncnn, m)
393423
.def("create", (void (Mat::*)(int, int, int, size_t, int, Allocator*)) & Mat::create,
394424
py::arg("w"), py::arg("h"), py::arg("c"), py::kw_only(),
395425
py::arg("elemsize") = 4, py::arg("elempack") = 1, py::arg("allocator") = nullptr)
426+
.def("create", (void (Mat::*)(int, int, int, int, size_t, int, Allocator*)) & Mat::create,
427+
py::arg("w"), py::arg("h"), py::arg("d"), py::arg("c"), py::kw_only(),
428+
py::arg("elemsize") = 4, py::arg("elempack") = 1, py::arg("allocator") = nullptr)
396429
.def("create_like", (void (Mat::*)(const Mat&, Allocator*)) & Mat::create_like,
397430
py::arg("m"), py::arg("allocator") = nullptr)
398431
.def("addref", &Mat::addref)
@@ -403,6 +436,8 @@ PYBIND11_MODULE(ncnn, m)
403436
.def("shape", &Mat::shape)
404437
.def("channel", (Mat(Mat::*)(int)) & Mat::channel, py::arg("c"))
405438
//.def("channel", (const Mat (Mat::*)(int) const) & Mat::channel, py::arg("c"))
439+
.def("depth", (Mat(Mat::*)(int)) & Mat::depth, py::arg("z"))
440+
//.def("depth", (const Mat (Mat::*)(int) const) & Mat::depth, py::arg("z"))
406441
.def(
407442
"row",
408443
[](Mat& m, int y) {
@@ -431,6 +466,8 @@ PYBIND11_MODULE(ncnn, m)
431466
py::arg("y"))
432467
.def("channel_range", (Mat(Mat::*)(int, int)) & Mat::channel_range, py::arg("c"), py::arg("channels"))
433468
//.def("channel_range", (const Mat (Mat::*)(int, int) const) & Mat::channel_range, py::arg("c"), py::arg("channels"))
469+
.def("depth_range", (Mat(Mat::*)(int, int)) & Mat::depth_range, py::arg("z"), py::arg("depths"))
470+
//.def("depth_range", (const Mat (Mat::*)(int, int) const) & Mat::depth_range, py::arg("z"), py::arg("depths"))
434471
.def("row_range", (Mat(Mat::*)(int, int)) & Mat::row_range, py::arg("y"), py::arg("rows"))
435472
//.def("row_range", (const Mat (Mat::*)(int, int) const) & Mat::row_range, py::arg("y"), py::arg("rows"))
436473
.def("range", (Mat(Mat::*)(int, int)) & Mat::range, py::arg("x"), py::arg("n"))
@@ -508,11 +545,12 @@ PYBIND11_MODULE(ncnn, m)
508545
.def_readwrite("dims", &Mat::dims)
509546
.def_readwrite("w", &Mat::w)
510547
.def_readwrite("h", &Mat::h)
548+
.def_readwrite("d", &Mat::d)
511549
.def_readwrite("c", &Mat::c)
512550
.def_readwrite("cstep", &Mat::cstep)
513551
.def("__repr__", [](const Mat& m) {
514552
std::stringstream ss;
515-
ss << "<ncnn.Mat w=" << m.w << " h=" << m.h << " c=" << m.c << " dims=" << m.dims
553+
ss << "<ncnn.Mat w=" << m.w << " h=" << m.h << " d=" << m.d << " c=" << m.c << " dims=" << m.dims
516554
<< " cstep=" << m.cstep << " elemsize=" << m.elemsize << " elempack=" << m.elempack << "\n\t"
517555
<< "refcount=" << (m.refcount ? *m.refcount : 0) << " data=0x" << static_cast<const void*>(m.data)
518556
<< " allocator=0x" << static_cast<const void*>(m.allocator) << ">\n";
@@ -720,6 +758,119 @@ PYBIND11_MODULE(ncnn, m)
720758
} // for k
721759
ss << "]\n";
722760
}
761+
else if (m.dims == 4)
762+
{
763+
bool dot_printed_c = false;
764+
ss << "[";
765+
for (int k = 0; k < m.c; k++)
766+
{
767+
bool dot_printed_d = false;
768+
if (k < max_count / 2 || k >= m.c - max_count / 2)
769+
{
770+
Mat channel = m.channel(k);
771+
if (k > 0)
772+
{
773+
ss << " ";
774+
}
775+
ss << "[";
776+
for (int z = 0; z < channel.d; z++)
777+
{
778+
bool dot_printed_h = false;
779+
if (z < max_count / 2 || z >= channel.d - max_count / 2)
780+
{
781+
if (z > 0)
782+
{
783+
ss << " ";
784+
}
785+
ss << "[";
786+
for (int j = 0; j < channel.h; j++)
787+
{
788+
bool dot_printed_w = false;
789+
if (j < max_count / 2 || j >= channel.h - max_count / 2)
790+
{
791+
if (j > 0)
792+
{
793+
ss << " ";
794+
}
795+
ss << "[";
796+
if (m.elemsize == 1)
797+
{
798+
const int8_t* row = channel.depth(z).row<int8_t>(j);
799+
for (int i = 0; i < channel.w; i++)
800+
{
801+
if (i < max_count / 2 || i >= channel.w - max_count / 2)
802+
{
803+
if (i > 0)
804+
{
805+
ss << ", ";
806+
}
807+
ss << static_cast<int>(row[i]);
808+
}
809+
else if (!dot_printed_w)
810+
{
811+
dot_printed_w = true;
812+
ss << ", ...";
813+
}
814+
}
815+
}
816+
if (m.elemsize == 4)
817+
{
818+
const float* row = channel.depth(z).row<float>(j);
819+
for (int i = 0; i < m.w; i++)
820+
{
821+
if (i < max_count / 2 || i >= m.w - max_count / 2)
822+
{
823+
if (i > 0)
824+
{
825+
ss << ", ";
826+
}
827+
ss << row[i];
828+
}
829+
else if (!dot_printed_w)
830+
{
831+
dot_printed_w = true;
832+
ss << ", ...";
833+
}
834+
}
835+
}
836+
ss << "]";
837+
if (j < channel.h - 1)
838+
{
839+
ss << "\n";
840+
}
841+
}
842+
else if (!dot_printed_h)
843+
{
844+
dot_printed_h = true;
845+
ss << " ...\n";
846+
}
847+
} // for j
848+
ss << "]";
849+
if (z < channel.d - 1)
850+
{
851+
ss << "\n";
852+
}
853+
}
854+
else if (!dot_printed_d)
855+
{
856+
dot_printed_d = true;
857+
ss << " ...\n";
858+
}
859+
} // for z
860+
ss << "]";
861+
if (k < m.c - 1)
862+
{
863+
ss << "\n\n";
864+
}
865+
}
866+
else if (!dot_printed_c)
867+
{
868+
dot_printed_c = true;
869+
ss << " ...\n";
870+
}
871+
} // for k
872+
ss << "]\n";
873+
}
723874
return ss.str();
724875
});
725876

@@ -932,6 +1083,21 @@ PYBIND11_MODULE(ncnn, m)
9321083
py::arg("top"), py::arg("bottom"), py::arg("left"), py::arg("right"),
9331084
py::arg("type"), py::arg("v"), py::arg("opt") = Option());
9341085

1086+
m.def("copy_make_border_3d", &copy_make_border_3d,
1087+
py::arg("src"), py::arg("dst"),
1088+
py::arg("top"), py::arg("bottom"), py::arg("left"), py::arg("right"), py::arg("front"), py::arg("behind"),
1089+
py::arg("type"), py::arg("v"), py::arg("opt") = Option());
1090+
m.def(
1091+
"copy_make_border_3d",
1092+
[](const Mat& src, int top, int bottom, int left, int right, int front, int behind, int type, float v, const Option& opt) {
1093+
Mat dst;
1094+
copy_make_border_3d(src, dst, top, bottom, left, right, front, behind, type, v, opt);
1095+
return dst;
1096+
},
1097+
py::arg("src"),
1098+
py::arg("top"), py::arg("bottom"), py::arg("left"), py::arg("right"), py::arg("front"), py::arg("behind"),
1099+
py::arg("type"), py::arg("v"), py::arg("opt") = Option());
1100+
9351101
m.def("copy_cut_border", &copy_cut_border,
9361102
py::arg("src"), py::arg("dst"),
9371103
py::arg("top"), py::arg("bottom"), py::arg("left"), py::arg("right"),

0 commit comments

Comments
 (0)