mshadow是一个模板库,支持CPU和GPU
目录结构为
├── CHANGES.md
├── cmake
│ ├── Cuda.cmake
│ ├── mshadow.cmake
│ └── Utils.cmake
├── doc
│ ├── Doxyfile
│ ├── mkdoc.sh
│ └── README.md
├── guide
│ ├── basic.cpp
│ ├── basic_stream.cu
│ ├── config.mk
│ ├── defop.cpp
│ ├── exp-template
│ │ ├── exp_lazy.cpp
│ │ ├── exp_template.cpp
│ │ ├── exp_template_op.cpp
│ │ ├── Makefile
│ │ └── README.md
│ ├── Makefile
│ ├── mshadow-ps
│ │ ├── 2-levels.png
│ │ ├── config.mk
│ │ ├── dbstr.h
│ │ ├── dist_async_sum.cpp
│ │ ├── dist_async_sum-inl.h
│ │ ├── local.sh
│ │ ├── local_sum.cpp
│ │ ├── local_sum.cu
│ │ ├── local_sum-inl.h
│ │ ├── Makefile
│ │ └── README.md
│ ├── neuralnet
│ │ ├── config.mk
│ │ ├── convnet.cu
│ │ ├── Makefile
│ │ ├── nnet.cu
│ │ ├── nnet_ps.cu
│ │ ├── README.md
│ │ └── util.h
│ └── README.md
├── LICENSE
├── make
│ ├── mshadow.mk
│ └── README.md
├── mshadow
│ ├── base.h
│ ├── cuda
│ │ ├── reduce.cuh
│ │ └── tensor_gpu-inl.cuh
│ ├── dot_engine-inl.h
│ ├── expr_engine-inl.h
│ ├── expression.h
│ ├── expr_scalar-inl.h
│ ├── extension
│ │ ├── broadcast.h
│ │ ├── broadcast_with_axis.h
│ │ ├── channel_pool.h
│ │ ├── channel_unpool.h
│ │ ├── choose.h
│ │ ├── complex.h
│ │ ├── concat.h
│ │ ├── crop.h
│ │ ├── fill.h
│ │ ├── flip.h
│ │ ├── implicit_gemm.h
│ │ ├── mask.h
│ │ ├── mirror.h
│ │ ├── one_hot.h
│ │ ├── pack_col2patch.h
│ │ ├── pad.h
│ │ ├── range.h
│ │ ├── reduceto1d.h
│ │ ├── reduce_with_axis.h
│ │ ├── reshape.h
│ │ ├── slice_ex.h
│ │ ├── slice.h
│ │ ├── spatial_pool.h
│ │ ├── spatial_unpool.h
│ │ ├── spatial_upsampling_nearest.h
│ │ ├── swapaxis.h
│ │ ├── take_grad.h
│ │ ├── take.h
│ │ ├── transpose.h
│ │ └── unpack_patch2col.h
│ ├── extension.h
│ ├── half.h
│ ├── io.h
│ ├── logging.h
│ ├── packet
│ │ ├── plain-inl.h
│ │ └── sse-inl.h
│ ├── packet-inl.h
│ ├── random.h
│ ├── README.md
│ ├── stream_gpu-inl.h
│ ├── tensor_blob.h
│ ├── tensor_container.h
│ ├── tensor_cpu-inl.h
│ ├── tensor_gpu-inl.h
│ └── tensor.h
├── mshadow-ps
│ ├── mshadow_ps.h
│ ├── ps_dist-inl.h
│ ├── ps_local-inl.h
│ ├── ps_rabit-inl.h
│ ├── README.md
│ ├── thread.h
│ └── thread_util.h
├── README.md
├── scripts
│ └── travis_script.sh
└── test
├── Makefile
├── pairtest.cu
├── pool.cu
├── reshape.cu
├── test.cu
├── test.h
├── test_tblob.cc
└── unpack.cu
所有的加减操作都是element-wise形式的,例如
void UpdateSGD(Tensor<cpu, 2> weight, Tensor<cpu, 2> grad, float eta, float lambda) {
weight -= eta * (grad + lambda * weight);
}
将被翻译成
void UpdateSGD(Tensor<cpu,2> weight, Tensor<cpu,2> grad, float eta, float lambda) {
for (index_t y = 0; y < weight.size(0); ++y) {
for (index_t x = 0; x < weight.size(1); ++x) {
weight[y][x] -= eta * (grad[y][x] + lambda * weight[y][x]);
}
}
}
通过mshadow写一份xpu代码,就可以不用再写gpu和cpu代码了
上面的代码也已写为
template<typename xpu>
void UpdateSGD(Tensor<xpu, 2> weight, const Tensor<xpu, 2> &grad,
float eta, float lambda) {
weight -= eta * (grad + lambda * weight);
}
basic.cpp中有基本的用法
// header file to use mshadow
#include "mshadow/tensor.h"
// this namespace contains all data structures, functions
using namespace mshadow;
// this namespace contains all operator overloads
using namespace mshadow::expr;
int main(void) {
// intialize tensor engine before using tensor operation, needed for CuBLAS
InitTensorEngine<cpu>();
// assume we have a float space
float data[20];
// create a 2 x 5 x 2 tensor, from existing space
Tensor<cpu, 3> ts(data, Shape3(2,5,2));
// take first subscript of the tensor
Tensor<cpu, 2> mat = ts[0];
// Tensor object is only a handle, assignment means they have same data content
// we can specify content type of a Tensor, if not specified, it is float bydefault
Tensor<cpu, 2, float> mat2 = mat;
// shape of matrix, note size order is the same as numpy
printf("%u X %u matrix\n", mat.size(0), mat.size(1));
// initialize all element to zero
mat = 0.0f;
// assign some values
mat[0][1] = 1.0f; mat[1][0] = 2.0f;
// elementwise operations
mat += (mat + 10.0f) / 10.0f + 2.0f;
// print out matrix, note: mat2 and mat1 are handles(pointers)
for (index_t i = 0; i < mat.size(0); ++i) {
for (index_t j = 0; j < mat.size(1); ++j) {
printf("%.2f ", mat2[i][j]);
}
printf("\n");
}
// shutdown tensor enigne after usage
ShutdownTensorEngine<cpu>();
return 0;
}
可以在mxnet/src/operator/m_shadow_op.h中增加新的操作(里面有sign函数)
struct sigmoid {
MSHADOW_XINLINE static float Map(float a) {
return 1.0f / (1.0f + expf(-a));
}
};
具体使用例子为
template<typename xpu>
void ExampleSigmoid(Tensor<xpu, 2> out, const Tensor<xpu, 2> &in) {
out = F<sigmoid>(in * 2.0f) + 1.0f;
out = F<sigmoid>(in);
}
[1] 源代码
[2] 教程