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

Commit

Permalink
Merge pull request #20 from antinucleon/master
Browse files Browse the repository at this point in the history
MNIST is OK
  • Loading branch information
antinucleon committed Aug 20, 2015
2 parents 9f4d31c + 910738d commit 838da47
Show file tree
Hide file tree
Showing 42 changed files with 2,741 additions and 781 deletions.
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

0 comments on commit 838da47

Please sign in to comment.