Commit eb471442 authored by Davis King's avatar Davis King

Added a column_major_layout for the matrix.

--HG--
extra : convert_revision : svn%3Afdd8eb12-d10e-0410-9acb-85c331704f74/trunk%402748
parent 55f1fcca
......@@ -311,7 +311,7 @@ namespace dlib
long num_rows = 0,
long num_cols = 0,
typename mem_manager = memory_manager<char>::kernel_1a,
typename layout = default_matrix_layout
typename layout = row_major_layout
>
class matrix : public matrix_exp<matrix<T,num_rows,num_cols,mem_manager,layout> >
{
......@@ -357,7 +357,7 @@ namespace dlib
unrolling which can result in substantially faster code.
Also note that the elements of this matrix are laid out in memory by the layout
object supplied as a template argument to this class. The default_matrix_layout
object supplied as a template argument to this class. The row_major_layout
sets elements down contiguously in memory and in row major order. Additionally,
all memory allocations are performed using the memory manager object supplied as
a template argument to this class.
......
......@@ -69,8 +69,10 @@ namespace dlib
// ----------------------------------------------------------------------------------------
struct default_matrix_layout
struct row_major_layout
{
// if a matrix is bigger than this many bytes then don't put it on the stack
const static size_t max_stack_based_size = 128;
// this is a hack to avoid a compile time error in visual studio 8. I would just
// use sizeof(T) and be done with it but that won't compile. The idea here
......@@ -96,9 +98,9 @@ namespace dlib
typename mem_manager,
int val = static_switch <
// when the sizes are all non zero and small
(num_rows*num_cols*get_sizeof_helper<T>::val <= 64) && (num_rows != 0 && num_cols != 0),
(num_rows*num_cols*get_sizeof_helper<T>::val <= max_stack_based_size) && (num_rows != 0 && num_cols != 0),
// when the sizes are all non zero and big
(num_rows*num_cols*get_sizeof_helper<T>::val >= 65) && (num_rows != 0 && num_cols != 0),
(num_rows*num_cols*get_sizeof_helper<T>::val > max_stack_based_size) && (num_rows != 0 && num_cols != 0),
num_rows == 0 && num_cols != 0,
num_rows != 0 && num_cols == 0,
num_rows == 0 && num_cols == 0
......@@ -477,6 +479,419 @@ namespace dlib
};
// ----------------------------------------------------------------------------------------
struct column_major_layout
{
// if a matrix is bigger than this many bytes then don't put it on the stack
const static size_t max_stack_based_size = 128;
// this is a hack to avoid a compile time error in visual studio 8. I would just
// use sizeof(T) and be done with it but that won't compile. The idea here
// is to avoid using the stack allocation of the layout object if it
// is going to contain another matrix and also avoid asking for the sizeof()
// the contained matrix.
template <typename T>
struct get_sizeof_helper
{
const static std::size_t val = sizeof(T);
};
template <typename T, long NR, long NC, typename mm, typename l>
struct get_sizeof_helper<matrix<T,NR,NC,mm,l> >
{
const static std::size_t val = 1000000;
};
template <
typename T,
long num_rows,
long num_cols,
typename mem_manager,
int val = static_switch <
// when the sizes are all non zero and small
(num_rows*num_cols*get_sizeof_helper<T>::val <= max_stack_based_size) && (num_rows != 0 && num_cols != 0),
// when the sizes are all non zero and big
(num_rows*num_cols*get_sizeof_helper<T>::val > max_stack_based_size) && (num_rows != 0 && num_cols != 0),
num_rows == 0 && num_cols != 0,
num_rows != 0 && num_cols == 0,
num_rows == 0 && num_cols == 0
>::value
>
class layout ;
/*!
WHAT THIS OBJECT REPRESENTS
This object represents the actual allocation of space for a matrix.
Small matrices allocate all their data on the stack and bigger ones
use a memory_manager to get their memory.
!*/
// ------------------------------------------------------------------------------------
template <
typename T,
long num_rows,
long num_cols,
typename mem_manager
>
class layout<T,num_rows,num_cols,mem_manager,1> : noncopyable // when the sizes are all non zero and small
{
public:
const static long NR = num_rows;
const static long NC = num_cols;
layout() {}
T& operator() (
long r,
long c
) { return data[c][r]; }
const T& operator() (
long r,
long c
) const { return data[c][r]; }
T& operator() (
long i
) { return *(*data + i); }
const T& operator() (
long i
) const { return *(*data + i); }
void swap(
layout& item
)
{
for (long r = 0; r < num_rows; ++r)
{
for (long c = 0; c < num_cols; ++c)
{
exchange((*this)(r,c),item(r,c));
}
}
}
long nr (
) const { return num_rows; }
long nc (
) const { return num_cols; }
void set_size (
long nr,
long nc
)
{
}
private:
T data[num_cols][num_rows];
};
// ------------------------------------------------------------------------------------
template <
typename T,
long num_rows,
long num_cols,
typename mem_manager
>
class layout<T,num_rows,num_cols,mem_manager,2> : noncopyable // when the sizes are all non zero and big
{
public:
const static long NR = num_rows;
const static long NC = num_cols;
layout (
) { data = pool.allocate_array(num_rows*num_cols); }
~layout ()
{ pool.deallocate_array(data); }
T& operator() (
long r,
long c
) { return data[c*num_rows + r]; }
const T& operator() (
long r,
long c
) const { return data[c*num_rows + r]; }
T& operator() (
long i
) { return data[i]; }
const T& operator() (
long i
) const { return data[i]; }
void swap(
layout& item
)
{
std::swap(item.data,data);
pool.swap(item.pool);
}
long nr (
) const { return num_rows; }
long nc (
) const { return num_cols; }
void set_size (
long nr,
long nc
)
{
}
private:
T* data;
typename mem_manager::template rebind<T>::other pool;
};
// ------------------------------------------------------------------------------------
template <
typename T,
long num_rows,
long num_cols,
typename mem_manager
>
class layout<T,num_rows,num_cols,mem_manager,3> : noncopyable // when num_rows == 0 && num_cols != 0,
{
public:
const static long NR = num_rows;
const static long NC = num_cols;
layout (
):data(0), nr_(0) { }
~layout ()
{
if (data)
pool.deallocate_array(data);
}
T& operator() (
long r,
long c
) { return data[c*nr_ + r]; }
const T& operator() (
long r,
long c
) const { return data[c*nr_ + r]; }
T& operator() (
long i
) { return data[i]; }
const T& operator() (
long i
) const { return data[i]; }
void swap(
layout& item
)
{
std::swap(item.data,data);
std::swap(item.nr_,nr_);
pool.swap(item.pool);
}
long nr (
) const { return nr_; }
long nc (
) const { return num_cols; }
void set_size (
long nr,
long nc
)
{
if (data)
{
pool.deallocate_array(data);
}
data = pool.allocate_array(nr*nc);
nr_ = nr;
}
private:
T* data;
long nr_;
typename mem_manager::template rebind<T>::other pool;
};
// ------------------------------------------------------------------------------------
template <
typename T,
long num_rows,
long num_cols,
typename mem_manager
>
class layout<T,num_rows,num_cols,mem_manager,4> : noncopyable // when num_rows != 0 && num_cols == 0
{
public:
const static long NR = num_rows;
const static long NC = num_cols;
layout (
):data(0), nc_(0) { }
~layout ()
{
if (data)
{
pool.deallocate_array(data);
}
}
T& operator() (
long r,
long c
) { return data[c*num_rows + r]; }
const T& operator() (
long r,
long c
) const { return data[c*num_rows + r]; }
T& operator() (
long i
) { return data[i]; }
const T& operator() (
long i
) const { return data[i]; }
void swap(
layout& item
)
{
std::swap(item.data,data);
std::swap(item.nc_,nc_);
pool.swap(item.pool);
}
long nr (
) const { return num_rows; }
long nc (
) const { return nc_; }
void set_size (
long nr,
long nc
)
{
if (data)
{
pool.deallocate_array(data);
}
data = pool.allocate_array(nr*nc);
nc_ = nc;
}
private:
T* data;
long nc_;
typename mem_manager::template rebind<T>::other pool;
};
// ------------------------------------------------------------------------------------
template <
typename T,
long num_rows,
long num_cols,
typename mem_manager
>
class layout<T,num_rows,num_cols,mem_manager,5> : noncopyable // when num_rows == 0 && num_cols == 0
{
public:
const static long NR = num_rows;
const static long NC = num_cols;
layout (
):data(0), nr_(0), nc_(0) { }
~layout ()
{
if (data)
{
pool.deallocate_array(data);
}
}
T& operator() (
long r,
long c
) { return data[c*nr_ + r]; }
const T& operator() (
long r,
long c
) const { return data[c*nr_ + r]; }
T& operator() (
long i
) { return data[i]; }
const T& operator() (
long i
) const { return data[i]; }
void swap(
layout& item
)
{
std::swap(item.data,data);
std::swap(item.nc_,nc_);
std::swap(item.nr_,nr_);
pool.swap(item.pool);
}
long nr (
) const { return nr_; }
long nc (
) const { return nc_; }
void set_size (
long nr,
long nc
)
{
if (data)
{
pool.deallocate_array(data);
}
data = pool.allocate_array(nr*nc);
nr_ = nr;
nc_ = nc;
}
private:
T* data;
long nr_;
long nc_;
typename mem_manager::template rebind<T>::other pool;
};
};
// ----------------------------------------------------------------------------------------
}
......
......@@ -10,7 +10,7 @@ namespace dlib
// ----------------------------------------------------------------------------------------
struct default_matrix_layout
struct row_major_layout
{
/*!
This is the default matrix layout. Any matrix object that uses this
......@@ -20,6 +20,17 @@ namespace dlib
!*/
};
// ----------------------------------------------------------------------------------------
struct column_major_layout
{
/*!
Any matrix object that uses this layout will be laid out in memory in
column major order. Additionally, all elements are contiguous (e.g.
there isn't any padding at the ends of rows or anything like that)
!*/
};
// ----------------------------------------------------------------------------------------
}
......
......@@ -595,7 +595,7 @@ namespace dlib
const static long NR = OP::NR;
const static long NC = OP::NC;
const static long cost = OP::cost;
typedef default_matrix_layout layout_type;
typedef row_major_layout layout_type;
};
template <
......@@ -682,7 +682,7 @@ namespace dlib
const static long NR = OP::NR;
const static long NC = OP::NC;
const static long cost = OP::cost;
typedef default_matrix_layout layout_type;
typedef row_major_layout layout_type;
};
template <
......@@ -761,7 +761,7 @@ namespace dlib
const static long NR = OP::NR;
const static long NC = OP::NC;
const static long cost = OP::cost;
typedef default_matrix_layout layout_type;
typedef row_major_layout layout_type;
};
template <
......@@ -924,7 +924,7 @@ namespace dlib
const static long NR = 0;
const static long NC = 1;
const static long cost = 1;
typedef default_matrix_layout layout_type;
typedef row_major_layout layout_type;
};
template <
......@@ -1004,7 +1004,7 @@ namespace dlib
{
typedef typename M::type type;
typedef typename M::mem_manager_type mem_manager_type;
typedef default_matrix_layout layout_type;
typedef row_major_layout layout_type;
const static long NR = 0;
const static long NC = 1;
const static long cost = 1;
......@@ -1087,7 +1087,7 @@ namespace dlib
{
typedef typename M::type type;
typedef typename M::mem_manager_type mem_manager_type;
typedef default_matrix_layout layout_type;
typedef row_major_layout layout_type;
const static long NR = 0;
const static long NC = 0;
const static long cost = 1;
......@@ -1265,7 +1265,7 @@ namespace dlib
{
typedef long type;
typedef memory_manager<char>::kernel_1a mem_manager_type;
typedef default_matrix_layout layout_type;
typedef row_major_layout layout_type;
const static long NR = 0;
const static long NC = 1;
const static long cost = 1;
......@@ -1361,7 +1361,7 @@ namespace dlib
const static long NR = tabs<(end - start)>::value/inc_ + 1;
const static long NC = 1;
const static long cost = 1;
typedef default_matrix_layout layout_type;
typedef row_major_layout layout_type;
};
template <long start, long inc_, long end>
......
......@@ -10,7 +10,7 @@ namespace dlib
// ----------------------------------------------------------------------------------------
struct default_matrix_layout;
struct row_major_layout;
// ----------------------------------------------------------------------------------------
......@@ -19,7 +19,7 @@ namespace dlib
long num_rows = 0,
long num_cols = 0,
typename mem_manager = memory_manager<char>::kernel_1a,
typename layout = default_matrix_layout
typename layout = row_major_layout
>
class matrix;
......
......@@ -47,7 +47,7 @@ namespace
}
{
matrix<double,5,5> m(5,5);
matrix<double,5,5,MM,column_major_layout> m(5,5);
for (long r = 0; r < m.nr(); ++r)
{
......@@ -123,7 +123,7 @@ namespace
{
matrix<double,5,2> m;
matrix<double,5,2,MM,column_major_layout> m;
for (long r = 0; r < m.nr(); ++r)
{
......@@ -164,12 +164,12 @@ namespace
{
matrix<long> a1(5,1);
matrix<long,0,0,MM> a2(1,5);
matrix<long,0,0,MM,column_major_layout> a2(1,5);
matrix<long,5,1> b1(5,1);
matrix<long,1,5> b2(1,5);
matrix<long,0,1> c1(5,1);
matrix<long,1,0> c2(1,5);
matrix<long,0,1,MM> d1(5,1);
matrix<long,0,1,MM,column_major_layout> d1(5,1);
matrix<long,1,0,MM> d2(1,5);
for (long i = 0; i < 5; ++i)
......@@ -322,7 +322,7 @@ namespace
}
{
matrix<double> a(6,7);
matrix<double,0,0,MM,column_major_layout> a(6,7);
for (long r = 0; r < a.nr(); ++r)
{
......@@ -428,7 +428,7 @@ namespace
}
{
matrix<long,5,5> m1, res;
matrix<long,5,5,MM,column_major_layout> m1, res;
matrix<long,2,2> m2;
set_all_elements(m1,0);
......
......@@ -368,7 +368,7 @@ namespace
DLIB_CASSERT(sum(abs(sigmoid(dm10) -sigmoid(m10))) < 1e-10,sum(abs(sigmoid(dm10) -sigmoid(m10))) );
matrix<double, 7, 7,MM> m7;
matrix<double, 7, 7,MM,column_major_layout> m7;
matrix<double> dm7(7,7);
for (long r= 0; r< dm7.nr(); ++r)
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment