ncnn 源碼學習-Mat.h Mat.c


純小白記錄下騰訊的ncnn框架源碼的學習。純粹寫給自己看的,不保證正確性。

Mat 類似於 caffe中的blob,是一個張量的存儲結構體。

一、數據成員:

1、void * data 多維數據按一位數組來存儲。並且需要是16字節對齊的。

2、int * refcount  *refcount表示這個Mat被引用的個數。類似於智能指針?×refcount == 0 自動釋放。

3、size_t elemsize 每個元素的大小。sizeof(type)

4、dims 維度。如果是1維就是向量只有w,2維就是平面w * h, 3維就是立方體 w * h * c。

5、w h c三個維度

6、cstep : channel step 每個channel 有多少個元素。注意是元素個數,而不是字節數。

total() = cstep * c 整個Mat有多少個元素。

 

二、方法成員:

void create(int _w, size_t _elemsize);

一維數組初始化。只有一個w。二維平面就是w h。

三維有些特殊:

cstep 不是單純的 w * h, 而是要求每個channel的起始地址都是16字節對齊的。

cstep 是 w*h*elemsize在16的基礎上,對齊得到的。

也就是說,cstep * elemsize 必須是16的倍數。

 

所以,三維mat的大小不是簡單的elemsize* align(w * h * c,16)。而是elemsize* c* align(w*h, 16).

Mat  Mat::channel(int c)

返回某一個channel的一維新Mat。

在channel內部,數據是連續的。channel之間可能有空隙。為了保證每個channel的起始地址是16對齊。

float * Mat::row(int y)

返回某一個Mat的第一個channel的第y個行的首地址。

 

template <typename T>
inline Mat::operator T*()
{
    return (T*)data;
}
這個符號重載,神奇。把Mat轉換成任意T *類型的指針。

返回的其內存地址。

inline float& Mat::operator[](int i)
{
    return ((float*)data)[i];
}

重載了取下標操作,直接取其地址的第i個。

因為channel之間不是連續的,所以這么取對第1個以后的channel來說,可能會出問題。應該是對dim < 3的方法。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM