/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/*!
 * \file ndarray.h
 * \brief definition of ndarray
 * \author Chuntao Hong, Zhang Chen
 */

#ifndef MXNET_CPP_NDARRAY_H_
#define MXNET_CPP_NDARRAY_H_

#include <map>
#include <memory>
#include <string>
#include <vector>
#include <iostream>
#include "mxnet-cpp/base.h"
#include "mxnet-cpp/shape.h"

namespace mxnet {
namespace cpp {

enum DeviceType { kCPU = 1, kGPU = 2, kCPUPinned = 3 };

/*!
 * \brief Context interface
 */
class Context {
 public:
  /*!
   * \brief Context constructor
   * \param type type of the device
   * \param id id of the device
   */
  Context(const DeviceType& type, int id) : type_(type), id_(id) {}
  /*!
   * \return the type of the device
   */
  DeviceType GetDeviceType() const {
    return type_;
  }
  /*!
   * \return the id of the device
   */
  int GetDeviceId() const {
    return id_;
  }

  /*!
   * \brief Return a GPU context
   * \param device_id id of the device
   * \return the corresponding GPU context
   */
  static Context gpu(int device_id = 0) {
    return Context(DeviceType::kGPU, device_id);
  }

  /*!
   * \brief Return a CPU context
   * \param device_id id of the device. this is not needed by CPU
   * \return the corresponding CPU context
   */
  static Context cpu(int device_id = 0) {
    return Context(DeviceType::kCPU, device_id);
  }

 private:
  DeviceType type_;
  int id_;
};

/*!
 * \brief struct to store NDArrayHandle
 */
struct NDBlob {
 public:
  /*!
   * \brief default constructor
   */
  NDBlob() : handle_(nullptr) {}
  /*!
   * \brief construct with a NDArrayHandle
   * \param handle NDArrayHandle to store
   */
  explicit NDBlob(NDArrayHandle handle) : handle_(handle) {}
  /*!
   * \brief destructor, free the NDArrayHandle
   */
  ~NDBlob() {
    MXNDArrayFree(handle_);
  }
  /*!
   * \brief the NDArrayHandle
   */
  NDArrayHandle handle_;

