# MXNet System Architecture

![System Overview](https://raw.githubusercontent.com/dmlc/dmlc.github.io/master/img/mxnet/system/overview.png)

This figure shows the major modules and components of the MXNet system and their interaction. The modules are:

- Runtime Dependency Engine: Schedules and executes the
  operations according to their read/write dependency.
- Storage Allocator: Efficiently allocates and recycles memory blocks for GPU and
  CPU processors.
- Resource Manager: Manages global resources, such as the random number generator and temporal space.
- NDArray: Dynamic asynchronous n-dimensional arrays, which provide flexible
  imperative programs for MXNet.
- Symbolic Execution: Static symbolic graph executor, which provides efficient symbolic
  graph execution and optimization.
- Operator: Operators that define static forward and gradient
  calculation (backprop).
- SimpleOp: Operators that extend to NDArray operators and symbolic operators
  in a unified fashion.
- Symbol Construction: Symbolic construction, which provides a way to construct
  a computation graph (net configuration).
- KVStore: Key-value store interface for easy parameter synchronization.
- Data Loading(IO): Efficient distributed data loading and augmentation.

# MXNet System Components

## Execution Engine

You can use MXNet's engine not only for deep learning, but for any domain-specific problem. It's designed to solve a general problem: execute a bunch of functions following their dependencies. Execution of any two functions with dependencies should be serialized.
To boost performance, functions with no dependencies *can* be executed in parallel.
For a general discussion of this topic, see the [Note on Dependency Engine](note_engine.md).

### Interface

The following API is the core interface for the execution engine:

```c++
    virtual void PushSync(Fn exec_fun, Context exec_ctx,
                          std::vector<VarHandle> const& const_vars,
                          std::vector<VarHandle> const& mutate_vars) = 0;
```
This API allows you to push a function (`exec_fun`), along with its context information and dependencies, to the engine. `exec_ctx` is the context information in which the `exec_fun` should be executed. `const_vars` denotes the variables that the function reads from,  and `mutate_vars` are the variables to be modified. Regardless of the details that we'll explain later, the engine guarantees following order:

>*The execution of any two functions when one of them modifies at least one common variable is serialized in their push order.*

### Function

The function type of the engine is:

```c++
    using Fn = std::function<void(RunContext)>;
```
`RunContext` contains runtime information, which is determined by the engine:

```c++
    struct RunContext {
        // stream pointer which could be safely cast to
        // cudaStream_t* type
	    void *stream;
    };
```
Alternatively, you could use `mxnet::engine::DAGEngine::Fn`, which is the same type definition.

All of the functions are executed by the engine's internal threads. In such a model, it's usually not a good idea to push *blocking* functions to the engine (usually for dealing with I/O tasks like disk, web service, UI, etc.) because it will occupy the execution thread and reduce total throughput. In that case, we provide another *asynchronous* function type:

```c++
    using Callback = std::function<void()>;
    using AsyncFn = std::function<void(RunContext, Callback)>;
```
In the `AsyncFn` function, you can pass the heavy part to your own threads and safely exit the body of the function. The engine doesn't consider the function finished until the `Callback` function is called.

### Context

You can specify the `Context` of the function to be executed within. This usually includes whether the function should be run on a CPU or a GPU, and if you specify a GPU, which GPU to use. `Context` is different from `RunContext`. `Context` contains device type (GPU/CPU) and device id, while `RunContext` contains information that can be decided only during runtime, for example, on which stream the function should be executed.

### VarHandle

`VarHandle` is used to specify the dependencies of functions. The MXNet engine is designed to be decoupled from other MXNet modules. So `VarHandle` is like an engine-provided token you use to represent the external resources the functions can use or modify. It's designed to be lightweight, so creating, deleting, or copying a variable incurs little overhead. Upon pushing the functions, you need to specify the variables that will be used (immutable) in the `const_vars` vector, and the variables that will be modified (mutable) in the `mutate_vars` vector. The engine uses one rule for resolving the dependencies among functions:

>*The execution of any two functions when one of them modifies at least one common variable is serialized in their push order.*

For example, if `Fn1` and `Fn2` both mutate, `V2`, `Fn2` is guaranteed to be executed after `Fn1` if `Fn2` is pushed after `Fn1`. On the other hand, if `Fn1` and `Fn2` both use `V2`, their actual execution order could be random.

This design allows the engine to schedule *state-mutating* operations. For example, the weight update function in DNN can now use the `+=` operator to update the weights in place, rather than generating a new weight array each time.

To create a variable, use the `NewVar()` API. To delete a variable, use the `PushDelete` API.

### Push and Wait

*All `Push` APIs are asynchronous.* The API call returns immediately regardless of whether the pushed `Fn` is finished. This allows the engine to start computing at the same time the user thread is pushing functions. All `Push` APIs are not thread-safe. To be specific, only one thread should make engine API calls at a time.

If you want to wait for a specific `Fn` to be finished, include a callback function in the closure, and call the function at the end of your `Fn`.

If you want to wait for all `Fn`s that involve (use or mutate) a certain variable to finish, use the `WaitForVar(var)` API.

If you want to wait for all pushed `Fn`s to finish, use the `WaitForAll()` API.

### Save Object Creation Cost

In some cases, you need to push several functions to the engine for a long period of time. If the computation of these functions is light, the overhead of copying lambdas and creating use/mutate variable lists becomes relatively high. We provide an API to create an `OprHandle` beforehand:

```c++
    virtual OprHandle NewOperator(AsyncFn fn,
                                  std::vector<VarHandle> const& const_vars,
                                  std::vector<VarHandle> const& mutate_vars) = 0;
```
You can keep pushing the `OprHandle` without repeatedly creating them:

```c++
    virtual void Push(OprHandle op, Context exec_ctx) = 0;
```
To delete it, call the `DeleteOperator(OprHandle op)` API. Ensure that the operator has finished computing before calling this API.


### API Reference

```eval_rst
    .. doxygenclass:: mxnet::Engine
       :members:
```

## Operators in MXNet

In MXNet, an operator is a class that contains both actual computation logic and auxiliary information that can aid the system in performing optimizations, like in-place updates and auto-derivatives. Before you continue with this document, we strongly recommend that you understand the `mshadow` library, because all operators compute on the tensor-like structure `mshadow::TBlob` provided by the system during runtime.

MXNet's operator interface allows you to:

* Save memory allocation cost by specifying in-place updates.
* Hide some internal arguments from Python to make it cleaner.
* Define the relationships among input tensors and output tensors, which allows the system to perform shape checking for you.
* Acquire additional temporary spaces from the system to perform computation (e.g., calling `cudnn` routines).

### Operator Interface

`Forward` is the core operator interface:

```c++
    virtual void Forward(const OpContext &ctx,
                         const std::vector<TBlob> &in_data,
                         const std::vector<OpReqType> &req,
                         const std::vector<TBlob> &out_data,
                         const std::vector<TBlob> &aux_states) = 0;
```
The `OpContext` structure is:

```c++
           struct OpContext {
             int is_train;
             RunContext run_ctx;
             std::vector<Resource> requested;
           }
```
It describes whether the operator is in the train or test phase, which device the operator should be run on (in `run_ctx`), and requested resources (covered in the following sections).


- `in_data` and `out_data` represent the input and output tensors, respectively. All of the tensor spaces have been allocated by the system.
- `req` denotes how the computation results are written into the `out_data`. In other words, `req.size() == out_data.size()` and `req[i]` correspond to the write type of `out_data[i]`.


- The `OpReqType` is defined as:

```c++
           enum OpReqType {
             kNullOp,
             kWriteTo,
             kWriteInplace,
             kAddTo
           };
```
  Normally, the types of all `out_data` should be `kWriteTo`, meaning that the provided `out_data` tensor is a *raw* memory block, so the operator should write results directly into it. In some cases, for example when calculating the `gradient` tensor, it would be great if we could accumulate the result, rather than directly overwrite the tensor contents so that  no extra space needs to be created each time. In such a case, the corresponding `req` type is set as `kAddTo`, indicating that a `+=` should be called.


- `aux_states` is intentionally designed for auxiliary tensors used to help computation. Currently, it is useless.

Aside from the `Forward` operator, you could optionally implement the `Backward` interface:

```c++
    virtual void Backward(const OpContext &ctx,
                          const std::vector<TBlob> &out_grad,
                          const std::vector<TBlob> &in_data,
                          const std::vector<TBlob> &out_data,
                          const std::vector<OpReqType> &req,
                          const std::vector<TBlob> &in_grad,
                          const std::vector<TBlob> &aux_states);
```
This interface follows the same design principle as the `Forward` interface, except that `out_grad`, `in_data`, and `out_data` are given, and the operator computes `in_grad` as the results. The naming strategy is similar to Torch's convention, and can be summarized in following figure:

[input/output semantics figure]

Some operators might not need all of the following: `out_grad`, `in_data` and `out_data`. Specified this with the `DeclareBackwardDependency` interface in `OperatorProperty`.

### Operator Property

One convolution might have several implementations, and you might want to switch among them to achieve the best performance. Therefore, we separate the operator *semantic* interfaces from the implementation interface (`Operator` class) into the `OperatorProperty` class. The `OperatorProperty` interface consists of:

* **InferShape:**

```c++
           virtual bool InferShape(std::vector<TShape> *in_shape,
                                   std::vector<TShape> *out_shape,
                                   std::vector<TShape> *aux_shape) const = 0;
```
  This interface has two purposes: 1. Tell the system the size of each input and output tensor, so it can allocate space for them before the `Forward` and `Backward` call; 2. Perform a size check to make sure that there isn't an obvious error before running. The shape in `in_shape` is set by the system (from the `out_shape` of the previous operators). It returns `false` when there is not enough information to infer shapes or throws an error when the shape is inconsistent.

* **Request Resources:** Operations like `cudnnConvolutionForward` need a work space for computation. If the system can manage that, it could then perform optimizations, like reuse the space, and so on. MXNet defines two interfaces to achieve this:

```c++
           virtual std::vector<ResourceRequest> ForwardResource(
               const std::vector<TShape> &in_shape) const;
           virtual std::vector<ResourceRequest> BackwardResource(
               const std::vector<TShape> &in_shape) const;
```
  The `ResourceRequest` structure (in `resource.h`) currently contains only a type flag:

```c++
           struct ResourceRequest {
             enum Type {
               kRandom,  // get a mshadow::Random<xpu> object
               kTempSpace,  // request temporary space
             };
             Type type;
           };
```
  If `ForwardResource` and `BackwardResource` return non-empty arrays, the system offers the corresponding resources through the `ctx` parameter in the `Forward` and `Backward` interface of `Operator`. Basically, to access those resources, simply write:

```c++
           auto tmp_space_res = ctx.requested[kTempSpace].get_space(some_shape, some_stream);
           auto rand_res = ctx.requested[kRandom].get_random(some_stream);
```
  For an example, see `src/operator/cudnn_convolution-inl.h`.

* **Backward dependency:** Let's look at two different operator signatures (we name all of the arguments for demonstration purposes):

```c++
           void FullyConnectedForward(TBlob weight, TBlob in_data, TBlob out_data);
           void FullyConnectedBackward(TBlob weight, TBlob in_data, TBlob out_grad, TBlob in_grad);

           void PoolingForward(TBlob in_data, TBlob out_data);
           void PoolingBackward(TBlob in_data, TBlob out_data, TBlob out_grad, TBlob in_grad);
```
  Note that `out_data` in `FullyConnectedForward` is not used by `FullyConnectedBackward`, while `PoolingBackward` requires all of the arguments of `PoolingForward`. Therefore, for `FullyConnectedForward`, the `out_data` tensor once consumed could be safely freed because the backward function will not need it. This provides a chance for the system to collect some tensors as garbage as soon as possible. To specify this situation, we provide an interface:

```c++
          virtual std::vector<int> DeclareBackwardDependency(
               const std::vector<int> &out_grad,
               const std::vector<int> &in_data,
               const std::vector<int> &out_data) const;
```
  The `int` element of the argument vector is an ID to distinguish different arrays. Let's see how this interface specifies different dependencies for `FullyConnected` and `Pooling`:

 ```c++
           std::vector<int> FullyConnectedProperty::DeclareBackwardDependency(
               const std::vector<int> &out_grad,
               const std::vector<int> &in_data,
               const std::vector<int> &out_data) const {
             return {out_grad[0], in_data[0]};  // NOTE: out_data[0] is NOT included
           }
           std::vector<int> PoolingProperty::DeclareBackwardDependency(
               const std::vector<int> &out_grad,
               const std::vector<int> &in_data,
               const std::vector<int> &out_data) const {
             return {out_grad[0], in_data[0], out_data[0]};
           }
```

* **In place Option:** To further save the cost of memory allocation, you can use in-place updates. They are appropriate for element-wise operations when the input tensor and output tensor have the same shape. You specify and in-place update with the following interface:

```c++
           virtual std::vector<std::pair<int, void*>>    ElewiseOpProperty::ForwardInplaceOption(
               const std::vector<int> &in_data,
               const std::vector<void*> &out_data) const {
             return { {in_data[0], out_data[0]} };
           }
           virtual std::vector<std::pair<int, void*>> ElewiseOpProperty::BackwardInplaceOption(
               const std::vector<int> &out_grad,
               const std::vector<int> &in_data,
               const std::vector<int> &out_data,
               const std::vector<void*> &in_grad) const {
             return { {out_grad[0], in_grad[0]} }
           }
```
  This tells the system that the `in_data[0]` and `out_data[0]` tensors could share the same memory spaces during `Forward`, and so do `out_grad[0]` and `in_grad[0]` during `Backward`.

  >**Important:** Even if you use the preceding specification, it's *not* guaranteed that the input and output tensors will share the same space. In fact, this is only a suggestion for the system, which makes the final decision. However, in either case, the decision is completely transparent to you, so the actual `Forward` and `Backward` implementation does not need to consider that.

* **Expose Operator to Python:** Because of the restrictions of C++, you need user to implement following interfaces:

```c++
           // initial the property class from a list of key-value string pairs
           virtual void Init(const vector<pair<string, string>> &kwargs) = 0;
           // return the parameters in a key-value string map
           virtual map<string, string> GetParams() const = 0;
           // return the name of arguments (for generating signature in python)
           virtual vector<string> ListArguments() const;
           // return the name of output values
           virtual vector<string> ListOutputs() const;
           // return the name of auxiliary states
           virtual vector<string> ListAuxiliaryStates() const;
           // return the number of output values
           virtual int NumOutputs() const;
           // return the number of visible outputs
           virtual int NumVisibleOutputs() const;
```

### Create an Operator from the Operator Property

 `OperatorProperty` includes all *semantic* attributes of an operation. It's also responsible for creating the `Operator` pointer for actual computation.

#### Create Operator
Implement the following interface in `OperatorProperty`:

```c++
    virtual Operator* CreateOperator(Context ctx) const = 0;
```
For example:

```c++
    class ConvolutionOp {
     public:
      void Forward( ... ) { ... }
      void Backward( ... ) { ... }
    };
    class ConvolutionOpProperty : public OperatorProperty {
     public:
      Operator* CreateOperator(Context ctx) const {
        return new ConvolutionOp;
      }
    };
```

#### Parametrize Operator
When implementing a convolution operator, you need to know the kernel size, the stride size, padding size, and so on. These parameters should be passed to the operator before any `Forward` or `Backward` interface is called. To do so, you could define a `ConvolutionParam` structure, as follows:

```c++
    #include <dmlc/parameter.h>
    struct ConvolutionParam : public dmlc::Parameter<ConvolutionParam> {
      TShape kernel, stride, pad;
      uint32_t num_filter, num_group, workspace;
      bool no_bias;
    };
```
Put it in `ConvolutionOpProperty`, and pass it to the operator class during construction:

```c++
    class ConvolutionOp {
     public:
      ConvolutionOp(ConvolutionParam p): param_(p) {}
      void Forward( ... ) { ... }
      void Backward( ... ) { ... }
     private:
      ConvolutionParam param_;
    };
    class ConvolutionOpProperty : public OperatorProperty {
     public:
      void Init(const vector<pair<string, string>& kwargs) {
        // initialize param_ using kwargs
      }
      Operator* CreateOperator(Context ctx) const {
        return new ConvolutionOp(param_);
      }
     private:
      ConvolutionParam param_;
    };
```

#### Register the Operator Property Class and the Parameter Class to MXNet
Use following macros to register the parameter structure and the operator property class to MXNet:

```c++
    DMLC_REGISTER_PARAMETER(ConvolutionParam);
    MXNET_REGISTER_OP_PROPERTY(Convolution, ConvolutionOpProperty);
```
The first argument is the name string, the second is the property class name.

### Interface Summary

We've almost covered the entire interface required to define a new operator. Let's do a recap:

* Use the `Operator` interface to write your computation logic (`Forward` and `Backward`).
* Use the `OperatorProperty` interface to:
  - Pass the parameter to the operator class (you can use the `Init` interface).
  - Create an operator using the `CreateOperator` interface.
  - Correctly implement the operator description interface, such as the names of arguments, etc.
  - Correctly implement the `InferShape` interface to set the output tensor shape.
  - [Optional] If additional resources are needed, check `ForwardResource` and `BackwardResource`.
  - [Optional] If `Backward` doesn't need all of the input and output of `Forward`, check `DeclareBackwardDependency`.
  - [Optional] If in-place update is supported, check `ForwardInplaceOption` and `BackwardInplaceOption`.
* Register the `OperatorProperty` class and the parameter class.

## Unifying the NDArray Operator and Symbolic Operator
NDArray operations are similar to symbolic operations, except that sometimes you
can't write in place to the operands without a complete dependency graph. However, the
logic underlying NDArray and symbolic operations are almost identical. *SimpleOp*, a new unified operator API, unifies different
invoking processes and returns to the fundamental elements of operators. Because most mathematical operators attend to one or two
operands, and more operands make dependency-related optimization useful, the unified operator
is specifically designed for unary and binary operations.

Consider the elements of an operation. Ideally, you need only functions and derivatives to  
describe an operation. Let's restrict that to the space of unary and binary operations. How
do we classify all operations to maximize the possibility of in-place write optimization? Note
that you can separate functions by the number of operands. Derivatives are a bit more
complex. To construct a dependency graph, you need to know whether output value, input data, or neither are needed alongside head gradient. Gradient functions in the unified API are  
differentiated by the types of operands it takes for calculation.

Before you learn more about the SimpleOp interface, we recommend that you review the [mshadow
library guide](https://github.com/dmlc/mshadow/tree/master/guide) because  calculations
will be done in the `mshadow::TBlob` structure.

In the following example, we'll create an operator functioning as a smooth l1 loss, which is a mixture
of l1 loss and l2 loss. The loss itself can be written as:

```
    loss = outside_weight .* f(inside_weight .* (data - label))
    grad = outside_weight .* inside_weight .* f'(inside_weight .* (data -    label))
```
 `.*` stands for element-wise multiplication, and `f`, `f'` is the smooth l1 loss function,
which we are assuming is in `mshadow` for now. At first glance, it's impossible to implement
this particular loss as a unary or binary operator. But we have automatic differentiation in symbolic execution. That simplifies the loss to `f` and `f'` directly. This
loss is no more complex than a `sin` or an `abs` function, and can certainly be implemented as a
unary operator.

## SimpleOp: The Unified Operator API
### Define Shapes
The `mshadow` library requires explicit memory allocation. As a consequence, all data shapes
must be provided before any calculation occurs. Before we proceed with defining functions and gradient,
let's check input data shape consistency and provide output shape.

```cpp
    typedef TShape (*UnaryShapeFunction)(const TShape& src,
                                         const EnvArguments& env);
    typedef TShape (*BinaryShapeFunction)(const TShape&                                         const TShape& rhs,lhs,

                                          const EnvArguments& env);
```
You can use `mshadow::TShape` to check input data shape and designate output data shape.
If you don't define this function, the default output shape is the same as the input shape.
In the case of a binary operator, the shape of `lhs` and `rhs` is checked as the same by default.

You can also use shape functions to check if any additional arguments and resources are present.
Refer to the additional usages of `EnvArguments` to accomplish this.

Before we start on our smooth l1 loss example, we define a `XPU` to `cpu` or `gpu` in the header
`smooth_l1_unary-inl.h` implementation so that we reuse the same code in `smooth_l1_unary.cc` and
`smooth_l1_unary.cu`.

```cpp
    #include <mxnet/operator_util.h>
    #if defined(__CUDACC__)
    #define XPU gpu
    #else
    #define XPU cpu
    #endif
```
In our smooth l1 loss example, it's okay to use the default behavior whereby the output has the same shape as the source.
Written explicitly, it is:

```cpp
    inline TShape SmoothL1Shape_(const TShape& src,
                                 const EnvArguments& env) {
      return TShape(src);
```

### Define Functions
Create a unary or binary function with one output: `mshadow::TBlob`.

```cpp
    typedef void (*UnaryFunction)(const TBlob& src,
                                  const EnvArguments& env,
                                  TBlob* ret,
                                  OpReqType req,
                                  RunContext ctx);
    typedef void (*BinaryFunction)(const TBlob& lhs,
                                   const TBlob& rhs,
                                   const EnvArguments& env,
                                   TBlob* ret,
                                   OpReqType req,
                                   RunContext ctx);
```
* Functions are differentiated by the types of input arguments.
* `RunContext ctx` contains information needed during runtime for execution.

```cpp
        struct RunContext {
          void *stream;  // the stream of the device, can be NULL or Stream<gpu>* in GPU mode
          template<typename xpu> inline mshadow::Stream<xpu>* get_stream() // get mshadow stream from Context
        }  // namespace mxnet
```
  `mshadow::stream<xpu> *s = ctx.get_stream<xpu>();` is an example of obtaining a stream from `ctx`.
* `OpReqType req` denotes how computation results are written into `ret`.

```cpp
        enum OpReqType {
          kNullOp,  // no operation, do not write anything
          kWriteTo,  // write gradient to provided space
          kWriteInplace,  // perform an in-place write
          kAddTo  // add to the provided space
        };
```
  A macro is defined in `operator_util.h` for a simplified use of `OpReqType`.
  `ASSIGN_DISPATCH(out, req, exp)` checks `req` and performs an assignment.

In our smooth l1 loss example, we use `UnaryFunction` to define the function of this operator.

```cpp
    template<typename xpu>
    void SmoothL1Forward_(const TBlob& src,
                          const EnvArguments& env,
                          TBlob *ret,
                          OpReqType req,
                          RunContext ctx) {
      using namespace mshadow;
      using namespace mshadow::expr;
      mshadow::Stream<xpu> *s = ctx.get_stream<xpu>();
      real_t sigma2 = env.scalar * env.scalar;
      MSHADOW_TYPE_SWITCH(ret->type_flag_, DType, {
        mshadow::Tensor<xpu, 2, DType> out = ret->get<xpu, 2, DType>(s);
        mshadow::Tensor<xpu, 2, DType> in = src.get<xpu, 2, DType>(s);
        ASSIGN_DISPATCH(out, req,
                        F<mshadow_op::smooth_l1_loss>(in, ScalarExp<DType>(sigma2)));
      });
    }
```
After obtaining `mshadow::Stream` from `RunContext`, we get `mshadow::Tensor` from `mshadow::TBlob`.
`mshadow::F` is a shortcut to initiate a `mshadow` expression. The macro `MSHADOW_TYPE_SWITCH(type, DType, ...)`
handles details on different types, and the macro `ASSIGN_DISPATCH(out, req, exp)` checks `OpReqType` and
performs actions accordingly. `sigma2` is a special parameter in this loss, which we will cover later.

### Define Gradients (Optional)
Create a gradient function with various types of inputs.

```cpp
    // depending only on out_grad
    typedef void (*UnaryGradFunctionT0)(const OutputGrad& out_grad,
                                        const EnvArguments& env,
                                        TBlob* in_grad,
                                        OpReqType req,
                                        RunContext ctx);
    // depending only on out_value
    typedef void (*UnaryGradFunctionT1)(const OutputGrad& out_grad,
                                        const OutputValue& out_value,
                                        const EnvArguments& env,
                                        TBlob* in_grad,
                                        OpReqType req,
                                         RunContext ctx);
    // depending only on in_data
    typedef void (*UnaryGradFunctionT2)(const OutputGrad& out_grad,
                                        const Input0& in_data0,
                                        const EnvArguments& env,
                                        TBlob* in_grad,
                                        OpReqType req,
                                        RunContext ctx);
```
Gradient functions of binary operators have similar structures, except that `Input`, `TBlob`, and `OpReqType`
are doubled.

`GradFunctionArgument`

  `Input0`, `Input`, `OutputValue`, and `OutputGrad` all share the structure of `GradFunctionArgument`,
  which is defined as:

  ```cpp
      struct GradFunctionArgument {
          TBlob data;
      }
  ```

In our smooth l1 loss example, note that it's an `f'(x)`, which utilizes input for the gradient calculation,
so the `UnaryGradFunctionT2` is suitable. To enable the chain rule of the gradient, we also need to multiply
`out_grad` from the top to the result of `in_grad`.

```cpp
    template<typename xpu>
    void SmoothL1BackwardUseIn_(const OutputGrad& out_grad,
                                const Input0& in_data0,
                                const EnvArguments& env,
                                TBlob *in_grad,
                                OpReqType req,
                                RunContext ctx) {
      using namespace mshadow;
      using namespace mshadow::expr;
      mshadow::Stream<xpu> *s = ctx.get_stream<xpu>();
      real_t sigma2 = env.scalar * env.scalar;
      MSHADOW_TYPE_SWITCH(in_grad->type_flag_, DType, {
        mshadow::Tensor<xpu, 2, DType> src = in_data0.data.get<xpu, 2, DType>(s);
        mshadow::Tensor<xpu, 2, DType> ograd = out_grad.data.get<xpu, 2, DType>(s);
        mshadow::Tensor<xpu, 2, DType> igrad = in_grad->get<xpu, 2, DType>(s);
         ASSIGN_DISPATCH(igrad, req,
                        ograd * F<mshadow_op::smooth_l1_gradient>(src, ScalarExp<DType>(sigma2)));
      });
    }
```

### Register SimpleOp to MXNet
After creating the shape, function, and gradient, restore them into both an NDArray operator and
a symbolic operator. To simplify this process, use the registration macro defined in `operator_util.h`.

```cpp
    MXNET_REGISTER_SIMPLE_OP(Name, DEV)
    .set_shape_function(Shape)
    .set_function(DEV::kDevMask, Function<XPU>, SimpleOpInplaceOption)
    .set_gradient(DEV::kDevMask, Gradient<XPU>, SimpleOpInplaceOption)
    .describe("description");
```
`SimpleOpInplaceOption` is defined as:

```cpp
    enum SimpleOpInplaceOption {
      kNoInplace,  // do not allow inplace in arguments
      kInplaceInOut,  // allow inplace in with out (unary)
      kInplaceOutIn,  // allow inplace out_grad with in_grad (unary)
      kInplaceLhsOut,  // allow inplace left operand with out (binary)
      kInplaceOutLhs  // allow inplace out_grad with lhs_grad (binary)
    };
```

In our example, we have a gradient function that relies on input data, so the function can't be written in
place. The output gradient has no purpose after gradient computation, so the gradient can be written in place.

```cpp
    MXNET_REGISTER_SIMPLE_OP(smooth_l1, XPU)
    .set_function(XPU::kDevMask, SmoothL1Forward_<XPU>, kNoInplace)
    .set_gradient(XPU::kDevMask, SmoothL1BackwardUseIn_<XPU>, kInplaceOutIn)
    .set_enable_scalar(true)
    .describe("Calculate Smooth L1 Loss(lhs, scalar)");
```
Remember from the discussion of shape functions that a default behavior without `set_shape_function` forces the inputs
(if they're binary) to be the same shape and yield the same shape for output. We'll discuss `set_enable_scalar` later.

### NDArray Operator Summary
* Create a shape function for determining the output shape.
* Create a function as the forward routine by choosing a suitable function type.
* Create a gradient as the backward routine by choosing a suitable gradient type.
* Register the operator using the registration process.

## Additional Information on SimpleOp
### Using SimpleOp on EnvArguments
Some operations might need a scalar as input, such as a  gradient scale, a set of keyword arguments
controlling behavior, or a temporary space to speed up calculations.`EnvArguments` provides additional arguments and resources to make calculations more scalable
and efficient.

```cpp
    struct EnvArguments {
      real_t scalar;  // scalar argument, if enabled
      std::vector<std::pair<std::string, std::string> > kwargs;  // keyword arguments
      std::vector<Resource> resource;  // pointer to the resources requested
    };
```

More registration parameters are required to enable these additional features. To prevent confusion on parameters, `scalar` and `kwargs`
can't be present at the same time. To enable `scalar`, use
`set_enable_scalar(bool enable_scalar)` in registration. Then, in forward functions and gradients, the `scalar` can be accessed from `env.scalar` as in the function parameter `EnvArguments env`.

To enable `kwargs`, use `set_enable_kwargs(bool enable_kwargs)` in registration. Then, in forward
functions and gradients, additional arguments are contained in `env.kwarg`, which is defined as
`std::vector<std::pair<std::string, std::string> >`. Use the DMLC parameter structure to
simplify parsing keyword arguments. For more details, see the [guide on parameter structure](https://github.com/dmlc/dmlc-core/blob/master/doc/parameter.md).

Additional resources like `mshadow::Random<xpu>` and temporary memory space can also be requested and
accessed from `EnvArguments.resource`. The registration routine is `set_resource_request(ResourceRequest req)`
or `set_resource_request(const std::vector<ResourceRequest>)`, where `mxnet::ResourceRequest` is defined as:

```cpp
    struct ResourceRequest {
      enum Type {  // Resource type, indicating what the pointer type is
        kRandom,  // mshadow::Random<xpu> object
        kTempSpace  // A dynamic temp space that can be arbitrary size
      };
      Type type;  // type of resources
    };
```
Registration will request the declared resource requests from `mxnet::ResourceManager`, and place resources
in `std::vector<Resource> resource` in `EnvArguments`. To access resources, use the following:

```cpp
    auto tmp_space_res = env.resources[0].get_space(some_shape, some_stream);
    auto rand_res = env.resources[0].get_random(some_stream);
```
For an example, see `src/operator/loss_binary_op-inl.h`.

In our smooth l1 loss example, a scalar input is needed to mark the turning point of a loss function. Therefore,
in the registration process, we use `set_enable_scalar(true)`, and use `env.scalar` in function and gradient
declarations.

### Crafting a Tensor Operation
Because computation utilizes the `mshadow` library and we sometimes don't have functions readily available, we 
can craft tensor operations in operator implementations. If you define such functions as element-wise, you
can implement them as a `mxnet::op::mshadow_op`. `src/operator/mshadow_op.h` that contains a lot of `mshadow_op`,
for example. `mshadow_op` are expression mappers. They deal with the scalar case of desired functions. For details, see
[mshadow expression API guide](https://github.com/dmlc/mshadow/tree/master/doc).

If an operation can't be done in an element-wise way, like the softmax loss and gradient, then you need to create a new tensor operation. You need to create as `mshadow` function and as `mshadow::cuda`
function directly. For details, see the `mshadow` library. For an example, see `src/operator/roi_pooling.cc`.

In our smooth l1 loss example, we create two mappers, namely the scalar cases of smooth l1 loss and gradient.

```cpp
    namespace mshadow_op {
    struct smooth_l1_loss {
      // a is x, b is sigma2
      MSHADOW_XINLINE static real_t Map(real_t a, real_t b) {
        if (a > 1.0f / b) {
          return a - 0.5f / b;
        } else if (a < -1.0f / b) {
          return -a - 0.5f / b;
        } else {
          return 0.5f * a * a * b;
        }
      }
    };
    }
```
The gradient, which can be found in `src/operator/smooth_l1_unary-inl.h`, is similar.

### Beyond Two Operands
The new unified API is designed to fulfill the fundamentals of an operation. For operators with more than two inputs,
more than one output, or that need more features, see the original [Operator API](http://mxnet.io/architecture/overview.html#operators-in-mxnet).

## KVStore: Multiple Devices and Multiple Computers

MXNet uses a two-level *parameter server* for data synchronization.

<img src=https://raw.githubusercontent.com/dmlc/web-data/master/mxnet/multi-node/ps_arch.png width=400/>

- On the first layer, data are synchronized over multiple devices within a
  single worker machine. A device could be a GPU card, CPU card, or other computational
  unit. We often use the sequential consistency model, also known as BSP, on this
  level.

- On the second layer, data are synchronized over multiple workers by way of servers. We can use either a sequential consistency model for guaranteed
  convergence or a (partial)-asynchronous model for better system performance.

### KVStore

MXNet implemented the two-level parameter server in class *KVStore*. We
currently provide the following three types. Given the batch size *b*.

```eval_rst
    ============  ======== ======== ============== ============== =========
    kvstore type  #devices #workers #ex per device #ex per update max delayN
    `dist_sync`   *k*       *n*       *b / k*       *b × n*       *0*
    `dist_async`  *k*       *n*       *b / k*       *b*           inf
    ============  ======== ======== ============== ============== =========
```

The number of devices *k* used on a worker could vary for different
workers.

- **Number examples per update**: For each update, the number of examples used to
  calculate the averaged gradients. Often, the larger, the slower the convergence.
- **Number examples per device**: The number of examples batched to one device
  each time. Often, the larger, the better the performance.
- **Max delay** : The maximum delay of the weight for a worker. Given a worker,
  a delay *d* for weight *w* means that when this worker uses *w* (to calculate the
  gradient), *w* has been already updated by *d* times  in some other places. A
  larger delay often improves the performance, but can slow
  convergence.

### Multiple Devices on a Single Computer

KV store `local` synchronizes data over multiple devices on a single computer.
It produces the same results (e.g., model accuracy) as when running a single device. But
compared to the latter, assume there are *k* devices, and that each device
processes only *1 / k* examples each time (and consumes *1 / k* of device memory). We
often increase the batch size *b* for better system performance.

When you use `local`, the system automatically chooses one of the following
three types. They differ on where to average
the gradients over all devices, and where to update the weight.

```eval_rst
    =======================  ================   ==============
     kvstore type            average gradient   perform update
    =======================  ================   ==============
    `local_update_cpu`       CPU                 CPU
    `local_allreduce_cpu`    CPU                 all devices
    `local_allreduce_device` a device            all devices
    =======================  ================   ==============
```

They produce (almost) the same results, but can vary on speed.

- `local_update_cpu`, gradients are first copied to main memory, averaged on the CPU,
  and then they update the weight on the CPU. This is suitable when the average size of
  weights isn't large and there are a large number of weights. Example: the
  Google Inception network.

- `local_allreduce_cpu` is similar to `local_update_cpu`, except that the
  averaged gradients are copied back to the devices, and then weights are
  updated on devices. When weight size is large, it's faster than the first option; you
  can use the device to accelerate computation (but you increase the workload
  by *k* times). Example: AlexNet on ImageNet.

- `local_allreduce_device` is similar to `local_allreduce_cpu` except that the
  gradients are averaged on a chosen device. It might take advantage of device-to-device communication, and might accelerate averaging. When the gradients are huge, it's faster than the second option, but it requires more
  device memory.

### Multiple Computers

Both `dist_async` and `dist_sync` can handle using  multiple computers. But they differ in both semantics and performance.

- `dist_sync`: The gradients are first averaged on the servers, and then sent back to workers for updating weight. If you treat a computer as a device, it's similar to `local` and
  `update_on_kvstore=false`.  If you reduce the batch size to *b / n*, it guarantees
  almost identical convergence as the single computer, single device scenario. However, it requires synchronization
  between all workers, and, therefore, might affect system performance.

- `dist_async`: The gradient is sent to the servers, and the weight is updated
  there. The weights that a worker has might be stale. This loose data consistency
  model reduces computer synchronization cost and, therefore, could improve
  system performance. However, it might affect convergence speed.

## Next Steps

* [Analogy to other DL systems](http://mxnet.io/architecture/analogy.html)
* [How to read MXNet code](http://mxnet.io/architecture/read_code.html)
* [Develop and hack MXNet](http://mxnet.io/how_to/develop_and_hack.html)
