Skip to content
This repository has been archived by the owner on Nov 17, 2023. It is now read-only.

MNIST is OK #20

Merged
merged 12 commits into from
Aug 20, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,14 @@ endif
BIN = test/api_registry_test test/test_storage
OBJ = narray_op_cpu.o
# add threaded engine after it is done
OBJCXX11 = engine.o narray.o c_api.o registry.o symbol.o storage.o fully_connected_cpu.o static_graph.o
OBJCXX11 = engine.o narray.o c_api.o registry.o symbol.o storage.o fully_connected_cpu.o static_graph.o activation_cpu.o elementwise_sum_cpu.o graph_executor.o pooling_cpu.o
CUOBJ =
SLIB = lib/libmxnet.so
ALIB = lib/libmxnet.a
LIB_DEP = $(DMLC_CORE)/libdmlc.a

ifeq ($(USE_CUDA), 1)
CUOBJ += narray_op_gpu.o fully_connected_gpu.o
CUOBJ += narray_op_gpu.o fully_connected_gpu.o activation_gpu.o elementwise_sum_gpu.o pooling_gpu.o
endif

.PHONY: clean all test lint doc
Expand All @@ -81,12 +81,19 @@ narray.o: src/narray/narray.cc
narray_op_cpu.o: src/narray/narray_op_cpu.cc src/narray/narray_op-inl.h
narray_op_gpu.o: src/narray/narray_op_gpu.cu src/narray/narray_op-inl.h
symbol.o: src/symbol/symbol.cc
graph_executor.o: src/symbol/graph_executor.cc
static_graph.o : src/symbol/static_graph.cc
registry.o: src/registry.cc
c_api.o: src/c_api.cc
operator.o: src/operator/static_operator_wrapper.cc
fully_connected_cpu.o: src/operator/fully_connected.cc
fully_connected_gpu.o: src/operator/fully_connected.cu
activation_cpu.o: src/operator/activation.cc
activation_gpu.o: src/operator/activation.cu
elementwise_sum_cpu.o: src/operator/elementwise_sum.cc
elementwise_sum_gpu.o: src/operator/elementwise_sum.cu
pooling_cpu.o: src/operator/pooling.cc
pooling_gpu.o: src/operator/pooling.cu


lib/libmxnet.a: $(OBJ) $(OBJCXX11) $(CUOBJ)
Expand Down
152 changes: 79 additions & 73 deletions include/mxnet/c_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,11 @@ typedef void *AtomicSymbolCreator;
typedef void *SymbolHandle;
/*! \brief handle to a AtomicSymbol */
typedef void *AtomicSymbolHandle;
/*! \brief handle to a NArrayOperator */
typedef void *OperatorHandle;
/*! \brief handle to an Executor */
typedef void *ExecutorHandle;
/*! \brief handle to a DataIterator */
typedef void *DataIterHandle;

/*!
/*
* \brief return str message of the last error
* all function in this file will return 0 when success
* and -1 when an error occured,
Expand All @@ -49,10 +48,9 @@ typedef void *DataIterHandle;
* \return error info
*/
MXNET_DLL const char *MXGetLastError();

//--------------------------------
//-------------------------------------
// Part 1: NArray creation and deletion
//--------------------------------
//-------------------------------------
/*!
* \brief create a NArray handle that is not initialized
* can be used to pass in as mutate variables
Expand Down Expand Up @@ -189,7 +187,6 @@ MXNET_DLL int MXFuncDescribe(FunctionHandle fun,
mx_uint *num_scalars,
mx_uint *num_mutate_vars,
int *type_mask);

/*!
* \brief invoke a function, the array size of passed in arguments
* must match the values in the
Expand Down Expand Up @@ -301,8 +298,8 @@ MXNET_DLL int MXSymbolListArguments(SymbolHandle symbol,
* \return 0 when success, -1 when failure happens
*/
MXNET_DLL int MXSymbolListReturns(SymbolHandle symbol,
mx_uint *out_size,
const char ***out_str_array);
mx_uint *out_size,
const char ***out_str_array);
/*!
* \brief Compose the symbol on other symbols.
*
Expand All @@ -322,82 +319,91 @@ MXNET_DLL int MXSymbolCompose(SymbolHandle sym,
mx_uint num_args,
const char** keys,
SymbolHandle* args);
/*!
* \brief infer shape of unknown input shapes given the known one.
* The shapes are packed into a CSR matrix represented by arg_ind_ptr and arg_shape_data
* The call will be treated as a kwargs call if key != nullptr or num_args==0, otherwise it is positional.
*
* \param sym symbol handle
* \param num_args numbe of input arguments.
* \param keys the key of keyword args (optional)
* \param arg_ind_ptr the head pointer of the rows in CSR
* \param arg_shape_data the content of the CSR
* \param in_shape_size sizeof the returning array of in_shapes
* \param in_shape_ndim returning array of shape dimensions of eachs input shape.
* \param in_shape_data returning array of pointers to head of the input shape.
* \param out_shape_size sizeof the returning array of out_shapes
* \param out_shape_ndim returning array of shape dimensions of eachs input shape.
* \param out_shape_data returning array of pointers to head of the input shape.
* \param complete whether infer shape completes or more information is needed.
* \return 0 when success, -1 when failure happens
*/
MXNET_DLL int MXSymbolInferShape(SymbolHandle sym,
mx_uint num_args,
const char** keys,
const mx_uint *arg_ind_ptr,
const mx_uint *arg_shape_data,
mx_uint *in_shape_size,
const mx_uint **in_shape_ndim,
const mx_uint ***in_shape_data,
mx_uint *out_shape_size,
const mx_uint **out_shape_ndim,
const mx_uint ***out_shape_data,
int *complete);
//--------------------------------------------
// Part 4: operator interface on NArray
// Part 4: Executor interface
//--------------------------------------------
/*!
* \brief create operator from symbol
* \param sym the symbol to create operator from
* \param dev_mask device mask to indicate the device type
* \param dev_id the device id we want to bind the symbol to
* \param out the corresponding function handle
* \brief Executor forward method
*
* \param handle executor handle
* \return 0 when success, -1 when failure happens
*/
MXNET_DLL int MXOpCreate(SymbolHandle sym,
int dev_mask,
int dev_id,
OperatorHandle *out);
MXNET_DLL int MXExecutorForward(ExecutorHandle handle);
/*!
* \brief free the operator handle
* \param op the handle to be freed
* \brief Excecutor run backward
*
* \param handle execute handle
* \param len lenth
* \param head_grads NArray handle for heads' gradient
*
* \return 0 when success, -1 when failure happens
*/
MXNET_DLL int MXOpFree(OperatorHandle op);
MXNET_DLL int MXExecutorBackward(ExecutorHandle handle,
mx_uint len,
NArrayHandle *head_grads);

/*!
* \brief return an array to describe the arguments
* of this operator
* \param out_size the size of output array
* \param out_array the array of parameter requirments
* \brief Get executor's head NArray
*
* \param handle executor handle
* \param out_size output narray vector size
* \param out out put narray handles
* \return 0 when success, -1 when failure happens
*/
MXNET_DLL int MXOpDescribeArgs(mx_uint *out_size,
int **out_array);
MXNET_DLL int MXExecutorHeads(ExecutorHandle handle,
mx_uint *out_size,
NArrayHandle **out);

/*!
* \brief infer shape of unknown input shapes given the known one
* this function do not return the shape of output
* the shapes are packed into a CSR matrix represened by ind_ptr and shape_array
* \brief Generate Executor from symbol
*
* When the function returns, it return a new CSR matrix by updating ind_ptr,
* and return the content in the return value
*
* \param ind_ptr the head pointer of the rows in CSR
* \param shape_array the content of the CSR
* \param out_nout number of output arguments of this operation
* \param out_array another content of CSR with infered shape
* \return 0 when success, -1 when failure happens
*/
MXNET_DLL int MXOpInferShape(mx_uint *ind_ptr,
mx_uint *shape_array,
mx_uint *out_nout,
mx_uint *out_array);
/*!
* \brief call forward on the operator
* \param op the operator handle
* \param in_data array of input narray to the operator
* \param out_data array of output NArray to hold the result
* \return 0 when success, -1 when failure happens
*/
MXNET_DLL int MXOpForward(OperatorHandle op,
NArrayHandle *in_data,
NArrayHandle *out_data);
/*!
* \brief call backward on the operator
* \param op the operator handle
* \param grad_next array of output gradients
* \param in_data array of input narray to the operator
* \param out_data array of output narray to the operator
* \param out_grad array to holds the gradient on these input
* can be NULL if that position request is kNullOp
* \param reqs gradient request type
* \return 0 when success, -1 when failure happens
* \sa mxnet::Operator::GradReqType
*/
MXNET_DLL int MXOpBackward(OperatorHandle op,
NArrayHandle *grad_next,
NArrayHandle *in_data,
NArrayHandle *out_data,
NArrayHandle *out_grad,
mx_uint *reqs);
* \param symbol_handle symbol handle
* \param len length
* \param in_args in args array
* \param arg_grad_store arg grads handle array
* \param grad_req_type grad req array
* \param out output executor handle
* \return 0 when success, -1 when failure happens
*/
MXNET_DLL int MXExecutorBind(SymbolHandle symbol_handle,
int dev_mask,
int dev_id,
mx_uint len,
NArrayHandle *in_args,
NArrayHandle *arg_grad_store,
mx_uint *grad_req_type,
ExecutorHandle *out);

//--------------------------------------------
// Part 5: IO Interface
Expand Down
10 changes: 10 additions & 0 deletions include/mxnet/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#ifndef MXNET_CONTEXT_H_
#define MXNET_CONTEXT_H_

#include "./base.h"

