text: /*!
   * Copyright 2014 by Contributors
   * \file metric.h
   * \brief interface of evaluation metric function supported in xgboost.
   * \author Tianqi Chen, Kailong Chen
   */
  #ifndef XGBOOST_METRIC_H_
  #define XGBOOST_METRIC_H_
  
  #include <vector>
  #include <string>
  #include <functional>
  #include <utility>
  
  #include <dmlc/registry.h>
  #include <xgboost/model.h>
  #include <xgboost/generic_parameters.h>
  #include <xgboost/data.h>
  #include <xgboost/base.h>
  #include <xgboost/host_device_vector.h>
  
  namespace xgboost {
  /*!
   * \brief interface of evaluation metric used to evaluate model performance.
   *  This has nothing to do with training, but merely act as evaluation purpose.
   */
  class Metric : public Configurable {
   protected:
    GenericParameter const* tparam_;
  
   public:
    /*!
     * \brief Configure the Metric with the specified parameters.
     * \param args arguments to the objective function.
     */
    virtual void Configure(
        const std::vector<std::pair<std::string, std::string> >& args) {}
    /*!
     * \brief Load configuration from JSON object
     * By default, metric has no internal configuration;
     * override this function to maintain internal configuration
     * \param in JSON object containing the configuration
     */
    void LoadConfig(Json const& in) override {}
    /*!
     * \brief Save configuration to JSON object
     * By default, metric has no internal configuration;
     * override this function to maintain internal configuration
     * \param out pointer to output JSON object
     */
    void SaveConfig(Json* out) const override {}
  
    /*!
     * \brief evaluate a specific metric
     * \param preds prediction
     * \param info information, including label etc.
     * \param distributed whether a call to Allreduce is needed to gather
     *        the average statistics across all the node,
     *        this is only supported by some metrics
     */
    virtual bst_float Eval(const HostDeviceVector<bst_float>& preds,
                           const MetaInfo& info,
                           bool distributed) = 0;
    /*! \return name of metric */
    virtual const char* Name() const = 0;
    /*! \brief virtual destructor */
    ~Metric() override = default;
    /*!
     * \brief create a metric according to name.
     * \param name name of the metric.
     *        name can be in form metric[@]param and the name will be matched in the
     *        registry.
     * \param tparam A global generic parameter
     * \return the created metric.
     */
    static Metric* Create(const std::string& name, GenericParameter const* tparam);
  };
  
  /*!
   * \brief Registry entry for Metric factory functions.
   *  The additional parameter const char* param gives the value after @, can be null.
   *  For example, metric map@3, then: param == "3".
   */
  struct MetricReg
      : public dmlc::FunctionRegEntryBase<MetricReg,
                                          std::function<Metric* (const char*)> > {
  };
  
  /*!
   * \brief Macro to register metric.
   *
   * \code
   * // example of registering a objective ndcg@k
   * XGBOOST_REGISTER_METRIC(RMSE, "ndcg")
   * .describe("Rooted mean square error.")
   * .set_body([](const char* param) {
   *     int at_k = atoi(param);
   *     return new NDCG(at_k);
   *   });
   * \endcode
   */
  #define XGBOOST_REGISTER_METRIC(UniqueId, Name)                         \
    ::xgboost::MetricReg&  __make_ ## MetricReg ## _ ## UniqueId ## __ =  \
        ::dmlc::Registry< ::xgboost::MetricReg>::Get()->__REGISTER__(Name)
  }  // namespace xgboost
  #endif  // XGBOOST_METRIC_H_
  