 private:
  NDBlob(const NDBlob&);
  NDBlob& operator=(const NDBlob&);
};

/*!
 * \brief NDArray interface
 */
class NDArray {
 public:
  /*!
   * \brief construct with a none handle
   */
  NDArray();
  /*!
   * \brief construct with a NDArrayHandle
   */
  explicit NDArray(const NDArrayHandle& handle);
  /*!
   * \brief construct a new dynamic NDArray
   * \param shape the shape of array
   * \param context context of NDArray
   * \param delay_alloc whether delay the allocation
   * \param dtype data type of NDArray
   */
  NDArray(const std::vector<mx_uint>& shape,
          const Context& context,
          bool delay_alloc = true,
          int dtype        = 0);
  /*!
   * \brief construct a new dynamic NDArray
   * \param shape the shape of array
   * \param constext context of NDArray
   * \param delay_alloc whether delay the allocation
   * \param dtype data type of NDArray
   */
  NDArray(const Shape& shape, const Context& context, bool delay_alloc = true, int dtype = 0);
  NDArray(const mx_float* data, size_t size);
  /*!
   * \brief construct a new dynamic NDArray
   * \param data the data to create NDArray from
   * \param shape the shape of array
   * \param constext context of NDArray
   */
  NDArray(const mx_float* data, const Shape& shape, const Context& context);
  /*!
   * \brief construct a new dynamic NDArray
   * \param data the data to create NDArray from
   * \param shape the shape of array
   * \param constext context of NDArray
   */
  NDArray(const std::vector<mx_float>& data, const Shape& shape, const Context& context);
  explicit NDArray(const std::vector<mx_float>& data);
  NDArray operator+(mx_float scalar);
  NDArray operator-(mx_float scalar);
  NDArray operator*(mx_float scalar);
  NDArray operator/(mx_float scalar);
  NDArray operator%(mx_float scalar);
  NDArray operator+(const NDArray&);
  NDArray operator-(const NDArray&);
  NDArray operator*(const NDArray&);
  NDArray operator/(const NDArray&);
  NDArray operator%(const NDArray&);
  /*!
   * \brief set all the elements in ndarray to be scalar
   * \param scalar the scalar to set
   * \return reference of self
   */
  NDArray& operator=(mx_float scalar);
  /*!
   * \brief elementwise add to current space
   *  this mutate the current NDArray
   * \param scalar the data to add
   * \return reference of self
   */
  NDArray& operator+=(mx_float scalar);
  /*!
   * \brief elementwise subtract from current ndarray
   * this mutate the current NDArray
   * \param scalar the data to subtract
   * \return reference of self
   */
  NDArray& operator-=(mx_float scalar);
  /*!
   * \brief elementwise multiplication to current ndarray
   *  this mutate the current NDArray
   * \param scalar the data to subtract
   * \return reference of self
   */
  NDArray& operator*=(mx_float scalar);
  /*!
   * \brief elementwise division from current ndarray
   *  this mutate the current NDArray
   * \param scalar the data to subtract
   * \return reference of self
   */
  NDArray& operator/=(mx_float scalar);
  /*!
   * \brief elementwise modulo from current ndarray
   *  this mutate the current NDArray
   * \param scalar the data to subtract
   * \return reference of self
   */
  NDArray& operator%=(mx_float scalar);
  /*!
   * \brief elementwise add to current space
   *  this mutate the current NDArray
   * \param src the data to add
   * \return reference of self
   */
  NDArray& operator+=(const NDArray& src);
  /*!
   * \brief elementwise subtract from current ndarray
   * this mutate the current NDArray
   * \param src the data to subtract
   * \return reference of self
   */
  NDArray& operator-=(const NDArray& src);
  /*!
   * \brief elementwise multiplication to current ndarray
   *  this mutate the current NDArray
   * \param src the data to subtract
   * \return reference of self
   */
  NDArray& operator*=(const NDArray& src);
  /*!
   * \brief elementwise division from current ndarray
   *  this mutate the current NDArray
   * \param src the data to subtract
   * \return reference of self
   */
  NDArray& operator/=(const NDArray& src);
  /*!
   * \brief elementwise modulo from current ndarray
   *  this mutate the current NDArray
   * \param src the data to subtract
   * \return reference of self
   */
  NDArray& operator%=(const NDArray& src);
  NDArray ArgmaxChannel();
  /*!
   * \brief Do a synchronize copy from a contiguous CPU memory region.
   *
   *  This function will call WaitToWrite before the copy is performed.
   *  This is useful to copy data from existing memory region that are
   *  not wrapped by NDArray(thus dependency not being tracked).
   *
   * \param data the data source to copy from.
   * \param size the memory size we want to copy from.
   */
  void SyncCopyFromCPU(const mx_float* data, size_t size);
  /*!
   * \brief Do a synchronize copy from a contiguous CPU memory region.
   *
   *  This function will call WaitToWrite before the copy is performed.
   *  This is useful to copy data from existing memory region that are
   *  not wrapped by NDArray(thus dependency not being tracked).
   *
   * \param data the data source to copy from, int the form of mx_float vector
   */
  void SyncCopyFromCPU(const std::vector<mx_float>& data);
  /*!
   * \brief Do a synchronize copy to a contiguous CPU memory region.
   *
   *  This function will call WaitToRead before the copy is performed.
   *  This is useful to copy data from existing memory region that are
   *  not wrapped by NDArray(thus dependency not being tracked).
   *
   * \param data the data source to copyinto.
   * \param size the memory size we want to copy into. Defualt value is Size()
   */
  void SyncCopyToCPU(mx_float* data, size_t size = 0);
  /*!
   * \brief Do a synchronize copy to a contiguous CPU memory region.
   *
   *  This function will call WaitToRead before the copy is performed.
   *  This is useful to copy data from existing memory region that are
   *  not wrapped by NDArray(thus dependency not being tracked).
   *
   * \param data the data source to copyinto.
   * \param size the memory size we want to copy into. Defualt value is Size()
   */
  void SyncCopyToCPU(std::vector<mx_float>* data, size_t size = 0);
  /*!
   * \brief copy the content of current array to a target array.
   * \param other the target NDArray
   * \return the target NDarray
   */
  NDArray CopyTo(NDArray* other) const;
  /*!
   * \brief return a new copy to this NDArray
   * \param Context the new context of this NDArray
   * \return the new copy
   */
  NDArray Copy(const Context&) const;
  /*!
   * \brief return offset of the element at (h, w)
   * \param h height position
   * \param w width position
   * \return offset of two dimensions array
   */
  size_t Offset(size_t h = 0, size_t w = 0) const;
  /*!
   * \brief return offset of three dimensions array
   * \param c channel position
   * \param h height position
   * \param w width position
   * \return offset of three dimensions array
   */
  size_t Offset(size_t c, size_t h, size_t w) const;
  /*!
   * \brief return value of the element at (index)
   * \param index  position
   * \return value of one dimensions array
   */
  mx_float At(size_t index) const;
  /*!
   * \brief return value of the element at (h, w)
   * \param h height position
   * \param w width position
   * \return value of two dimensions array
   */
  mx_float At(size_t h, size_t w) const;
  /*!
   * \brief return value of three dimensions array
   * \param c channel position
   * \param h height position
   * \param w width position
   * \return value of three dimensions array
   */
  mx_float At(size_t c, size_t h, size_t w) const;
  /*!
   * \brief Slice a NDArray
   * \param begin begin index in first dim
   * \param end end index in first dim
   * \return sliced NDArray
   */
  NDArray Slice(mx_uint begin, mx_uint end) const;
  /*!
   * \brief Return a reshaped NDArray that shares memory with current one
   * \param new_shape the new shape
   * \return reshaped NDarray
   */
  NDArray Reshape(const Shape& new_shape) const;
  /*!
   * \brief Block until all the pending write operations with respect
   *    to current NDArray are finished, and read can be performed.
   */
  void WaitToRead() const;
  /*!
   * \brief Block until all the pending read/write operations with respect
   *    to current NDArray are finished, and write can be performed.
   */
  void WaitToWrite();
  /*!
   * \brief Block until all the pending read/write operations with respect
   *    to current NDArray are finished, and read/write can be performed.
   */
  static void WaitAll();
  /*!
   * \brief Sample gaussian distribution for each elements of out.
   * \param mu mean of gaussian distribution.
   * \param sigma standard deviation of gaussian distribution.
   * \param out output NDArray.
   */
  static void SampleGaussian(mx_float mu, mx_float sigma, NDArray* out);
  /*!
   * \brief Sample uniform distribution for each elements of out.
   * \param begin lower bound of distribution.
   * \param end upper bound of distribution.
   * \param out output NDArray.
   */
  static void SampleUniform(mx_float begin, mx_float end, NDArray* out);
  /*!
   * \brief Load NDArrays from binary file.
   * \param file_name name of the binary file.
   * \param array_list a list of NDArrays returned, do not fill the list if
   * nullptr is given.
   * \param array_map a map from names to NDArrays returned, do not fill the map
   * if nullptr is given or no names is stored in binary file.
   */
  static void Load(const std::string& file_name,
                   std::vector<NDArray>* array_list          = nullptr,
                   std::map<std::string, NDArray>* array_map = nullptr);
  /*!
   * \brief Load map of NDArrays from binary file.
   * \param file_name name of the binary file.
   * \return a list of NDArrays.
   */
  static std::map<std::string, NDArray> LoadToMap(const std::string& file_name);
  /*!
   * \brief Load list of NDArrays from binary file.
   * \param file_name name of the binary file.
   * \return a map from names to NDArrays.
   */
  static std::vector<NDArray> LoadToList(const std::string& file_name);
  /*!
   * \brief Load NDArrays from buffer.
   * \param buffer Pointer to buffer. (ie contents of param file)
   * \param size Size of buffer
   * \param array_list a list of NDArrays returned, do not fill the list if
   * nullptr is given.
   * \param array_map a map from names to NDArrays returned, do not fill the map
   * if nullptr is given or no names is stored in binary file.
   */
  static void LoadFromBuffer(const void* buffer,
                             size_t size,
                             std::vector<NDArray>* array_list          = nullptr,
                             std::map<std::string, NDArray>* array_map = nullptr);
  /*!
   * \brief Load map of NDArrays from buffer.
   * \param buffer Pointer to buffer. (ie contents of param file)
   * \param size Size of buffer
   * \return a list of NDArrays.
   */
  static std::map<std::string, NDArray> LoadFromBufferToMap(const void* buffer, size_t size);
  /*!
   * \brief Load list of NDArrays from buffer.
   * \param buffer Pointer to buffer. (ie contents of param file)
   * \param size Size of buffer
   * \return a map from names to NDArrays.
   */
  static std::vector<NDArray> LoadFromBufferToList(const void* buffer, size_t size);
  /*!
   * \brief save a map of string->NDArray to binary file.
   * \param file_name name of the binary file.
   * \param array_map a map from names to NDArrays.
   */
  static void Save(const std::string& file_name, const std::map<std::string, NDArray>& array_map);
  /*!
   * \brief save a list of NDArrays to binary file.
   * \param file_name name of the binary file.
   * \param array_list a list of NDArrays.
   */
  static void Save(const std::string& file_name, const std::vector<NDArray>& array_list);
  /*!
   * \return the size of current NDArray, a.k.a. the production of all shape dims
   */
  size_t Size() const;
  /*!
   * \return the shape of current NDArray, in the form of mx_uint vector
   */
  std::vector<mx_uint> GetShape() const;
  /*!
   * \return the data type of current NDArray
   */
  int GetDType() const;
  /*!
   * \brief Get the pointer to data (IMPORTANT: The ndarray should not be in GPU)
   * \return the data pointer to the current NDArray
   */
  const mx_float* GetData() const;

  /*!
   * \return the context of NDArray
   */
  Context GetContext() const;

  /*!
   * \return the NDArrayHandle of the current NDArray
   */
  NDArrayHandle GetHandle() const {
    return blob_ptr_->handle_;
  }

 private:
  std::shared_ptr<NDBlob> blob_ptr_;
};

std::ostream& operator<<(std::ostream& out, const NDArray& ndarray);
}  // namespace cpp
}  // namespace mxnet

#endif  // MXNET_CPP_NDARRAY_H_