namespace mxnet {

/*! \brief Context information about the execution enviroment */
Expand All @@ -31,6 +33,14 @@ struct Context {
inline bool operator==(const Context &b) const {
return dev_mask == b.dev_mask && dev_id == b.dev_id;
}
/*!
* \brief check if current context not equals another one
* \param b another context to compare
* \return whether they are not the same
*/
inline bool operator!=(const Context &b) const {
return !(*this == b);
}
};

/*!
Expand Down
67 changes: 54 additions & 13 deletions include/mxnet/narray.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class NArray {
*/
NArray(const TShape &shape, Context ctx,
bool delay_alloc = false)
: ptr_(new Chunk(shape, ctx, delay_alloc)) {
: ptr_(new Chunk(shape.Size(), ctx, delay_alloc)), shape_(shape), offset_(0) {
}
/*!
* \brief constructing a static NArray that shares data with TBlob
Expand All @@ -45,19 +45,20 @@ class NArray {
* \param dev_id the device id this tensor sits at
*/
NArray(const TBlob &data, int dev_id)
: ptr_(new Chunk(data, dev_id)) {
: ptr_(new Chunk(data, dev_id)), shape_(data.shape_), offset_(0) {
}
/*!
* \return the shape of current NArray
*/
inline const TShape &shape() const {
return ptr_->data.shape_;
return shape_;
}
/*!
* \return the data TBlob
*/
inline const TBlob &data() const {
return ptr_->data;
inline TBlob data() const {
return TBlob(static_cast<real_t*>(ptr_->shandle.dptr) + offset_, \
shape_, ptr_->shandle.ctx.dev_mask);
}
/*!
* \return the context of NArray, this function is only valid when the NArray is not empty
Expand Down Expand Up @@ -123,6 +124,43 @@ class NArray {
* \return the new copy
*/
NArray Copy(Context ctx) const;
/*!
* \brief Slice a NArray
*
* \param begin begin index in first dim
* \param end end index in first dim
*
* \return sliced NArray
*/
inline NArray Slice(index_t begin, index_t end) const {
NArray ret = *this;
CHECK_GE(shape_.ndim(), 0) << "NArray not initialized";
CHECK_GE(shape_[0], end) << "Chunk is smaller than required";
size_t length = 1;
if (shape_.ndim() == 1) {
ret.offset_= begin;
} else {
for (index_t i = 1; i < shape_.ndim(); ++i) {
length *= shape_[i];
}
ret.offset_ = begin * length;
}
ret.shape_[0] = end - begin;
return ret;
}
/*!
* \brief Reshape current NArray
*
* \param shape new shape
* \return NArray in new shape
*/
inline NArray Reshape(const TShape &shape) const {
CHECK_GE(shape_.Size(), shape.Size()) \
<< "required shape is larger than chunk";
NArray ret = *this;
ret.shape_ = shape;
return ret;
}

private:
/*! \brief the real data chunk that backs NArray */
Expand All @@ -131,8 +169,6 @@ class NArray {
Storage::Handle shandle;
/*! \brief variable from DAG engine */
DAGEngine::Variable var;
/*! \brief holds the data content */
TBlob data;
/*!
* \brief if this is true, this means the data do not come
* from Storage, and do not need to be freed
Expand All @@ -146,25 +182,25 @@ class NArray {
}
/*! \brief construct from static data */
Chunk(const TBlob &data, int dev_id)
: data(data),
static_data(true),
: static_data(true),
delay_alloc(false) {
var = DAGEngine::Get()->NewVar();
shandle.ctx = Context(data.dev_mask_, dev_id);
shandle.dptr = data.dptr_;
shandle.size = data.shape_.Size() * sizeof(real_t);
}
/*! \brief construct a new chunk */
Chunk(const TShape &shape, Context ctx, bool delay_alloc_)
Chunk(uint64_t size, Context ctx, bool delay_alloc_)
: static_data(false), delay_alloc(true) {
var = DAGEngine::Get()->NewVar();
data.shape_ = shape;
shandle.size = size * sizeof(real_t);
shandle.ctx = ctx;
if (!delay_alloc_) this->CheckAndAlloc();
}
/*! \brief check if delay alloc is on, do alloc if not yet done */
inline void CheckAndAlloc(void) {
if (delay_alloc) {
shandle = Storage::Get()->Alloc(data.shape_.Size() * sizeof(real_t), shandle.ctx);
data = TBlob(static_cast<real_t*>(shandle.dptr), data.shape_, shandle.ctx.dev_mask);
shandle = Storage::Get()->Alloc(shandle.size, shandle.ctx);
delay_alloc = false;
}
}
Expand All @@ -183,6 +219,11 @@ class NArray {
};
/*! \brief internal data of NArray */
std::shared_ptr<Chunk> ptr_;
/*! \brief shape of current NArray */
TShape shape_;
/*! \brief offset in chunk */
size_t offset_;

// add friend to helper functions
friend void CopyFromTo(const NArray &from, NArray *to);
template<typename OP>
Expand Down
Loading