@@ -180,7 +180,7 @@ void signalHandler(int sig) {
     case SIGTERM:
       FLOG_INFO("Signal %d(%s) received, stopping this server", sig, ::strsignal(sig));
       if (gStorageServer) {
-        gStorageServer->stop();
+        gStorageServer->notifyStop();
       }
       break;
     default:

/* Copyright (c) 2018 vesoft inc. All rights reserved.
 *
 * This source code is licensed under Apache 2.0 License.
 */

#include <folly/ssl/Init.h>
#include <thrift/lib/cpp2/server/ThriftServer.h>

#include "common/base/Base.h"
#include "common/base/SignalHandler.h"
#include "common/network/NetworkUtils.h"
#include "common/process/ProcessUtils.h"
#include "common/time/TimezoneInfo.h"
#include "storage/StorageServer.h"
#include "version/Version.h"

DEFINE_string(local_ip, "", "IP address which is used to identify this server");
DEFINE_string(data_path,
              "",
              "Root data path, multi paths should be split by comma."
              "For rocksdb engine, one path one instance.");
DEFINE_string(wal_path,
              "",
              "Nebula wal path. By default, wal will be stored as a sibling of "
              "rocksdb data.");
DEFINE_string(listener_path,
              "",
              "Path for listener, only wal will be saved."
              "if it is not empty, data_path will not take effect.");
DEFINE_bool(daemonize, true, "Whether to run the process as a daemon");
DEFINE_string(pid_file, "pids/nebula-storaged.pid", "File to hold the process id");
DEFINE_string(meta_server_addrs,
              "",
              "list of meta server addresses,"
              "the format looks like ip1:port1, ip2:port2, ip3:port3");
DECLARE_int32(port);

using nebula::operator<<;
using nebula::HostAddr;
using nebula::ProcessUtils;
using nebula::Status;
using nebula::StatusOr;
using nebula::network::NetworkUtils;

static void signalHandler(int sig);
static Status setupSignalHandler();
extern Status setupLogging();
#if defined(__x86_64__)
extern Status setupBreakpad();
#endif

std::unique_ptr<nebula::storage::StorageServer> gStorageServer;

int main(int argc, char *argv[]) {
  google::SetVersionString(nebula::versionString());
  // Detect if the server has already been started
  // Check pid before glog init, in case of user may start daemon twice
  // the 2nd will make the 1st failed to output log anymore
  gflags::ParseCommandLineFlags(&argc, &argv, false);

  // Setup logging
  auto status = setupLogging();
  if (!status.ok()) {
    LOG(ERROR) << status;
    return EXIT_FAILURE;
  }

#if defined(__x86_64__)
  status = setupBreakpad();
  if (!status.ok()) {
    LOG(ERROR) << status;
    return EXIT_FAILURE;
  }
#endif

  auto pidPath = FLAGS_pid_file;
  status = ProcessUtils::isPidAvailable(pidPath);
  if (!status.ok()) {
    LOG(ERROR) << status;
    return EXIT_FAILURE;
  }

  folly::init(&argc, &argv, true);
  if (FLAGS_enable_ssl || FLAGS_enable_meta_ssl) {
    folly::ssl::init();
  }
  if (FLAGS_daemonize) {
    google::SetStderrLogging(google::FATAL);
  } else {
    google::SetStderrLogging(google::INFO);
  }

  if (FLAGS_daemonize) {
    status = ProcessUtils::daemonize(pidPath);
    if (!status.ok()) {
      LOG(ERROR) << status;
      return EXIT_FAILURE;
    }
  } else {
    // Write the current pid into the pid file
    status = ProcessUtils::makePidFile(pidPath);
    if (!status.ok()) {
      LOG(ERROR) << status;
      return EXIT_FAILURE;
    }
  }

  if (FLAGS_data_path.empty()) {
    LOG(ERROR) << "Storage Data Path should not empty";
    return EXIT_FAILURE;
  }

  std::string hostName;
  if (FLAGS_local_ip.empty()) {
    hostName = nebula::network::NetworkUtils::getHostname();
  } else {
    status = NetworkUtils::validateHostOrIp(FLAGS_local_ip);
    if (!status.ok()) {
      LOG(ERROR) << status;
      return EXIT_FAILURE;
    }
    hostName = FLAGS_local_ip;
  }
  nebula::HostAddr localhost{hostName, FLAGS_port};
  LOG(INFO) << "localhost = " << localhost;
  auto metaAddrsRet = nebula::network::NetworkUtils::toHosts(FLAGS_meta_server_addrs);
  if (!metaAddrsRet.ok() || metaAddrsRet.value().empty()) {
    LOG(ERROR) << "Can't get metaServer address, status:" << metaAddrsRet.status()
               << ", FLAGS_meta_server_addrs:" << FLAGS_meta_server_addrs;
    return EXIT_FAILURE;
  }

  std::vector<std::string> paths;
  folly::split(",", FLAGS_data_path, paths, true);
  std::transform(paths.begin(), paths.end(), paths.begin(), [](auto &p) {
    return folly::trimWhitespace(p).str();
  });
  if (paths.empty()) {
    LOG(ERROR) << "Bad data_path format:" << FLAGS_data_path;
    return EXIT_FAILURE;
  }

  // Setup the signal handlers
  status = setupSignalHandler();
  if (!status.ok()) {
    LOG(ERROR) << status;
    return EXIT_FAILURE;
  }

  // Initialize the global timezone, it's only used for datetime type compute
  // won't affect the process timezone.
  status = nebula::time::Timezone::initializeGlobalTimezone();
  if (!status.ok()) {
    LOG(ERROR) << status;
    return EXIT_FAILURE;
  }

  gStorageServer = std::make_unique<nebula::storage::StorageServer>(
      localhost, metaAddrsRet.value(), paths, FLAGS_wal_path, FLAGS_listener_path);
  if (!gStorageServer->start()) {
    LOG(ERROR) << "Storage server start failed";
    gStorageServer->stop();
    return EXIT_FAILURE;
  }

  gStorageServer->waitUntilStop();
  LOG(INFO) << "The storage Daemon stopped";
  return EXIT_SUCCESS;
}

Status setupSignalHandler() {
  return nebula::SignalHandler::install(
      {SIGINT, SIGTERM},
      [](nebula::SignalHandler::GeneralSignalInfo *info) { signalHandler(info->sig()); });
}

void signalHandler(int sig) {
  switch (sig) {
    case SIGINT:
    case SIGTERM:
      FLOG_INFO("Signal %d(%s) received, stopping this server", sig, ::strsignal(sig));
      if (gStorageServer) {
        gStorageServer->stop();
      }
      break;
    default:
      FLOG_ERROR("Signal %d(%s) received but ignored", sig, ::strsignal(sig));
  }
}

This fix looks good. My concern, don't forget to fix metad too!


@@ -30,7 +30,10 @@ double getAlignmentTransform(const ROMol &prbMol, const ROMol &refMol,
   if (atomMap == 0) {
     // we have to figure out the mapping between the two molecule
     MatchVectType match;
-    if (SubstructMatch(refMol, prbMol, match)) {
+    const bool recursionPossible = true;
+    const bool useChirality = false;
+    const bool useQueryQueryMatches = true;
+    if (SubstructMatch(refMol, prbMol, match, recursionPossible, useChirality, useQueryQueryMatches)) {
       MatchVectType::const_iterator mi;
       for (mi = match.begin(); mi != match.end(); mi++) {
         prbPoints.push_back(&prbCnf.getAtomPos(mi->first));

// $Id$
//
//  Copyright (C) 2001-2008 Greg Landrum and Rational Discovery LLC
//
//   @@ All Rights Reserved @@
//  This file is part of the RDKit.
//  The contents are covered by the terms of the BSD license
//  which is included in the file license.txt, found at the root
//  of the RDKit source tree.
//
#include "AlignMolecules.h"
#include <Geometry/Transform3D.h>
#include <Numerics/Vector.h>
#include <GraphMol/Substruct/SubstructMatch.h>
#include <GraphMol/Conformer.h>
#include <GraphMol/ROMol.h>
#include <Numerics/Alignment/AlignPoints.h>
#include <GraphMol/MolTransforms/MolTransforms.h>

namespace RDKit {
namespace MolAlign {
double getAlignmentTransform(const ROMol &prbMol, const ROMol &refMol,
                             RDGeom::Transform3D &trans, int prbCid, int refCid,
                             const MatchVectType *atomMap,
                             const RDNumeric::DoubleVector *weights,
                             bool reflect, unsigned int maxIterations) {
  RDGeom::Point3DConstPtrVect refPoints, prbPoints;
  const Conformer &prbCnf = prbMol.getConformer(prbCid);
  const Conformer &refCnf = refMol.getConformer(refCid);
  if (atomMap == 0) {
    // we have to figure out the mapping between the two molecule
    MatchVectType match;
    if (SubstructMatch(refMol, prbMol, match)) {
      MatchVectType::const_iterator mi;
      for (mi = match.begin(); mi != match.end(); mi++) {
        prbPoints.push_back(&prbCnf.getAtomPos(mi->first));
        refPoints.push_back(&refCnf.getAtomPos(mi->second));
      }
    } else {
      throw MolAlignException(
          "No sub-structure match found between the probe and query mol");
    }
  } else {
    MatchVectType::const_iterator mi;
    for (mi = atomMap->begin(); mi != atomMap->end(); mi++) {
      prbPoints.push_back(&prbCnf.getAtomPos(mi->first));
      refPoints.push_back(&refCnf.getAtomPos(mi->second));
    }
  }
  double ssr = RDNumeric::Alignments::AlignPoints(
      refPoints, prbPoints, trans, weights, reflect, maxIterations);
  ssr /= (prbPoints.size());
  return sqrt(ssr);
}

double alignMol(ROMol &prbMol, const ROMol &refMol, int prbCid, int refCid,
                const MatchVectType *atomMap,
                const RDNumeric::DoubleVector *weights, bool reflect,
                unsigned int maxIterations) {
  RDGeom::Transform3D trans;
  double res = getAlignmentTransform(prbMol, refMol, trans, prbCid, refCid,
                                     atomMap, weights, reflect, maxIterations);
  // now transform the relevant conformation on prbMol
  Conformer &conf = prbMol.getConformer(prbCid);
  MolTransforms::transformConformer(conf, trans);
  return res;
}

void _fillAtomPositions(RDGeom::Point3DConstPtrVect &pts, const Conformer &conf,
                        const std::vector<unsigned int> *atomIds = 0) {
  unsigned int na = conf.getNumAtoms();
  pts.clear();
  if (atomIds == 0) {
    unsigned int ai;
    pts.reserve(na);
    for (ai = 0; ai < na; ++ai) {
      pts.push_back(&conf.getAtomPos(ai));
    }
  } else {
    pts.reserve(atomIds->size());
    std::vector<unsigned int>::const_iterator cai;
    for (cai = atomIds->begin(); cai != atomIds->end(); cai++) {
      pts.push_back(&conf.getAtomPos(*cai));
    }
  }
}

void alignMolConformers(ROMol &mol, const std::vector<unsigned int> *atomIds,
                        const std::vector<unsigned int> *confIds,
                        const RDNumeric::DoubleVector *weights, bool reflect,
                        unsigned int maxIters, std::vector<double> *RMSlist) {
  if (mol.getNumConformers() == 0) {
    // nothing to be done ;
    return;
  }

  RDGeom::Point3DConstPtrVect refPoints, prbPoints;
  int cid = -1;
  if ((confIds != 0) && (confIds->size() > 0)) {
    cid = confIds->front();
  }
  const Conformer &refCnf = mol.getConformer(cid);
  _fillAtomPositions(refPoints, refCnf, atomIds);

  // now loop throught the remaininf conformations and transform them
  RDGeom::Transform3D trans;
  double ssd;
  if (confIds == 0) {
    unsigned int i = 0;
    ROMol::ConformerIterator cnfi;
    // Conformer *conf;
    for (cnfi = mol.beginConformers(); cnfi != mol.endConformers(); cnfi++) {
      // conf = (*cnfi);
      i += 1;
      if (i == 1) {
        continue;
      }
      _fillAtomPositions(prbPoints, *(*cnfi), atomIds);
      ssd = RDNumeric::Alignments::AlignPoints(refPoints, prbPoints, trans,
                                               weights, reflect, maxIters);
      if (RMSlist) {
        ssd /= (prbPoints.size());
        RMSlist->push_back(sqrt(ssd));
      }
      MolTransforms::transformConformer(*(*cnfi), trans);
    }
  } else {
    std::vector<unsigned int>::const_iterator cai;
    unsigned int i = 0;
    for (cai = confIds->begin(); cai != confIds->end(); cai++) {
      i += 1;
      if (i == 1) {
        continue;
      }
      Conformer &conf = mol.getConformer(*cai);
      _fillAtomPositions(prbPoints, conf, atomIds);
      ssd = RDNumeric::Alignments::AlignPoints(refPoints, prbPoints, trans,
                                               weights, reflect, maxIters);
      if (RMSlist) {
        ssd /= (prbPoints.size());
        RMSlist->push_back(sqrt(ssd));
      }
      MolTransforms::transformConformer(conf, trans);
    }
  }
}
}
}

This piece isn't backwards compatible, but it's enough of an edge case that I think it's unlikely to be a problem.


@@ -13,32 +13,28 @@ void ListTagIndexesProcessor::process(const cpp2::ListTagIndexesReq& req) {
     auto space = req.get_space_id();
     CHECK_SPACE_ID_AND_RETURN(space);
     folly::SharedMutex::ReadHolder rHolder(LockUtils::tagIndexLock());
-    auto prefix = MetaServiceUtils::tagIndexPrefix(space);
+    auto prefix = MetaServiceUtils::indexPrefix(space);

     std::unique_ptr<kvstore::KVIterator> iter;
     auto ret = kvstore_->prefix(kDefaultSpaceId, kDefaultPartId, prefix, &iter);
     resp_.set_code(to(ret));
     if (ret != kvstore::ResultCode::SUCCEEDED) {
         LOG(ERROR) << "List Tag Index Failed: SpaceID " << space;
+        resp_.set_code(cpp2::ErrorCode::E_NOT_FOUND);
         onFinished();
         return;
     }

     decltype(resp_.items) items;
     while (iter->valid()) {
-        auto key = iter->key();
         auto val = iter->val();
-        auto tagIndex = *reinterpret_cast<const TagIndexID *>(key.data() + prefix.size());
-        auto nameSize = *reinterpret_cast<const int32_t *>(val.data());
-        auto name = val.subpiece(sizeof(int32_t), nameSize).str();
-        auto fields = MetaServiceUtils::parseTagIndex(val);
-        nebula::meta::cpp2::TagIndexItem item;
-        item.set_index_id(tagIndex);
-        item.set_index_name(std::move(name));
-        item.set_fields(std::move(fields));
-        items.emplace_back(std::move(item));
+        auto item = MetaServiceUtils::parseIndex(val);
+        if (item.get_schema_id().getType() == nebula::cpp2::SchemaID::Type::tag_id) {
+            items.emplace_back(std::move(item));
+        }
         iter->next();
     }
+    resp_.set_code(cpp2::ErrorCode::SUCCEEDED);
     resp_.set_items(std::move(items));
     onFinished();
 }

/* Copyright (c) 2019 vesoft inc. All rights reserved.
 *
 * This source code is licensed under Apache 2.0 License,
 * attached with Common Clause Condition 1.0, found in the LICENSES directory.
 */

#include "meta/processors/indexMan/ListTagIndexesProcessor.h"

namespace nebula {
namespace meta {

void ListTagIndexesProcessor::process(const cpp2::ListTagIndexesReq& req) {
    auto space = req.get_space_id();
    CHECK_SPACE_ID_AND_RETURN(space);
    folly::SharedMutex::ReadHolder rHolder(LockUtils::tagIndexLock());
    auto prefix = MetaServiceUtils::tagIndexPrefix(space);

    std::unique_ptr<kvstore::KVIterator> iter;
    auto ret = kvstore_->prefix(kDefaultSpaceId, kDefaultPartId, prefix, &iter);
    resp_.set_code(to(ret));
    if (ret != kvstore::ResultCode::SUCCEEDED) {
        LOG(ERROR) << "List Tag Index Failed: SpaceID " << space;
        onFinished();
        return;
    }

    decltype(resp_.items) items;
    while (iter->valid()) {
        auto key = iter->key();
        auto val = iter->val();
        auto tagIndex = *reinterpret_cast<const TagIndexID *>(key.data() + prefix.size());
        auto nameSize = *reinterpret_cast<const int32_t *>(val.data());
        auto name = val.subpiece(sizeof(int32_t), nameSize).str();
        auto fields = MetaServiceUtils::parseTagIndex(val);
        nebula::meta::cpp2::TagIndexItem item;
        item.set_index_id(tagIndex);
        item.set_index_name(std::move(name));
        item.set_fields(std::move(fields));
        items.emplace_back(std::move(item));
        iter->next();
    }
    resp_.set_items(std::move(items));
    onFinished();
}

}  // namespace meta
}  // namespace nebula

"resp_.set_code(to(ret)); " is not enough?


@@ -23,6 +23,7 @@ void MemoryDataLayer<Dtype>::DataLayerSetUp(const vector<Blob<Dtype>*>& bottom,
   added_label_.Reshape(batch_size_, 1, 1, 1);
   data_ = NULL;
   labels_ = NULL;
+  needs_reshape_ = false;
   added_data_.cpu_data();
   added_label_.cpu_data();
 }

#include <vector>

#include "caffe/data_layers.hpp"
#include "caffe/layer.hpp"
#include "caffe/util/io.hpp"

namespace caffe {

template <typename Dtype>
void MemoryDataLayer<Dtype>::DataLayerSetUp(const vector<Blob<Dtype>*>& bottom,
     const vector<Blob<Dtype>*>& top) {
  batch_size_ = this->layer_param_.memory_data_param().batch_size();
  channels_ = this->layer_param_.memory_data_param().channels();
  height_ = this->layer_param_.memory_data_param().height();
  width_ = this->layer_param_.memory_data_param().width();
  size_ = channels_ * height_ * width_;
  CHECK_GT(batch_size_ * size_, 0) <<
      "batch_size, channels, height, and width must be specified and"
      " positive in memory_data_param";
  top[0]->Reshape(batch_size_, channels_, height_, width_);
  top[1]->Reshape(batch_size_, 1, 1, 1);
  added_data_.Reshape(batch_size_, channels_, height_, width_);
  added_label_.Reshape(batch_size_, 1, 1, 1);
  data_ = NULL;
  labels_ = NULL;
  added_data_.cpu_data();
  added_label_.cpu_data();
}

template <typename Dtype>
void MemoryDataLayer<Dtype>::AddDatumVector(const vector<Datum>& datum_vector) {
  CHECK(!has_new_data_) <<
      "Can't add Datum when earlier ones haven't been consumed"
      << " by the upper layers";
  size_t num = datum_vector.size();
  CHECK_GT(num, 0) << "There is no datum to add";
  CHECK_LE(num, batch_size_) <<
      "The number of added datum must be no greater than the batch size";

  // Apply data transformations (mirror, scale, crop...)
  this->data_transformer_.Transform(datum_vector, &added_data_);
  // Copy Labels
  Dtype* top_label = added_label_.mutable_cpu_data();
  for (int item_id = 0; item_id < num; ++item_id) {
    top_label[item_id] = datum_vector[item_id].label();
  }
  // num_images == batch_size_
  Dtype* top_data = added_data_.mutable_cpu_data();
  Reset(top_data, top_label, batch_size_);
  has_new_data_ = true;
}

template <typename Dtype>
void MemoryDataLayer<Dtype>::Reset(Dtype* data, Dtype* labels, int n) {
  CHECK(data);
  CHECK(labels);
  CHECK_EQ(n % batch_size_, 0) << "n must be a multiple of batch size";
  data_ = data;
  labels_ = labels;
  n_ = n;
  pos_ = 0;
}

template <typename Dtype>
void MemoryDataLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
      const vector<Blob<Dtype>*>& top) {
  CHECK(data_) << "MemoryDataLayer needs to be initalized by calling Reset";
  top[0]->set_cpu_data(data_ + pos_ * size_);
  top[1]->set_cpu_data(labels_ + pos_);
  pos_ = (pos_ + batch_size_) % n_;
  has_new_data_ = false;
}

INSTANTIATE_CLASS(MemoryDataLayer);
REGISTER_LAYER_CLASS(MEMORY_DATA, MemoryDataLayer);
}  // namespace caffe

Initialize `needs_reshape_` with true and call `Reshape` method


@@ -19,6 +19,10 @@
 #include "internal/conversion.h"
 #include "service_memory.h"

+#if defined(__INTEL_COMPILER)
+    #include <immintrin.h>
+#endif
+
 namespace daal
 {
 namespace data_management

/** file data_management_utils_cpu.cpp */
/*******************************************************************************
* Copyright 2014-2019 Intel Corporation
*
* Licensed 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.
*******************************************************************************/

#include "data_conversion_cpu.h"
#include "internal/conversion.h"
#include "service_memory.h"

namespace daal
{
namespace data_management
{
namespace internal
{

template<typename T1, typename T2, CpuType cpu>
void vectorConvertFuncCpu(size_t n, const void *src, void *dst)
{
    for(size_t i = 0; i < n; i++)
    {
        ((T2 *)dst)[i] = static_cast<T2>(((T1 *)src)[i]);
    }
}

template<typename T1, typename T2, CpuType cpu>
void vectorStrideConvertFuncCpu(size_t n, const void *src, size_t srcByteStride, void *dst, size_t dstByteStride)
{
    for(size_t i = 0; i < n ; i++)
    {
        *(T2 *)(((char *)dst) + i * dstByteStride) = static_cast<T2>(*(T1 *)(((char *)src) + i * srcByteStride));
    }
}

#undef  DAAL_FUNCS_UP_ENTRY
#define DAAL_FUNCS_UP_ENTRY(F,T,A)      \
template void F<T, float , DAAL_CPU> A; \
template void F<T, double, DAAL_CPU> A; \
template void F<T, int   , DAAL_CPU> A;

#undef  DAAL_FUNCS_DOWN_ENTRY
#define DAAL_FUNCS_DOWN_ENTRY(F,T,A)    \
template void F<float , T, DAAL_CPU> A; \
template void F<double, T, DAAL_CPU> A; \
template void F<int   , T, DAAL_CPU> A;

#undef  DAAL_CONVERT_UP_FUNCS
#define DAAL_CONVERT_UP_FUNCS(F,A)                    \
        DAAL_FUNCS_UP_ENTRY(F,float,A)                \
        DAAL_FUNCS_UP_ENTRY(F,double,A)               \
        DAAL_FUNCS_UP_ENTRY(F,int,A)                  \
        DAAL_FUNCS_UP_ENTRY(F,unsigned int,A)         \
        DAAL_FUNCS_UP_ENTRY(F,DAAL_INT64,A)           \
        DAAL_FUNCS_UP_ENTRY(F,DAAL_UINT64,A)          \
        DAAL_FUNCS_UP_ENTRY(F,char,A)                 \
        DAAL_FUNCS_UP_ENTRY(F,unsigned char,A)        \
        DAAL_FUNCS_UP_ENTRY(F,short,A)                \
        DAAL_FUNCS_UP_ENTRY(F,unsigned short,A)

#undef  DAAL_CONVERT_DOWN_FUNCS
#define DAAL_CONVERT_DOWN_FUNCS(F,A)                 \
        DAAL_FUNCS_DOWN_ENTRY(F,unsigned int,A)      \
        DAAL_FUNCS_DOWN_ENTRY(F,DAAL_INT64,A)        \
        DAAL_FUNCS_DOWN_ENTRY(F,DAAL_UINT64,A)       \
        DAAL_FUNCS_DOWN_ENTRY(F,char,A)              \
        DAAL_FUNCS_DOWN_ENTRY(F,unsigned char,A)     \
        DAAL_FUNCS_DOWN_ENTRY(F,short,A)             \
        DAAL_FUNCS_DOWN_ENTRY(F,unsigned short,A)

DAAL_CONVERT_UP_FUNCS(vectorConvertFuncCpu,(size_t n, const void *src, void *dst))
DAAL_CONVERT_DOWN_FUNCS(vectorConvertFuncCpu,(size_t n, const void *src, void *dst))

DAAL_CONVERT_UP_FUNCS(vectorStrideConvertFuncCpu,(size_t n, const void *src, size_t srcByteStride, void *dst, size_t dstByteStride))
DAAL_CONVERT_DOWN_FUNCS(vectorStrideConvertFuncCpu,(size_t n, const void *src, size_t srcByteStride, void *dst, size_t dstByteStride))

template<typename T, CpuType cpu>
void vectorAssignValueToArrayCpu(void* const ptr, const size_t n, const void* const value)
{
    const T& valueT = *((const T*)value);
    T* const ptrT = (T*)ptr;
    services::internal::service_memset<T, cpu>(ptrT, valueT, n);
}

#define DAAL_REGISTER_VECTOR_ASSIGN_CPU(Type) template void vectorAssignValueToArrayCpu<Type, DAAL_CPU>(void* const ptr, const size_t n, const void* const value);
DAAL_REGISTER_WITH_HOMOGEN_NT_TYPES(DAAL_REGISTER_VECTOR_ASSIGN_CPU)

} // namespace internal
} // namespace data_management
} // namespace daal


@@ -81,6 +81,11 @@ namespace Impl {
 CudaLockArrays g_host_cuda_lock_arrays = {nullptr, nullptr, 0};

 void initialize_host_cuda_lock_arrays() {
+#ifdef KOKKOS_ENABLE_IMPL_DESUL_ATOMICS
+  desul::Impl::init_lock_arrays();
+
+  DESUL_ENSURE_CUDA_LOCK_ARRAYS_ON_DEVICE();
+#endif
   if (g_host_cuda_lock_arrays.atomic != nullptr) return;
   CUDA_SAFE_CALL(cudaMalloc(&g_host_cuda_lock_arrays.atomic,
                             sizeof(int) * (CUDA_SPACE_ATOMIC_MASK + 1)));

/*
//@HEADER
// ************************************************************************
//
//                        Kokkos v. 3.0
//       Copyright (2020) National Technology & Engineering
//               Solutions of Sandia, LLC (NTESS).
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the name of the Corporation nor the names of the
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY NTESS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NTESS OR THE
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Questions? Contact Christian R. Trott (crtrott@sandia.gov)
//
// ************************************************************************
//@HEADER
*/

#include <Kokkos_Core.hpp>
#ifdef KOKKOS_ENABLE_CUDA
#include <Cuda/Kokkos_Cuda_Locks.hpp>
#include <Cuda/Kokkos_Cuda_Error.hpp>

#ifdef KOKKOS_ENABLE_CUDA_RELOCATABLE_DEVICE_CODE
namespace Kokkos {
namespace Impl {
__device__ __constant__ CudaLockArrays g_device_cuda_lock_arrays = {nullptr,
                                                                    nullptr, 0};
}
}  // namespace Kokkos
#endif

namespace Kokkos {

namespace {

__global__ void init_lock_array_kernel_atomic() {
  unsigned i = blockIdx.x * blockDim.x + threadIdx.x;
  if (i < CUDA_SPACE_ATOMIC_MASK + 1) {
    Kokkos::Impl::g_device_cuda_lock_arrays.atomic[i] = 0;
  }
}

__global__ void init_lock_array_kernel_threadid(int N) {
  unsigned i = blockIdx.x * blockDim.x + threadIdx.x;
  if (i < (unsigned)N) {
    Kokkos::Impl::g_device_cuda_lock_arrays.scratch[i] = 0;
  }
}

}  // namespace

namespace Impl {

CudaLockArrays g_host_cuda_lock_arrays = {nullptr, nullptr, 0};

void initialize_host_cuda_lock_arrays() {
  if (g_host_cuda_lock_arrays.atomic != nullptr) return;
  CUDA_SAFE_CALL(cudaMalloc(&g_host_cuda_lock_arrays.atomic,
                            sizeof(int) * (CUDA_SPACE_ATOMIC_MASK + 1)));
  CUDA_SAFE_CALL(cudaMalloc(&g_host_cuda_lock_arrays.scratch,
                            sizeof(int) * (Cuda::concurrency())));
  CUDA_SAFE_CALL(cudaDeviceSynchronize());
  g_host_cuda_lock_arrays.n = Cuda::concurrency();
  KOKKOS_COPY_CUDA_LOCK_ARRAYS_TO_DEVICE();
  init_lock_array_kernel_atomic<<<(CUDA_SPACE_ATOMIC_MASK + 1 + 255) / 256,
                                  256>>>();
  init_lock_array_kernel_threadid<<<(Kokkos::Cuda::concurrency() + 255) / 256,
                                    256>>>(Kokkos::Cuda::concurrency());
  CUDA_SAFE_CALL(cudaDeviceSynchronize());
}

void finalize_host_cuda_lock_arrays() {
  if (g_host_cuda_lock_arrays.atomic == nullptr) return;
  cudaFree(g_host_cuda_lock_arrays.atomic);
  g_host_cuda_lock_arrays.atomic = nullptr;
  cudaFree(g_host_cuda_lock_arrays.scratch);
  g_host_cuda_lock_arrays.scratch = nullptr;
  g_host_cuda_lock_arrays.n       = 0;
#ifdef KOKKOS_ENABLE_CUDA_RELOCATABLE_DEVICE_CODE
  KOKKOS_COPY_CUDA_LOCK_ARRAYS_TO_DEVICE();
#endif
}

}  // namespace Impl

}  // namespace Kokkos

#else

void KOKKOS_CORE_SRC_CUDA_CUDA_LOCKS_PREVENT_LINK_ERROR() {}

#endif

This one is replaced by `desul`, isn't it? Can `g_host_cuda_lock_arrays.atomic` be guarded and eventually removed as well?


@@ -179,4 +179,24 @@ TEST(proj_context, read_grid_from_user_writable_directory) {
     MyUnlink(filename);
 }

+// ---------------------------------------------------------------------------
+
+TEST(proj_context, proj_context_set_ca_bundle_path) {
+
+    std::string dirname;
+    auto filename = createTempDict(dirname, "temp_proj_dic2");
+    if (filename.empty())
+        return;
+
+    auto ctx = proj_context_create();
+
+    const char *path = dirname.c_str();
+    proj_context_set_ca_bundle_path(ctx, path);
+    ASSERT_EQ(ctx->ca_bundle_path, dirname);
+
+    proj_context_destroy(ctx);
+
+    MyUnlink(filename);
+}
+
 } // namespace

/******************************************************************************
 *
 * Project:  PROJ
 * Purpose:  Test functions in proj_context namespae
 * Author:   Even Rouault <even dot rouault at spatialys dot com>
 *
 ******************************************************************************
 * Copyright (c) 2019, Even Rouault <even dot rouault at spatialys dot com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 ****************************************************************************/

#include <stdlib.h>
#ifdef _MSC_VER
#include <io.h>
#else
#include <unistd.h>
#endif

#include "proj.h"
#include "proj_internal.h"

#include "gtest_include.h"

namespace {

static bool createTmpFile(const std::string &filename) {
    FILE *f = fopen(filename.c_str(), "wt");
    if (!f)
        return false;
    fprintf(
        f,
        "<MY_PIPELINE> +proj=pipeline +step +proj=utm +zone=31 +ellps=GRS80\n");
    fclose(f);
    return true;
}

// ---------------------------------------------------------------------------

static std::string createTempDict(std::string &dirname, const char *filename) {
    const char *temp_dir = getenv("TEMP");
    if (!temp_dir) {
        temp_dir = getenv("TMP");
    }
#ifndef WIN32
    if (!temp_dir) {
        temp_dir = "/tmp";
    }
#endif
    if (!temp_dir)
        return std::string();

    dirname = temp_dir;

    std::string tmpFilename;
    tmpFilename = temp_dir;
    tmpFilename += DIR_CHAR;
    tmpFilename += filename;

    return createTmpFile(tmpFilename) ? tmpFilename : std::string();
}

// ---------------------------------------------------------------------------

static int MyUnlink(const std::string &filename) {
#ifdef _MSC_VER
    return _unlink(filename.c_str());
#else
    return unlink(filename.c_str());
#endif
}

// ---------------------------------------------------------------------------

TEST(proj_context, proj_context_set_file_finder) {

    std::string dirname;
    auto filename = createTempDict(dirname, "temp_proj_dic1");
    if (filename.empty())
        return;

    auto ctx = proj_context_create();

    struct FinderData {
        PJ_CONTEXT *got_ctx = nullptr;
        std::string dirname{};
        std::string tmpFilename{};
    };

    const auto finder = [](PJ_CONTEXT *got_ctx, const char *file,
                           void *user_data) -> const char * {
        auto finderData = static_cast<FinderData *>(user_data);
        finderData->got_ctx = got_ctx;
        finderData->tmpFilename = finderData->dirname;
        finderData->tmpFilename += DIR_CHAR;
        finderData->tmpFilename += file;
        return finderData->tmpFilename.c_str();
    };

    FinderData finderData;
    finderData.dirname = dirname;
    proj_context_set_file_finder(ctx, finder, &finderData);

    auto P = proj_create(ctx, "+init=temp_proj_dic1:MY_PIPELINE");
    EXPECT_NE(P, nullptr);
    proj_destroy(P);

    EXPECT_EQ(finderData.got_ctx, ctx);

    proj_context_destroy(ctx);
}

// ---------------------------------------------------------------------------

TEST(proj_context, proj_context_set_search_paths) {

    std::string dirname;
    auto filename = createTempDict(dirname, "temp_proj_dic2");
    if (filename.empty())
        return;

    auto ctx = proj_context_create();

    const char *path = dirname.c_str();
    proj_context_set_search_paths(ctx, 1, &path);

    auto P = proj_create(ctx, "+init=temp_proj_dic2:MY_PIPELINE");
    EXPECT_NE(P, nullptr);
    proj_destroy(P);

    proj_context_destroy(ctx);

    MyUnlink(filename);
}

// ---------------------------------------------------------------------------

TEST(proj_context, read_grid_from_user_writable_directory) {

    auto ctx = proj_context_create();
    auto path =
        std::string(proj_context_get_user_writable_directory(ctx, true));
    EXPECT_TRUE(!path.empty());
    auto filename = path + DIR_CHAR + "temp_proj_dic3";
    EXPECT_TRUE(createTmpFile(filename));
    {
        // Check that with PROJ_SKIP_READ_USER_WRITABLE_DIRECTORY=YES (set by
        // calling script), we cannot find the file
        auto P = proj_create(ctx, "+init=temp_proj_dic3:MY_PIPELINE");
        EXPECT_EQ(P, nullptr);
        proj_destroy(P);
    }
    {
        // Cancel the effect of PROJ_SKIP_READ_USER_WRITABLE_DIRECTORY
        putenv(const_cast<char *>("PROJ_SKIP_READ_USER_WRITABLE_DIRECTORY="));
        auto P = proj_create(ctx, "+init=temp_proj_dic3:MY_PIPELINE");
        EXPECT_NE(P, nullptr);
        putenv(
            const_cast<char *>("PROJ_SKIP_READ_USER_WRITABLE_DIRECTORY=YES"));
        proj_destroy(P);
    }
    proj_context_destroy(ctx);
    MyUnlink(filename);
}

} // namespace

creating the directory and deleting afterwards is probably unneeded. You could pass a completely dummy string


@@ -4,12 +4,8 @@
  *  (found in the LICENSE.Apache file in the root directory)
  */
 #include <gtest/gtest.h>
-#include <cstdlib>
-#include <thread>
-#include <mutex>
-#include <atomic>
-#include "common/concurrent/Barrier.h"
-#include "common/thread/GenericThreadPool.h"
+#include "concurrent/Barrier.h"
+#include "thread/GenericThreadPool.h"

 namespace vesoft {
 namespace concurrent {

/* Copyright (c) 2018 - present, VE Software Inc. All rights reserved
 *
 * This source code is licensed under Apache 2.0 License
 *  (found in the LICENSE.Apache file in the root directory)
 */
#include <gtest/gtest.h>
#include <cstdlib>
#include <thread>
#include <mutex>
#include <atomic>
#include "common/concurrent/Barrier.h"
#include "common/thread/GenericThreadPool.h"

namespace vesoft {
namespace concurrent {

TEST(BarrierTest, BasicTest) {
    // test for invalid initial counter
    {
        ASSERT_THROW({Barrier barrier(0UL);}, std::invalid_argument);
    }
    // test for single-thread normal case
    {
        Barrier barrier(1UL);
        barrier.wait();
        ASSERT_TRUE(true);
    }
    // test for multiple-thread normal case
    {
        Barrier barrier(2UL);
        std::atomic<size_t> counter{0};
        auto cb = [&] () {
            barrier.wait();
            ++counter;
        };
        std::thread thread(cb);
        usleep(1000);
        ASSERT_EQ(0UL, counter.load());
        barrier.wait();
        thread.join();
        ASSERT_EQ(1UL, counter.load());
    }
    // test for multiple-thread completion
    {
        std::atomic<size_t> counter{0};
        auto completion = [&] () {
            ++counter;
            ++counter;
        };
        Barrier barrier(2UL, completion);

        auto cb = [&] () {
            barrier.wait();
            ++counter;
        };

        std::thread thread(cb);
        usleep(1000);
        ASSERT_EQ(0UL, counter.load());
        barrier.wait();
        ASSERT_GE(counter.load(), 2UL);
        thread.join();
        ASSERT_EQ(3UL, counter.load());
    }
}

TEST(BarrierTest, ConsecutiveTest) {
    std::atomic<size_t> counter{0};
    constexpr auto N = 64UL;
    constexpr auto iters = 100UL;
    auto completion = [&] () {
        // At the completion phase, `counter' should be multiple to `N'.
        ASSERT_EQ(0UL, counter.load() % N);
    };

    Barrier barrier(N, completion);
    auto cb = [&] () {
        auto i = iters;
        while (i-- != 0) {
            ++counter;
            barrier.wait();
        }
    };

    std::vector<std::thread> threads;
    for (auto i = 0UL; i < N; i++) {
        threads.emplace_back(cb);
    }
    for (auto &thread : threads) {
        thread.join();
    }
    ASSERT_EQ(0UL, counter.load() % N);
}

}   // namespace concurrent
}   // namespace vesoft

Need to include "common/base/Base.h" in front of this line


@@ -40,14 +40,24 @@ JNIEXPORT jint JNICALL Java_org_apache_hadoop_hbase_client_transactional_RMInter
    char la_tbldesc[TM_MAX_DDLREQUEST_STRING];
    char la_tblname[TM_MAX_DDLREQUEST_STRING];
    char* str_key;
-   str_key = new char[TM_MAX_DDLREQUEST_STRING];
    char** la_keys;
    la_keys = new char *[TM_MAX_DDLREQUEST_STRING];
    int lv_error = FEOK;

+   if( pv_keyLength > TM_MAX_DDLREQUEST_STRING)
+   {
+     cout << "Table key length is larger than max allowed " << pv_keyLength << endl;
+     delete [] la_keys;
+     return FEBADKEYDESC;
+   }
+   str_key = new char[TM_MAX_DDLREQUEST_STRING];
+
    int lv_tblname_len = pp_env->GetArrayLength(pv_tblname);
    if(lv_tblname_len > TM_MAX_DDLREQUEST_STRING) {
       cout << "Table name length is larger than max allowed" << endl;
+      delete [] la_keys;
+      delete str_key;
+      return FEBADNAME;
    }
    else {
       int lv_tbldesc_length = pp_env->GetArrayLength(pv_tableDescriptor);

/*
* @@@ START COPYRIGHT @@@
*
* 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.
*
* @@@ END COPYRIGHT @@@                                                          */

#include "tmddlrequests.h"
#include "dtm/tm.h"
#include <string.h>
#include <iostream>
#include "../../inc/fs/feerrors.h"

using namespace std;

/*
* Class:     org_apache_hadoop_hbase_client_transactional_RMInterface
* Method:    createTableReq
* Signature: ([B)V
*/

JNIEXPORT jint JNICALL Java_org_apache_hadoop_hbase_client_transactional_RMInterface_createTableReq
  (JNIEnv *pp_env, jobject pv_object, jbyteArray pv_tableDescriptor, jobjectArray pv_keys, jint pv_numSplits, jint pv_keyLength, jlong pv_transid, jbyteArray pv_tblname){

   char la_tbldesc[TM_MAX_DDLREQUEST_STRING];
   char la_tblname[TM_MAX_DDLREQUEST_STRING];
   char* str_key;
   str_key = new char[TM_MAX_DDLREQUEST_STRING];
   char** la_keys;
   la_keys = new char *[TM_MAX_DDLREQUEST_STRING];
   int lv_error = FEOK;

   int lv_tblname_len = pp_env->GetArrayLength(pv_tblname);
   if(lv_tblname_len > TM_MAX_DDLREQUEST_STRING) {
      cout << "Table name length is larger than max allowed" << endl;
   }
   else {
      int lv_tbldesc_length = pp_env->GetArrayLength(pv_tableDescriptor);
      memset(la_tbldesc, 0, lv_tbldesc_length);
      jbyte *lp_tbldesc = pp_env->GetByteArrayElements(pv_tableDescriptor, 0);
      memcpy(la_tbldesc, lp_tbldesc, lv_tbldesc_length);

      memset(la_tblname, 0, lv_tblname_len < TM_MAX_DDLREQUEST_STRING ? lv_tblname_len : TM_MAX_DDLREQUEST_STRING);
      jbyte *lp_tblname = pp_env->GetByteArrayElements(pv_tblname, 0);
      memcpy(la_tblname, lp_tblname, lv_tblname_len < TM_MAX_DDLREQUEST_STRING ? lv_tblname_len : TM_MAX_DDLREQUEST_STRING -1 );

      long lv_transid = (long) pv_transid;

      // Keys for Salted Tables
      int lv_numSplits = (int) pv_numSplits;
      int lv_keyLength = (int) pv_keyLength;

      for(int i=0; i<lv_numSplits; i++)
      {
         jbyteArray jba_keyarray = (jbyteArray)(pp_env->GetObjectArrayElement((jobjectArray)pv_keys, i));
         int lv_key_len = pp_env->GetArrayLength(jba_keyarray);
         pp_env->GetByteArrayRegion(jba_keyarray, 0, lv_key_len, (jbyte*)str_key);

         la_keys[i] = new char[lv_key_len];
         memcpy(la_keys[i], str_key, lv_key_len);

         pp_env->DeleteLocalRef(jba_keyarray);
      }

      lv_error  = CREATETABLE(la_tbldesc, lv_tbldesc_length, la_tblname, la_keys, lv_numSplits, lv_keyLength, lv_transid);

      pp_env->ReleaseByteArrayElements(pv_tableDescriptor, lp_tbldesc, 0);
      pp_env->ReleaseByteArrayElements(pv_tblname, lp_tblname, 0);
   }
   return lv_error;
}

/*
 * Class:     org_apache_hadoop_hbase_client_transactional_RMInterface
 * Method:    dropTableReq
 * Signature: ([BJ)V
 */
JNIEXPORT jint JNICALL Java_org_apache_hadoop_hbase_client_transactional_RMInterface_dropTableReq
  (JNIEnv *pp_env, jobject pv_object, jbyteArray pv_tblname, jlong pv_transid) {

   char la_tblname[TM_MAX_DDLREQUEST_STRING];
   int lv_error = FEOK;

   int lv_tblname_len = pp_env->GetArrayLength(pv_tblname);
   if(lv_tblname_len > TM_MAX_DDLREQUEST_STRING) {
      cout << "Table name length is larger than max allowed" << endl;
   }
   else {
      memset(la_tblname, 0, lv_tblname_len < TM_MAX_DDLREQUEST_STRING ? lv_tblname_len : TM_MAX_DDLREQUEST_STRING);
      jbyte *lp_tblname = pp_env->GetByteArrayElements(pv_tblname, 0);
      memcpy(la_tblname, lp_tblname, lv_tblname_len < TM_MAX_DDLREQUEST_STRING ? lv_tblname_len : TM_MAX_DDLREQUEST_STRING -1 );

      long lv_transid = (long) pv_transid;

      lv_error = DROPTABLE(la_tblname, lv_tblname_len, lv_transid);
      pp_env->ReleaseByteArrayElements(pv_tblname, lp_tblname, 0);
   }
   return lv_error;
}

/*
 * Class:     org_apache_hadoop_hbase_client_transactional_RMInterface
 * Method:    truncateOnAbortReq
 * Signature: ([BJ)V
 */
JNIEXPORT jint JNICALL Java_org_apache_hadoop_hbase_client_transactional_RMInterface_truncateOnAbortReq
  (JNIEnv *pp_env, jobject pv_object, jbyteArray pv_tblname, jlong pv_transid) {

   char la_tblname[TM_MAX_DDLREQUEST_STRING];
   int lv_error = FEOK;

   int lv_tblname_len = pp_env->GetArrayLength(pv_tblname);
   if(lv_tblname_len > TM_MAX_DDLREQUEST_STRING) {
      cout << "Table name length is larger than max allowed" << endl;
   }
   else {
      memset(la_tblname, 0, lv_tblname_len < TM_MAX_DDLREQUEST_STRING ? lv_tblname_len : TM_MAX_DDLREQUEST_STRING);
      jbyte *lp_tblname = pp_env->GetByteArrayElements(pv_tblname, 0);
      memcpy(la_tblname, lp_tblname, lv_tblname_len < TM_MAX_DDLREQUEST_STRING ? lv_tblname_len : TM_MAX_DDLREQUEST_STRING -1 );

      long lv_transid = (long) pv_transid;

      lv_error = REGTRUNCATEONABORT(la_tblname, lv_tblname_len, lv_transid);
      pp_env->ReleaseByteArrayElements(pv_tblname, lp_tblname, 0);
   }
   return lv_error;
}

/*
 * Class:     org_apache_hadoop_hbase_client_transactional_RMInterface
 * Method:    alterTableReq
 * Signature: ([B[Ljava/lang/Object;J)V
 */
JNIEXPORT jint JNICALL Java_org_apache_hadoop_hbase_client_transactional_RMInterface_alterTableReq
  (JNIEnv *pp_env, jobject pv_object, jbyteArray pv_tblName, jobjectArray pv_tableOptions, jlong pv_transID) {

   int lv_error = FEOK;
   int tblopts_len =0;
   char la_tblname[TM_MAX_DDLREQUEST_STRING];

   char** tbl_options;
   tbl_options = new char *[TM_MAX_DDLREQUEST_STRING];

   int lv_tblname_len = pp_env->GetArrayLength(pv_tblName);
   if(lv_tblname_len > TM_MAX_DDLREQUEST_STRING) {
      cout << "Table name length is larger than max allowed" << endl;
   }
   else {
      memset(la_tblname, 0, lv_tblname_len < TM_MAX_DDLREQUEST_STRING ? lv_tblname_len : TM_MAX_DDLREQUEST_STRING);
      jbyte *lp_tblname = pp_env->GetByteArrayElements(pv_tblName, 0);
      memcpy(la_tblname, lp_tblname, lv_tblname_len < TM_MAX_DDLREQUEST_STRING ? lv_tblname_len : TM_MAX_DDLREQUEST_STRING -1 );

      int tbloptions_cnt = pp_env->GetArrayLength(pv_tableOptions);

      for (int i=0; i<tbloptions_cnt; i++) {

         cout << " TableOptions loop " << i << endl;
         jstring jstr_options = (jstring) pp_env->GetObjectArrayElement(pv_tableOptions, i);
         const char *str_options = pp_env->GetStringUTFChars(jstr_options, 0);
         // Don't forget to call `ReleaseStringUTFChars` when you're done.

         //int str_opts_len = length(jstr_options);
         //int str_opts_len = pp_env->GetStringUTFLength(jstr_options);
         int str_opts_len = sizeof(str_options)/sizeof(*str_options);
         cout << "str_opts_len: " << str_opts_len <<  " or " << sizeof(str_options)/sizeof(*str_options) << endl;

         tbl_options[i] = new char[tbloptions_cnt];
         memcpy(tbl_options[i], str_options, str_opts_len);

         pp_env->ReleaseStringUTFChars(jstr_options, str_options);

         if(tblopts_len == 0)
            tblopts_len = str_opts_len;
      }

      long lv_transid = (long) pv_transID;
      lv_error = ALTERTABLE(la_tblname, lv_tblname_len, tbl_options, tblopts_len, tbloptions_cnt, lv_transid);
      pp_env->ReleaseByteArrayElements(pv_tblName, lp_tblname, 0);
   }
   return lv_error;
}

A native English speaker will see "Table key length is larger than max allowed 5123" and think that 5123 is the max, instead of the actual key length value. It might be a bit clearer if it were "Table key length 5123 is larger than max allowed".


@@ -55,6 +55,12 @@ folly::StringPiece LogStrListIterator::logMsg() const {
     return logEntries_.at(idx_).get_log_str();
 }

+LogEntry LogStrListIterator::logEntry() {
+    DCHECK(valid());
+    return {firstLogId_ + idx_, term_, logEntries_.at(idx_).get_cluster(),
+            logEntries_.at(idx_).get_log_str()};
+}
+
 }  // namespace raftex
 }  // namespace nebula

/* Copyright (c) 2018 vesoft inc. All rights reserved.
 *
 * This source code is licensed under Apache 2.0 License,
 * attached with Common Clause Condition 1.0, found in the LICENSES directory.
 */

#include "base/Base.h"
#include "kvstore/raftex/LogStrListIterator.h"

namespace nebula {
namespace raftex {

LogStrListIterator::LogStrListIterator(
    LogID firstLogId,
    TermID term,
    std::vector<cpp2::LogEntry> logEntries)
        : firstLogId_(firstLogId)
        , term_(term)
        , logEntries_(std::move(logEntries)) {
    idx_ = 0;
}

LogIterator& LogStrListIterator::operator++() {
    ++idx_;
    return *this;
}

bool LogStrListIterator::valid() const {
    return idx_ < logEntries_.size();
}

LogID LogStrListIterator::logId() const {
    DCHECK(valid());
    return firstLogId_ + idx_;
}

TermID LogStrListIterator::logTerm() const {
    DCHECK(valid());
    return term_;
}

ClusterID LogStrListIterator::logSource() const {
    DCHECK(valid());
    return logEntries_.at(idx_).get_cluster();
}

folly::StringPiece LogStrListIterator::logMsg() const {
    DCHECK(valid());
    return logEntries_.at(idx_).get_log_str();
}

}  // namespace raftex
}  // namespace nebula

I strongly suggest to explicitly construct the tuple, like `return LogEntry(...)`. Actually, using it this way is not standardized until C++17, although the compilers of latest versions(at least not in GCC 5.2) already have supported it.


@@ -64,4 +64,53 @@ BOOST_AUTO_TEST_CASE(test_match)
     }
 }

+BOOST_AUTO_TEST_CASE(test_match_split)
+{
+    using namespace osrm;
+
+    auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/ch/monaco.osrm");
+
+    MatchParameters params;
+    params.coordinates = get_split_trace_locations();
+    params.timestamps = {1,2,1700,1800};
+
+    json::Object result;
+
+    const auto rc = osrm.Match(params, result);
+
+    BOOST_CHECK(rc == Status::Ok || rc == Status::Error);
+    const auto code = result.values.at("code").get<json::String>().value;
+    BOOST_CHECK_EQUAL(code, "Ok");
+
+    const auto &tracepoints = result.values.at("tracepoints").get<json::Array>().values;
+    BOOST_CHECK_EQUAL(tracepoints.size(), params.coordinates.size());
+
+    const auto &matchings = result.values.at("matchings").get<json::Array>().values;
+    const auto &number_of_matchings = matchings.size();
+    BOOST_CHECK_EQUAL(number_of_matchings, 2);
+    for (const auto &waypoint : tracepoints)
+    {
+        if (waypoint.is<mapbox::util::recursive_wrapper<util::json::Object>>())
+        {
+            BOOST_CHECK(waypoint_check(waypoint));
+            const auto &waypoint_object = waypoint.get<json::Object>();
+            const auto matchings_index =
+                waypoint_object.values.at("matchings_index").get<json::Number>().value;
+            const auto waypoint_index =
+                waypoint_object.values.at("waypoint_index").get<json::Number>().value;
+            const auto &route_legs = matchings[matchings_index]
+                                         .get<json::Object>()
+                                         .values.at("legs")
+                                         .get<json::Array>()
+                                         .values;
+            BOOST_CHECK_LT(waypoint_index, route_legs.size() + 1);
+            BOOST_CHECK_LT(matchings_index, number_of_matchings);
+        }
+        else
+        {
+            BOOST_CHECK(waypoint.is<json::Null>());
+        }
+    }
+}
+
 BOOST_AUTO_TEST_SUITE_END()

#include <boost/test/test_case_template.hpp>
#include <boost/test/unit_test.hpp>

#include "coordinates.hpp"
#include "fixture.hpp"
#include "waypoint_check.hpp"

#include "osrm/match_parameters.hpp"

#include "osrm/coordinate.hpp"
#include "osrm/engine_config.hpp"
#include "osrm/json_container.hpp"
#include "osrm/osrm.hpp"
#include "osrm/status.hpp"

BOOST_AUTO_TEST_SUITE(match)

BOOST_AUTO_TEST_CASE(test_match)
{
    using namespace osrm;

    auto osrm = getOSRM(OSRM_TEST_DATA_DIR "/ch/monaco.osrm");

    MatchParameters params;
    params.coordinates.push_back(get_dummy_location());
    params.coordinates.push_back(get_dummy_location());
    params.coordinates.push_back(get_dummy_location());

    json::Object result;

    const auto rc = osrm.Match(params, result);

    BOOST_CHECK(rc == Status::Ok || rc == Status::Error);
    const auto code = result.values.at("code").get<json::String>().value;
    BOOST_CHECK_EQUAL(code, "Ok");

    const auto &tracepoints = result.values.at("tracepoints").get<json::Array>().values;
    BOOST_CHECK_EQUAL(tracepoints.size(), params.coordinates.size());

    const auto &matchings = result.values.at("matchings").get<json::Array>().values;
    const auto &number_of_matchings = matchings.size();
    for (const auto &waypoint : tracepoints)
    {
        if (waypoint.is<mapbox::util::recursive_wrapper<util::json::Object>>())
        {
            BOOST_CHECK(waypoint_check(waypoint));
            const auto &waypoint_object = waypoint.get<json::Object>();
            const auto matchings_index =
                waypoint_object.values.at("matchings_index").get<json::Number>().value;
            const auto waypoint_index =
                waypoint_object.values.at("waypoint_index").get<json::Number>().value;
            const auto &route_legs = matchings[matchings_index]
                                         .get<json::Object>()
                                         .values.at("legs")
                                         .get<json::Array>()
                                         .values;
            BOOST_CHECK_LT(waypoint_index, route_legs.size() + 1);
            BOOST_CHECK_LT(matchings_index, number_of_matchings);
        }
        else
        {
            BOOST_CHECK(waypoint.is<json::Null>());
        }
    }
}

BOOST_AUTO_TEST_SUITE_END()

This is a bad check, since it would still pass in the following cases: - All `waypoint_index` values are the same like `0, 0, 0, 0` - The order of values of `waypoint_index` is random `0, 2, 1, 4` - There could be holes like `0, 1, 5, 6` The check should actually check that the value for `waypoint_index` is really ascending like `0, 1, 2, 3`.


@@ -28,6 +28,21 @@ void DropEdgeIndexProcessor::process(const cpp2::DropEdgeIndexReq& req) {
     }

     std::vector<std::string> keys;
+    // delete rebuild index status info
+    auto indexStatusKey = MetaServiceUtils::rebuildIndexStatus(spaceID, 'E', indexName);
+    std::string status;
+    auto ret = kvstore_->get(kDefaultSpaceId, kDefaultPartId, indexStatusKey, &status);
+    if (ret == kvstore::ResultCode::SUCCEEDED) {
+        if (status == "RUNNING") {
+            LOG(ERROR) << "Edge Index status is RUNNING, drop index is not allowed. Index : "
+                       << indexName;
+            handleErrorCode(cpp2::ErrorCode::E_CONFLICT);
+            onFinished();
+            return;
+        } else {
+            keys.emplace_back(std::move(indexStatusKey));
+        }
+    }
     keys.emplace_back(MetaServiceUtils::indexIndexKey(spaceID, indexName));
     keys.emplace_back(MetaServiceUtils::indexKey(spaceID, edgeIndexID.value()));

/* Copyright (c) 2019 vesoft inc. All rights reserved.
 *
 * This source code is licensed under Apache 2.0 License,
 * attached with Common Clause Condition 1.0, found in the LICENSES directory.
 */

#include "meta/processors/indexMan/DropEdgeIndexProcessor.h"

namespace nebula {
namespace meta {

void DropEdgeIndexProcessor::process(const cpp2::DropEdgeIndexReq& req) {
    auto spaceID = req.get_space_id();
    auto indexName = req.get_index_name();
    CHECK_SPACE_ID_AND_RETURN(spaceID);
    folly::SharedMutex::WriteHolder wHolder(LockUtils::edgeIndexLock());

    auto edgeIndexID = getIndexID(spaceID, indexName);
    if (!edgeIndexID.ok()) {
        LOG(ERROR) << "Edge Index not exists in Space: " << spaceID << " Index name: " << indexName;
        if (req.get_if_exists()) {
            handleErrorCode(cpp2::ErrorCode::SUCCEEDED);
        } else {
            handleErrorCode(cpp2::ErrorCode::E_NOT_FOUND);
        }
        onFinished();
        return;
    }

    std::vector<std::string> keys;
    keys.emplace_back(MetaServiceUtils::indexIndexKey(spaceID, indexName));
    keys.emplace_back(MetaServiceUtils::indexKey(spaceID, edgeIndexID.value()));

    LOG(INFO) << "Drop Edge Index " << indexName;
    resp_.set_id(to(edgeIndexID.value(), EntryType::INDEX));
    doSyncMultiRemoveAndUpdate(std::move(keys));
}

}  // namespace meta
}  // namespace nebula


@@ -40,6 +40,8 @@ void DropSpaceExecutor::execute() {
         if (*spaceName_ == ectx()->rctx()->session()->spaceName()) {
             ectx()->rctx()->session()->setSpace("", -1);
         }
+        ectx()->addWarningMsg("Data will be deleted completely after restarting the services");
+
         doFinish(Executor::ProcessControl::kNext);
     };

/* Copyright (c) 2018 vesoft inc. All rights reserved.
 *
 * This source code is licensed under Apache 2.0 License,
 * attached with Common Clause Condition 1.0, found in the LICENSES directory.
 */

#include "graph/DropSpaceExecutor.h"

namespace nebula {
namespace graph {

DropSpaceExecutor::DropSpaceExecutor(Sentence *sentence,
                                     ExecutionContext *ectx)
    : Executor(ectx, "drop_space") {
    sentence_ = static_cast<DropSpaceSentence*>(sentence);
}

Status DropSpaceExecutor::prepare() {
    spaceName_ = sentence_->spaceName();
    return Status::OK();
}

void DropSpaceExecutor::execute() {
    auto future = ectx()->getMetaClient()->dropSpace(*spaceName_, sentence_->isIfExists());
    auto *runner = ectx()->rctx()->runner();

    auto cb = [this] (auto &&resp) {
        if (!resp.ok()) {
            doError(std::move(resp).status());
            return;
        }
        auto  ret = std::move(resp).value();
        if (!ret) {
            doError(Status::Error("Drop space `%s' failed.", spaceName_->c_str()));
            return;
        }

        if (*spaceName_ == ectx()->rctx()->session()->spaceName()) {
            ectx()->rctx()->session()->setSpace("", -1);
        }
        doFinish(Executor::ProcessControl::kNext);
    };

    auto error = [this] (auto &&e) {
        auto msg = folly::stringPrintf("Drop space `%s' exception: %s",
                spaceName_->c_str(), e.what().c_str());
        LOG(ERROR) << msg;
        doError(Status::Error(std::move(msg)));
        return;
    };

    std::move(future).via(runner).thenValue(cb).thenError(error);
}

void DropSpaceExecutor::setupResponse(cpp2::ExecutionResponse &resp)  {
    resp.set_warning_msg("Data will be deleted completely after restarting the services.");
}
}   // namespace graph
}   // namespace nebula


@@ -120,8 +120,16 @@ int main(int argc, char **argv)
     MPI_Init(nullptr, nullptr);
 #endif

-    ::testing::InitGoogleTest(&argc, argv);
-    int result = RUN_ALL_TESTS();
+    int result = -1;
+    try
+    {
+        ::testing::InitGoogleTest(&argc, argv);
+        result = RUN_ALL_TESTS();
+    }
+    catch (std::exception &e)
+    {
+        result = 1;
+    }

 #ifdef ADIOS2_HAVE_MPI
     MPI_Finalize();

/*
 * Distributed under the OSI-approved Apache License, Version 2.0.  See
 * accompanying file Copyright.txt for details.
 *
 * TestBPWriteTypes.c
 *
 *  Created on: Aug 9, 2017
 *      Author: Haocheng
 */

#include <adios2_c.h>

#ifdef ADIOS2_HAVE_MPI
#include <mpi.h>
#endif

#include <gtest/gtest.h>

#include "SmallTestData_c.h"

class BPWriteTypes : public ::testing::Test
{
public:
    BPWriteTypes() = default;
};

TEST_F(BPWriteTypes, ADIOS2BPWriteTypes)
{
#ifdef ADIOS2_HAVE_MPI
    int rank(0);
    int size(0);
    adios2_adios *adiosH = adios2_init(MPI_COMM_WORLD, adios2_debug_mode_on);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
#else
    adios2_adios *adiosH = adios2_init_nompi(adios2_debug_mode_on);
#endif

    // IO
    adios2_io *ioH = adios2_declare_io(adiosH, "CArrayTypes");
    // Set engine parameters
    adios2_set_engine(ioH, "BPFile");
    adios2_set_parameter(ioH, "ProfileUnits", "Microseconds");
    adios2_set_parameter(ioH, "Threads", "1");

    // Set transport and parameters
    const unsigned int transportID = adios2_add_transport(ioH, "File");
    adios2_set_transport_parameter(ioH, transportID, "library", "fstream");

    // count dims are allocated in stack
    size_t count[1];
    count[0] = data_Nx;

    // Define variables in ioH
    {

        adios2_define_variable(ioH, "varI8", adios2_type_int8_t, 1, NULL, NULL,
                               count, adios2_constant_dims_true, NULL);
        adios2_define_variable(ioH, "varI16", adios2_type_int16_t, 1, NULL,
                               NULL, count, adios2_constant_dims_true, NULL);
        adios2_define_variable(ioH, "varI32", adios2_type_int32_t, 1, NULL,
                               NULL, count, adios2_constant_dims_true, NULL);
        adios2_define_variable(ioH, "varI64", adios2_type_int64_t, 1, NULL,
                               NULL, count, adios2_constant_dims_true, NULL);

        adios2_define_variable(ioH, "varU8", adios2_type_uint8_t, 1, NULL, NULL,
                               count, adios2_constant_dims_true, NULL);
        adios2_define_variable(ioH, "varU16", adios2_type_uint16_t, 1, NULL,
                               NULL, count, adios2_constant_dims_true, NULL);
        adios2_define_variable(ioH, "varU32", adios2_type_uint32_t, 1, NULL,
                               NULL, count, adios2_constant_dims_true, NULL);
        adios2_define_variable(ioH, "varU64", adios2_type_uint64_t, 1, NULL,
                               NULL, count, adios2_constant_dims_true, NULL);

        adios2_define_variable(ioH, "varR32", adios2_type_float, 1, NULL, NULL,
                               count, adios2_constant_dims_true, NULL);
        adios2_define_variable(ioH, "varR64", adios2_type_double, 1, NULL, NULL,
                               count, adios2_constant_dims_true, NULL);
    }
    // inquire variables
    adios2_variable *varI8 = adios2_inquire_variable(ioH, "varI8");
    adios2_variable *varI16 = adios2_inquire_variable(ioH, "varI16");
    adios2_variable *varI32 = adios2_inquire_variable(ioH, "varI32");
    adios2_variable *varI64 = adios2_inquire_variable(ioH, "varI64");
    adios2_variable *varU8 = adios2_inquire_variable(ioH, "varU8");
    adios2_variable *varU16 = adios2_inquire_variable(ioH, "varU16");
    adios2_variable *varU32 = adios2_inquire_variable(ioH, "varU32");
    adios2_variable *varU64 = adios2_inquire_variable(ioH, "varU64");
    adios2_variable *varR32 = adios2_inquire_variable(ioH, "varR32");
    adios2_variable *varR64 = adios2_inquire_variable(ioH, "varR64");

    adios2_engine *engineH = adios2_open(ioH, "ctypes.bp", adios2_mode_write);

    adios2_put_sync(engineH, varI8, data_I8);
    adios2_put_sync(engineH, varI16, data_I16);
    adios2_put_sync(engineH, varI32, data_I32);
    adios2_put_sync(engineH, varI64, data_I64);

    adios2_put_sync(engineH, varU8, data_U8);
    adios2_put_sync(engineH, varU16, data_U16);
    adios2_put_sync(engineH, varU32, data_U32);
    adios2_put_sync(engineH, varU64, data_U64);

    adios2_put_sync(engineH, varR32, data_R32);
    adios2_put_sync(engineH, varR64, data_R64);

    adios2_close(engineH);

    // deallocate adiosH
    adios2_finalize(adiosH);
}

//******************************************************************************
// main
//******************************************************************************

int main(int argc, char **argv)
{
#ifdef ADIOS2_HAVE_MPI
    MPI_Init(nullptr, nullptr);
#endif

    ::testing::InitGoogleTest(&argc, argv);
    int result = RUN_ALL_TESTS();

#ifdef ADIOS2_HAVE_MPI
    MPI_Finalize();
#endif

    return result;
}

Why swallow the exception here rather than propagate it?


@@ -27,7 +27,7 @@ struct train_kernel_cpu<Float, method::brute_force> {
     train_result operator()(const context_cpu& ctx,
                             const descriptor_base& desc,
                             const train_input& input) const {
-        throw unimplemented_error("k-NN brute force method is not implemented for CPU!");
+        throw unimplemented_error("k-NN brute force method is not implemented for CPU");
         return train_result();
     }
 };

/*******************************************************************************
* Copyright 2020 Intel Corporation
*
* Licensed 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.
*******************************************************************************/

#include "oneapi/dal/algo/knn/backend/cpu/train_kernel.hpp"
#include "oneapi/dal/backend/interop/common.hpp"
#include "oneapi/dal/backend/interop/error_converter.hpp"

namespace oneapi::dal::knn::backend {

using dal::backend::context_cpu;

template <typename Float>
struct train_kernel_cpu<Float, method::brute_force> {
    train_result operator()(const context_cpu& ctx,
                            const descriptor_base& desc,
                            const train_input& input) const {
        throw unimplemented_error("k-NN brute force method is not implemented for CPU!");
        return train_result();
    }
};

template struct train_kernel_cpu<float, method::brute_force>;
template struct train_kernel_cpu<double, method::brute_force>;

} // namespace oneapi::dal::knn::backend


@@ -35,15 +35,17 @@ int main(int argc, char *argv[])
         adios2::Variable<float> bpFloats = bpIO.DefineVariable<float>(
             "bpFloats", {}, {}, {Nx}, adios2::ConstantDims);

+        std::string filename = "myVector_cpp.bp";
         /** Engine derived class, spawned to start IO operations */
         adios2::Engine bpWriter =
-            bpIO.Open("myVector_cpp.bp", adios2::Mode::Write);
+            bpIO.Open(filename, adios2::Mode::Write);

         /** Write variable for buffering */
         bpWriter.Put<float>(bpFloats, myFloats.data());

         /** Create bp file, engine becomes unreachable after this*/
         bpWriter.Close();
+        std::cout << "Wrote file " << filename << " to disk. It can now be read by running ./bin/hello_bpReader.\n";
     }
     catch (std::invalid_argument &e)
     {

/*
 * Distributed under the OSI-approved Apache License, Version 2.0.  See
 * accompanying file Copyright.txt for details.
 *
 * helloBPWriter_nompi.cpp sequential non-mpi version of helloBPWriter
 *
 *  Created on: Jan 9, 2017
 *      Author: William F Godoy godoywf@ornl.gov
 */

#include <ios>       //std::ios_base::failure
#include <iostream>  //std::cout
#include <stdexcept> //std::invalid_argument std::exception
#include <vector>

#include <adios2.h>

int main(int argc, char *argv[])
{
    /** Application variable */
    std::vector<float> myFloats = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    const std::size_t Nx = myFloats.size();

    try
    {
        /** ADIOS class factory of IO class objects, DebugON is recommended */
        adios2::ADIOS adios(adios2::DebugON);

        /*** IO class object: settings and factory of Settings: Variables,
         * Parameters, Transports, and Execution: Engines */
        adios2::IO bpIO = adios.DeclareIO("BPFile_N2N");

        /** global array: name, { shape (total dimensions) }, { start (local) },
         * { count (local) }, all are constant dimensions */
        adios2::Variable<float> bpFloats = bpIO.DefineVariable<float>(
            "bpFloats", {}, {}, {Nx}, adios2::ConstantDims);

        /** Engine derived class, spawned to start IO operations */
        adios2::Engine bpWriter =
            bpIO.Open("myVector_cpp.bp", adios2::Mode::Write);

        /** Write variable for buffering */
        bpWriter.Put<float>(bpFloats, myFloats.data());

        /** Create bp file, engine becomes unreachable after this*/
        bpWriter.Close();
    }
    catch (std::invalid_argument &e)
    {
        std::cout << "Invalid argument exception, STOPPING PROGRAM\n";
        std::cout << e.what() << "\n";
    }
    catch (std::ios_base::failure &e)
    {
        std::cout << "IO System base failure exception, STOPPING PROGRAM\n";
        std::cout << e.what() << "\n";
    }
    catch (std::exception &e)
    {
        std::cout << "Exception, STOPPING PROGRAM\n";
        std::cout << e.what() << "\n";
    }

    return 0;
}

Add an extra `catch(std::ios_base::failure &e) { ..// your extra error message }`


@@ -47,12 +47,13 @@

 namespace lbann {

-lbann_comm* initialize(int& argc, char**& argv, int seed) {
+world_comm_ptr initialize(int& argc, char**& argv, int seed) {
   // Initialize Elemental.
   El::Initialize(argc, argv);
   // Create a new comm object.
   // Initial creation with every process in one model.
-  auto* comm = new lbann_comm(0);
+  auto comm = world_comm_ptr{new lbann_comm(0), &lbann::finalize };
+
 #if defined(LBANN_TOPO_AWARE)
   // Determine the number of NUMA nodes present.
   hwloc_topology_t topo;

////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2014-2016, Lawrence Livermore National Security, LLC.
// Produced at the Lawrence Livermore National Laboratory.
// Written by the LBANN Research Team (B. Van Essen, et al.) listed in
// the CONTRIBUTORS file. <lbann-dev@llnl.gov>
//
// LLNL-CODE-697807.
// All rights reserved.
//
// This file is part of LBANN: Livermore Big Artificial Neural Network
// Toolkit. For details, see http://software.llnl.gov/LBANN or
// https://github.com/LLNL/LBANN.
//
// Licensed under the Apache License, Version 2.0 (the "Licensee"); 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.
//
// lbann_base .cpp - Basic definitions, functions
////////////////////////////////////////////////////////////////////////////////

#include "lbann/base.hpp"

#include <omp.h>
#if defined(LBANN_TOPO_AWARE)
#include <hwloc.h>
#if defined(HWLOC_API_VERSION) && (HWLOC_API_VERSION < 0x00010b00)
#define HWLOC_OBJ_NUMANODE HWLOC_OBJ_NODE
#endif
#endif

#include "lbann/comm.hpp"
#include "lbann/utils/random.hpp"
#include "lbann/utils/omp_diagnostics.hpp"
#include "lbann/utils/stack_trace.hpp"

#ifdef LBANN_HAS_CUDNN
#include "lbann/utils/cudnn.hpp"
#endif

namespace lbann {

lbann_comm* initialize(int& argc, char**& argv, int seed) {
  // Initialize Elemental.
  El::Initialize(argc, argv);
  // Create a new comm object.
  // Initial creation with every process in one model.
  auto* comm = new lbann_comm(0);
#if defined(LBANN_TOPO_AWARE)
  // Determine the number of NUMA nodes present.
  hwloc_topology_t topo;
  hwloc_topology_init(&topo);
  hwloc_topology_load(topo);
  int numa_depth = hwloc_get_type_depth(topo, HWLOC_OBJ_NUMANODE);
  if (numa_depth == HWLOC_TYPE_DEPTH_UNKNOWN) {
    std::cout << comm->get_rank_in_world() <<
              ": cannot determine hwloc NUMA-node depth" << std::endl;
  }
  int num_numa_nodes = hwloc_get_nbobjs_by_depth(topo, numa_depth);
  // Warn if there are more NUMA nodes than processes per node.
  // It's probably fine if there are more processes than NUMA nodes for now.
  // We can adjust that later when we better understand the threaded perf.
  int ppn = comm->get_procs_per_node();
  if (num_numa_nodes > ppn) {
    if (comm->get_rank_in_node() == 0) {
      std::cout << comm->get_rank_in_world() <<
                ": WARNING: node has " << num_numa_nodes <<
                " NUMA nodes but you have " << ppn << " processes per node" <<
                std::endl;
    }
  }
  hwloc_topology_destroy(topo);
#endif
  // Initialize local random number generators.
  init_random(seed);
  init_data_seq_random(seed);

  return comm;
}

void finalize(lbann_comm* comm) {
#ifdef LBANN_HAS_CUDNN
  cudnn::destroy();
#endif
  if (comm != nullptr) {
    delete comm;
  }
  El::Finalize();
}

/** hack to avoid long switch/case statement; users should ignore; of interest to developers */
static std::vector<std::string> pool_mode_names = { "invalid", "max", "average", "average_no_pad" };

/** returns a string representation of the pool_mode */
std::string get_pool_mode_name(pool_mode m) {
  if ((int)m < 1 or (int)m >= (int)pool_mode_names.size()) {
    throw(std::string{} + __FILE__ + " " + std::to_string(__LINE__) + " :: "
          + " Invalid pool_mode");
  }
  return pool_mode_names[(int)m];
}

} // namespace lbann

Should we be doing this with `make_unique` or something?


@@ -15,6 +15,10 @@ ExecutionContext::~ExecutionContext() {
         sm_ = nullptr;
     }

+    if (nullptr != gflagsManager_) {
+        gflagsManager_ = nullptr;
+    }
+
     if (nullptr != storage_) {
         storage_ = nullptr;
     }

/* Copyright (c) 2018 vesoft inc. All rights reserved.
 *
 * This source code is licensed under Apache 2.0 License,
 * attached with Common Clause Condition 1.0, found in the LICENSES directory.
 */

#include "base/Base.h"
#include "graph/ExecutionContext.h"

namespace nebula {
namespace graph {

ExecutionContext::~ExecutionContext() {
    if (nullptr != sm_) {
        sm_ = nullptr;
    }

    if (nullptr != storage_) {
        storage_ = nullptr;
    }

    if (nullptr != metaClient_) {
        metaClient_ = nullptr;
    }
}

}   // namespace graph
}   // namespace nebula


@@ -22,8 +22,8 @@
 #include "depotchest.h"
 #include "tools.h"

-DepotChest::DepotChest(uint16_t type) :
-	Container(type), maxDepotItems(2000) {}
+DepotChest::DepotChest(uint16_t type, bool paginated /*= true*/) :
+	Container(type, items[type].maxItems, true, paginated), maxDepotItems(2000) {}

 ReturnValue DepotChest::queryAdd(int32_t index, const Thing& thing, uint32_t count,
 		uint32_t flags, Creature* actor/* = nullptr*/) const

/**
 * The Forgotten Server - a free and open-source MMORPG server emulator
 * Copyright (C) 2019  Mark Samman <mark.samman@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "otpch.h"

#include "depotchest.h"
#include "tools.h"

DepotChest::DepotChest(uint16_t type) :
	Container(type), maxDepotItems(2000) {}

ReturnValue DepotChest::queryAdd(int32_t index, const Thing& thing, uint32_t count,
		uint32_t flags, Creature* actor/* = nullptr*/) const
{
	const Item* item = thing.getItem();
	if (!item) {
		return RETURNVALUE_NOTPOSSIBLE;
	}

	bool skipLimit = hasBitSet(FLAG_NOLIMIT, flags);
	if (!skipLimit) {
		int32_t addCount = 0;

		if ((item->isStackable() && item->getItemCount() != count)) {
			addCount = 1;
		}

		if (item->getTopParent() != this) {
			if (const Container* container = item->getContainer()) {
				addCount = container->getItemHoldingCount() + 1;
			} else {
				addCount = 1;
			}
		}

		if (getItemHoldingCount() + addCount > maxDepotItems) {
			return RETURNVALUE_DEPOTISFULL;
		}
	}

	return Container::queryAdd(index, thing, count, flags, actor);
}

void DepotChest::postAddNotification(Thing* thing, const Cylinder* oldParent, int32_t index, cylinderlink_t)
{
	Cylinder* parent = getParent();
	if (parent) {
		parent->postAddNotification(thing, oldParent, index, LINK_PARENT);
	}
}

void DepotChest::postRemoveNotification(Thing* thing, const Cylinder* newParent, int32_t index, cylinderlink_t)
{
	Cylinder* parent = getParent();
	if (parent) {
		parent->postRemoveNotification(thing, newParent, index, LINK_PARENT);
	}
}

Cylinder* DepotChest::getParent() const
{
	if (parent) {
		return parent->getParent();
	}
	return nullptr;
}


@@ -38,17 +38,14 @@ namespace interface2
  * \DAAL_DEPRECATED_USE{ Model::create }
  */
 template <typename modelFPType>
-DAAL_EXPORT Model::Model(size_t nFeatures, modelFPType dummy) :
-    _nFeatures(nFeatures),
-    _models(new data_management::DataCollection())
+DAAL_EXPORT Model::Model(size_t nFeatures, modelFPType dummy) : _nFeatures(nFeatures), _models(new data_management::DataCollection())
 {
     _alpha = data_management::NumericTablePtr(new data_management::HomogenNumericTable<modelFPType>(NULL, 1, 0));
 }

 template <typename modelFPType>
-DAAL_EXPORT Model::Model(size_t nFeatures, modelFPType dummy, services::Status &st) :
-    _nFeatures(nFeatures),
-    _models(new data_management::DataCollection())
+DAAL_EXPORT Model::Model(size_t nFeatures, modelFPType dummy, services::Status & st)
+    : _nFeatures(nFeatures), _models(new data_management::DataCollection())
 {
     if (!_models) { st.add(services::ErrorMemoryAllocationFailed); }
     _alpha = data_management::HomogenNumericTable<modelFPType>::create(NULL, 1, 0, &st);

/* file: adaboost_model_fpt.cpp */
/*******************************************************************************
* Copyright 2014-2019 Intel Corporation
*
* Licensed 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.
*******************************************************************************/

/*
//++
//  Implementation of class defining Ada Boost model
//--
*/

#include "algorithms/boosting/adaboost_model.h"

namespace daal
{
namespace algorithms
{
namespace adaboost
{
namespace interface2
{
/**
 * Constructs the AdaBoost model
 * \tparam modelFPType  Data type to store AdaBoost model data, double or float
 * \param[in] dummy     Dummy variable for the templated constructor
 * \DAAL_DEPRECATED_USE{ Model::create }
 */
template <typename modelFPType>
DAAL_EXPORT Model::Model(size_t nFeatures, modelFPType dummy) :
    _nFeatures(nFeatures),
    _models(new data_management::DataCollection())
{
    _alpha = data_management::NumericTablePtr(new data_management::HomogenNumericTable<modelFPType>(NULL, 1, 0));
}

template <typename modelFPType>
DAAL_EXPORT Model::Model(size_t nFeatures, modelFPType dummy, services::Status &st) :
    _nFeatures(nFeatures),
    _models(new data_management::DataCollection())
{
    if (!_models) { st.add(services::ErrorMemoryAllocationFailed); }
    _alpha = data_management::HomogenNumericTable<modelFPType>::create(NULL, 1, 0, &st);
}

/**
 * Constructs the AdaBoost model
 * \tparam modelFPType   Data type to store AdaBoost model data, double or float
 * \param[in]  nFeatures Number of features in the dataset
 * \param[out] stat      Status of the model construction
 */
template<typename modelFPType>
DAAL_EXPORT ModelPtr Model::create(size_t nFeatures, services::Status *stat)
{
    DAAL_DEFAULT_CREATE_IMPL_EX(Model, nFeatures, (modelFPType)0 /* dummy */);
}

template DAAL_EXPORT Model::Model(size_t, DAAL_FPTYPE);
template DAAL_EXPORT Model::Model(size_t, DAAL_FPTYPE, services::Status &);
template DAAL_EXPORT ModelPtr Model::create<DAAL_FPTYPE>(size_t, services::Status *);

}// namespace interface2
}// namespace adaboost
}// namespace algorithms
}// namespace daal

why here we have initialization in one row, but in algorithms/kernel/adaboost/adaboost_model.cpp on separate rows?


@@ -132,6 +132,7 @@ static train_result<Task> call_daal_kernel(const context_cpu& ctx,
         daal::services::internal::hostApp(daal_input),
         daal_data.get(),
         daal_labels.get(),
+        nullptr, // no weights
         *mptr,
         daal_result,
         daal_parameter));

/*******************************************************************************
* Copyright 2020 Intel Corporation
*
* Licensed 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.
*******************************************************************************/

#include <daal/include/services/error_handling.h>
#include <daal/src/algorithms/dtrees/forest/classification/df_classification_model_impl.h>
#include <daal/src/services/service_algo_utils.h>

#include <daal/include/algorithms/decision_forest/decision_forest_classification_training_batch.h>
#include <daal/include/algorithms/decision_forest/decision_forest_classification_training_types.h>

#include <daal/src/algorithms/dtrees/forest/classification/df_classification_train_kernel.h>
//to prevent reordering by clang-format
#include <daal/src/algorithms/dtrees/forest/classification/df_classification_train_dense_default_kernel.h>

#include "oneapi/dal/algo/decision_forest/backend/cpu/train_kernel.hpp"
#include "oneapi/dal/algo/decision_forest/backend/interop_helpers.hpp"
#include "oneapi/dal/backend/interop/common.hpp"
#include "oneapi/dal/backend/interop/error_converter.hpp"
#include "oneapi/dal/backend/interop/table_conversion.hpp"
#include "oneapi/dal/detail/common.hpp"

#include "oneapi/dal/table/row_accessor.hpp"

namespace oneapi::dal::decision_forest::backend {

using dal::backend::context_cpu;

namespace df = daal::algorithms::decision_forest;
namespace cls = daal::algorithms::decision_forest::classification;

namespace interop = dal::backend::interop;
namespace df_interop = dal::backend::interop::decision_forest;

template <typename Float, daal::CpuType Cpu>
using cls_dense_kernel_t = cls::training::internal::
    ClassificationTrainBatchKernel<Float, cls::training::defaultDense, Cpu>;

using cls_model_p = cls::ModelPtr;

template <typename Float, typename Task>
static train_result<Task> call_daal_kernel(const context_cpu& ctx,
                                           const descriptor_base<Task>& desc,
                                           const table& data,
                                           const table& labels) {
    const int64_t row_count = data.get_row_count();
    const int64_t column_count = data.get_column_count();

    auto arr_data = row_accessor<const Float>{ data }.pull();
    auto arr_label = row_accessor<const Float>{ labels }.pull();

    const auto daal_data =
        interop::convert_to_daal_homogen_table(arr_data, row_count, column_count);
    const auto daal_labels = interop::convert_to_daal_homogen_table(arr_label, row_count, 1);

    /* init param for daal kernel */
    auto daal_input = daal::algorithms::classifier::training::Input();
    daal_input.set(daal::algorithms::classifier::training::data, daal_data);
    daal_input.set(daal::algorithms::classifier::training::labels, daal_labels);

    auto daal_parameter = cls::training::Parameter(desc.get_class_count());
    daal_parameter.nTrees = desc.get_tree_count();
    daal_parameter.observationsPerTreeFraction = desc.get_observations_per_tree_fraction();
    daal_parameter.featuresPerNode = desc.get_features_per_node();
    daal_parameter.maxTreeDepth = desc.get_max_tree_depth();
    daal_parameter.minObservationsInLeafNode = desc.get_min_observations_in_leaf_node();
    // TODO take engines from desc
    daal_parameter.engine = daal::algorithms::engines::mt2203::Batch<>::create();
    daal_parameter.impurityThreshold = desc.get_impurity_threshold();
    daal_parameter.memorySavingMode = desc.get_memory_saving_mode();
    daal_parameter.bootstrap = desc.get_bootstrap();
    daal_parameter.minObservationsInSplitNode = desc.get_min_observations_in_split_node();
    daal_parameter.minWeightFractionInLeafNode = desc.get_min_weight_fraction_in_leaf_node();
    daal_parameter.minImpurityDecreaseInSplitNode = desc.get_min_impurity_decrease_in_split_node();
    daal_parameter.maxLeafNodes = desc.get_max_leaf_nodes();

    daal_parameter.resultsToCompute = static_cast<std::uint64_t>(desc.get_error_metric_mode());

    auto vimp = desc.get_variable_importance_mode();

    daal_parameter.varImportance = df_interop::convert_to_daal_variable_importance_mode(vimp);

    train_result<Task> res;

    auto daal_result = cls::training::Result();

    /* init daal result's objects */
    if (check_mask_flag(desc.get_error_metric_mode(), error_metric_mode::out_of_bag_error)) {
        auto arr_oob_err = array<Float>::empty(1 * 1);
        res.set_oob_err(dal::detail::homogen_table_builder{}.reset(arr_oob_err, 1, 1).build());

        const auto res_oob_err = interop::convert_to_daal_homogen_table(arr_oob_err, 1, 1);
        daal_result.set(cls::training::outOfBagError, res_oob_err);
    }

    if (check_mask_flag(desc.get_error_metric_mode(),
                        error_metric_mode::out_of_bag_error_per_observation)) {
        auto arr_oob_per_obs_err = array<Float>::empty(row_count * 1);
        res.set_oob_err_per_observation(
            dal::detail::homogen_table_builder{}.reset(arr_oob_per_obs_err, row_count, 1).build());

        const auto res_oob_per_obs_err =
            interop::convert_to_daal_homogen_table(arr_oob_per_obs_err, row_count, 1);
        daal_result.set(cls::training::outOfBagErrorPerObservation, res_oob_per_obs_err);
    }
    if (variable_importance_mode::none != vimp) {
        auto arr_var_imp = array<Float>::empty(1 * column_count);
        res.set_var_importance(
            dal::detail::homogen_table_builder{}.reset(arr_var_imp, 1, column_count).build());

        const auto res_var_imp =
            interop::convert_to_daal_homogen_table(arr_var_imp, 1, column_count);
        daal_result.set(cls::training::variableImportance, res_var_imp);
    }

    cls::ModelPtr mptr = cls::ModelPtr(new cls::internal::ModelImpl(column_count));

    interop::status_to_exception(interop::call_daal_kernel<Float, cls_dense_kernel_t>(
        ctx,
        daal::services::internal::hostApp(daal_input),
        daal_data.get(),
        daal_labels.get(),
        *mptr,
        daal_result,
        daal_parameter));

    /* extract results from daal objects */
    if (check_mask_flag(desc.get_error_metric_mode(), error_metric_mode::out_of_bag_error)) {
        auto table_oob_err = interop::convert_from_daal_homogen_table<Float>(
            daal_result.get(cls::training::outOfBagError));
        res.set_oob_err(table_oob_err);
    }

    if (check_mask_flag(desc.get_error_metric_mode(),
                        error_metric_mode::out_of_bag_error_per_observation)) {
        auto table_oob_per_obs_err = interop::convert_from_daal_homogen_table<Float>(
            daal_result.get(cls::training::outOfBagErrorPerObservation));
        res.set_oob_err_per_observation(table_oob_per_obs_err);
    }

    if (variable_importance_mode::none != vimp) {
        auto table_var_imp = interop::convert_from_daal_homogen_table<Float>(
            daal_result.get(cls::training::variableImportance));
        res.set_var_importance(table_var_imp);
    }

    return res.set_model(dal::detail::pimpl_accessor().make_from_pimpl<model<Task>>(
        std::make_shared<interop::decision_forest::interop_model_impl<Task, cls_model_p>>(mptr)));
}

template <typename Float, typename Task>
static train_result<Task> train(const context_cpu& ctx,
                                const descriptor_base<Task>& desc,
                                const train_input<Task>& input) {
    return call_daal_kernel<Float>(ctx, desc, input.get_data(), input.get_labels());
}

template <typename Float, typename Task>
struct train_kernel_cpu<Float, Task, method::dense> {
    train_result<Task> operator()(const context_cpu& ctx,
                                  const descriptor_base<Task>& desc,
                                  const train_input<Task>& input) const {
        return train<Float, Task>(ctx, desc, input);
    }
};

template struct train_kernel_cpu<float, task::classification, method::dense>;
template struct train_kernel_cpu<double, task::classification, method::dense>;

} // namespace oneapi::dal::decision_forest::backend

Please add full weights setting/getting support for train input, thus it can be used here instead of nullptr


@@ -55,10 +55,43 @@ static train_result call_daal_kernel(const context_gpu& ctx,
     auto arr_data  = row_accessor<const Float>{ data }.pull(queue);
     auto arr_label = row_accessor<const Float>{ labels }.pull(queue);

+    // TODO: make for dpcpp kernel
+    auto arr_new_label = array<Float>::empty(queue, row_count * 1);
+    arr_label.need_mutable_data(queue);
+    Float value_first_class_label  = arr_label[0];
+    Float value_second_class_label = arr_label[1];
+
+    arr_new_label[0] = Float(-1.0);
+    std::int64_t i   = 1;
+    for (; i < row_count; ++i) {
+        if (arr_label[i] == value_first_class_label) {
+            arr_new_label[i] = Float(-1.0);
+        }
+        else {
+            value_second_class_label = arr_label[i];
+            arr_new_label[i]         = Float(+1.0);
+        }
+    }
+    if (value_first_class_label == value_second_class_label) {
+        throw invalid_argument("Input label data should have more one unique label");
+    }
+
+    for (; i < row_count; ++i) {
+        if (arr_label[i] == value_first_class_label) {
+            arr_new_label[i] = Float(-1.0);
+        }
+        else if (arr_label[i] == value_second_class_label) {
+            arr_new_label[i] = Float(+1.0);
+        }
+        else {
+            throw invalid_argument("Input label data should have only two unique labels");
+        }
+    }
+
     const auto daal_data =
         interop::convert_to_daal_sycl_homogen_table(queue, arr_data, row_count, column_count);
     const auto daal_labels =
-        interop::convert_to_daal_sycl_homogen_table(queue, arr_label, row_count, 1);
+        interop::convert_to_daal_sycl_homogen_table(queue, arr_new_label, row_count, 1);

     auto kernel_impl       = desc.get_kernel_impl()->get_impl();
     const auto daal_kernel = kernel_impl->get_daal_kernel_function();

/*******************************************************************************
* Copyright 2020 Intel Corporation
*
* Licensed 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.
*******************************************************************************/

#define DAAL_SYCL_INTERFACE
#define DAAL_SYCL_INTERFACE_USM
#define DAAL_SYCL_INTERFACE_REVERSED_RANGE

#include "oneapi/dal/algo/svm/backend/gpu/train_kernel.hpp"
#include "oneapi/dal/algo/svm/backend/interop_model.hpp"
#include "oneapi/dal/algo/svm/backend/kernel_function_impl.hpp"
#include "oneapi/dal/backend/interop/common_dpc.hpp"
#include "oneapi/dal/backend/interop/error_converter.hpp"
#include "oneapi/dal/backend/interop/table_conversion.hpp"

#include <daal/src/algorithms/svm/oneapi/svm_train_thunder_kernel_oneapi.h>

namespace oneapi::dal::svm::backend {

using std::int64_t;
using dal::backend::context_gpu;

namespace daal_svm             = daal::algorithms::svm;
namespace daal_kernel_function = daal::algorithms::kernel_function;
namespace interop              = dal::backend::interop;

template <typename Float>
using daal_svm_thunder_kernel_t = daal_svm::training::internal::
    SVMTrainOneAPI<Float, daal_svm::Parameter, daal_svm::training::thunder>;

template <typename Float>
static train_result call_daal_kernel(const context_gpu& ctx,
                                     const descriptor_base& desc,
                                     const table& data,
                                     const table& labels) {
    auto& queue = ctx.get_queue();
    interop::execution_context_guard guard(queue);

    const int64_t row_count    = data.get_row_count();
    const int64_t column_count = data.get_column_count();

    // TODO: data is table, not a homogen_table. Think better about accessor - is it enough to have just a row_accessor?
    auto arr_data  = row_accessor<const Float>{ data }.pull(queue);
    auto arr_label = row_accessor<const Float>{ labels }.pull(queue);

    const auto daal_data =
        interop::convert_to_daal_sycl_homogen_table(queue, arr_data, row_count, column_count);
    const auto daal_labels =
        interop::convert_to_daal_sycl_homogen_table(queue, arr_label, row_count, 1);

    auto kernel_impl       = desc.get_kernel_impl()->get_impl();
    const auto daal_kernel = kernel_impl->get_daal_kernel_function();
    daal_svm::Parameter daal_parameter(
        daal_kernel,
        desc.get_c(),
        desc.get_accuracy_threshold(),
        desc.get_tau(),
        desc.get_max_iteration_count(),
        int64_t(desc.get_cache_size() * 1024 * 1024), // DAAL get in bytes
        desc.get_shrinking());

    auto daal_model = daal_svm::Model::create<Float>(column_count);
    interop::status_to_exception(daal_svm_thunder_kernel_t<Float>().compute(daal_data,
                                                                            *daal_labels,
                                                                            daal_model.get(),
                                                                            &daal_parameter));
    auto table_support_indices =
        interop::convert_from_daal_homogen_table<Float>(daal_model->getSupportIndices());

    return train_result()
        .set_model(convert_from_daal_model<Float>(*daal_model))
        .set_support_indices(table_support_indices);
}

template <typename Float>
static train_result train(const context_gpu& ctx,
                          const descriptor_base& desc,
                          const train_input& input) {
    return call_daal_kernel<Float>(ctx, desc, input.get_data(), input.get_labels());
}

template <typename Float>
struct train_kernel_gpu<Float, task::classification, method::thunder> {
    train_result operator()(const dal::backend::context_gpu& ctx,
                            const descriptor_base& desc,
                            const train_input& input) const {
        return train<Float>(ctx, desc, input);
    }
};

template struct train_kernel_gpu<float, task::classification, method::thunder>;
template struct train_kernel_gpu<double, task::classification, method::thunder>;

} // namespace oneapi::dal::svm::backend

You can use the method extracted earlier in CPU backend rather than copy-paste


@@ -42,6 +42,22 @@ DEFINE_int32(rocksdb_batch_size,
 DEFINE_string(part_man_type,
               "memory",
               "memory, meta");
+
+static bool validateRocksdbStatsLevel(const char* flagname, int value) {
+    if (value < rocksdb::StatsLevel::kAll && value >= 0) {
+        return true;
+    }
+
+    VLOG(3) << "Invalid value for --" << flagname << ": " << value;
+    return false;
+}
+
+DEFINE_int32(rocksdb_stats_level, 0,
+             "Statistics Level for RocksDB. Default is 0 (kExceptHistogramOrTimers)");
+DEFINE_validator(rocksdb_stats_level, &validateRocksdbStatsLevel);
+
+DEFINE_int32(rocksdb_stats_dump_period_sec, 0, "DBOptions::stats_dump_period_sec for RocksDB");
+
 /*
  * For these un-supported string options as below, will need to specify them with gflag.
  */

/* Copyright (c) 2018 vesoft inc. All rights reserved.
 *
 * This source code is licensed under Apache 2.0 License,
 * attached with Common Clause Condition 1.0, found in the LICENSES directory.
 */

#include "base/Base.h"
#include "kvstore/RocksEngineConfig.h"
#include "rocksdb/db.h"
#include "rocksdb/cache.h"
#include "rocksdb/convenience.h"
#include "rocksdb/utilities/options_util.h"
#include "rocksdb/slice_transform.h"

// [WAL]
DEFINE_bool(rocksdb_disable_wal,
            false,
            "Whether to disable the WAL in rocksdb");

// [DBOptions]
DEFINE_string(rocksdb_db_options,
              "",
              "DBOptions, each option will be given "
              "as <option_name>:<option_value> separated by ;");

// [CFOptions "default"]
DEFINE_string(rocksdb_column_family_options,
              "",
              "ColumnFamilyOptions, each option will be given "
              "as <option_name>:<option_value> separated by ;");

//  [TableOptions/BlockBasedTable "default"]
DEFINE_string(rocksdb_block_based_table_options,
              "",
              "BlockBasedTableOptions, each option will be given "
              "as <option_name>:<option_value> separated by ;");

DEFINE_int32(rocksdb_batch_size,
             4 * 1024,
             "default reserved bytes for one batch operation");

DEFINE_string(part_man_type,
              "memory",
              "memory, meta");
/*
 * For these un-supported string options as below, will need to specify them with gflag.
 */

// BlockBasedTable block_cache
DEFINE_int64(rocksdb_block_cache, 4,
             "The default block cache size used in BlockBasedTable. The unit is MB");

namespace nebula {
namespace kvstore {

rocksdb::Status initRocksdbOptions(rocksdb::Options &baseOpts) {
    rocksdb::Status s;
    rocksdb::DBOptions dbOpts;
    rocksdb::ColumnFamilyOptions cfOpts;
    rocksdb::BlockBasedTableOptions bbtOpts;
    s = GetDBOptionsFromString(rocksdb::DBOptions(),
            FLAGS_rocksdb_db_options, &dbOpts);
    if (!s.ok()) {
        return s;
    }

    s = GetColumnFamilyOptionsFromString(rocksdb::ColumnFamilyOptions(),
            FLAGS_rocksdb_column_family_options, &cfOpts);

    if (!s.ok()) {
        return s;
    }

    baseOpts = rocksdb::Options(dbOpts, cfOpts);

    s = GetBlockBasedTableOptionsFromString(rocksdb::BlockBasedTableOptions(),
            FLAGS_rocksdb_block_based_table_options, &bbtOpts);

    if (!s.ok()) {
        return s;
    }

    bbtOpts.block_cache = rocksdb::NewLRUCache(FLAGS_rocksdb_block_cache * 1024 * 1024);
    baseOpts.table_factory.reset(NewBlockBasedTableFactory(bbtOpts));
    baseOpts.create_if_missing = true;
    return s;
}

}  // namespace kvstore
}  // namespace nebula

I remember this option only control the interval for dumping stats into the LOG file, and if we want to get the stats in string, need to call `db->GetProperty()` to get the string version.