@@ -52,11 +52,18 @@ class EditableMol : boost::noncopyable {
     PRECONDITION(atom, "bad atom");
     return dp_mol->addAtom(atom, true, false);
   };
-  void ReplaceAtom(unsigned int idx, Atom *atom) {
+  void ReplaceAtom(unsigned int idx, Atom *atom,
+                   bool updateLabels, bool preserveProps) {
     PRECONDITION(dp_mol, "no molecule");
     PRECONDITION(atom, "bad atom");
-    dp_mol->replaceAtom(idx, atom);
+    dp_mol->replaceAtom(idx, atom, updateLabels, preserveProps);
   };
+  void ReplaceBond(unsigned int idx, Bond *bond, bool preserveProps) {
+    PRECONDITION(dp_mol, "no molecule");
+    PRECONDITION(bond, "bad bond");
+    dp_mol->replaceBond(idx, bond, preserveProps);
+  };
+
   ROMol *GetMol() const {
     PRECONDITION(dp_mol, "no molecule");
     ROMol *res = new ROMol(*dp_mol);

// $Id$
//
//  Copyright (C) 2007 Greg Landrum
//
//   @@ 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.
//
// there's a compiler bug in some versions of g++ that causes this file to not
// compile unless
// we skip the docstrings:
//#define BOOST_PYTHON_NO_PY_SIGNATURES

#define NO_IMPORT_ARRAY
#include <RDBoost/python.h>
#include <string>

#include "rdchem.h"
// ours
#include <GraphMol/RDKitBase.h>

namespace python = boost::python;

namespace RDKit {

namespace {
class EditableMol : boost::noncopyable {
 public:
  EditableMol(const ROMol &m) { dp_mol = new RWMol(m); };
  ~EditableMol() {
    PRECONDITION(dp_mol, "no molecule");
    delete dp_mol;
  };

  void RemoveAtom(unsigned int idx) {
    PRECONDITION(dp_mol, "no molecule");
    dp_mol->removeAtom(idx);
  };
  void RemoveBond(unsigned int idx1, unsigned int idx2) {
    PRECONDITION(dp_mol, "no molecule");
    dp_mol->removeBond(idx1, idx2);
  };
  int AddBond(unsigned int begAtomIdx, unsigned int endAtomIdx,
              Bond::BondType order = Bond::UNSPECIFIED) {
    PRECONDITION(dp_mol, "no molecule");
    return dp_mol->addBond(begAtomIdx, endAtomIdx, order);
  };
  int AddAtom(Atom *atom) {
    PRECONDITION(dp_mol, "no molecule");
    PRECONDITION(atom, "bad atom");
    return dp_mol->addAtom(atom, true, false);
  };
  void ReplaceAtom(unsigned int idx, Atom *atom) {
    PRECONDITION(dp_mol, "no molecule");
    PRECONDITION(atom, "bad atom");
    dp_mol->replaceAtom(idx, atom);
  };
  ROMol *GetMol() const {
    PRECONDITION(dp_mol, "no molecule");
    ROMol *res = new ROMol(*dp_mol);
    return res;
  };

 private:
  RWMol *dp_mol;
};
}

struct EditableMol_wrapper {
  static void wrap() {
    std::string molClassDoc =
        "The EditableMol class.\n\n\
   This class can be used to add/remove bonds and atoms to\n\
   a molecule.\n\
   In order to use it, you need to first construct an EditableMol\n\
   from a standard Mol:\n\
   >>> m = Chem.MolFromSmiles('CCC')\n\
   >>> em = Chem.EditableMol(m)\n\
   >>> em.AddAtom(Chem.Atom(8))\n\
   >>> em.AddBond(0,3,Chem.BondType.SINGLE)\n\
   >>> m2 = em.GetMol()\n\
   >>> Chem.SanitizeMol(m2)\n\
   >>> Chem.MolToSmiles(m2)\n\
   'CCCO'\n\
\n\
   *Note*: It is very, very easy to shoot yourself in the foot with\n\
           this class by constructing an unreasonable molecule.\n\
";
    python::class_<EditableMol, boost::noncopyable>(
        "EditableMol", "an editable molecule class",
        python::init<const ROMol &>("Construct from a Mol"))
        .def("RemoveAtom", &EditableMol::RemoveAtom,
             "Remove the specified atom from the molecule")
        .def("RemoveBond", &EditableMol::RemoveBond,
             "Remove the specified bond from the molecule")

        .def("AddBond", &EditableMol::AddBond,
             (python::arg("mol"), python::arg("beginAtomIdx"),
              python::arg("endAtomIdx"),
              python::arg("order") = Bond::UNSPECIFIED),
             "add a bond, returns the index of the newly added bond")

        .def("AddAtom", &EditableMol::AddAtom,
             (python::arg("mol"), python::arg("atom")),
             "add an atom, returns the index of the newly added atom")
        .def("ReplaceAtom", &EditableMol::ReplaceAtom,
             (python::arg("mol"), python::arg("index"), python::arg("newAtom")),
             "replaces the specified atom with the provided one")
        .def("GetMol", &EditableMol::GetMol,
             "Returns a Mol (a normal molecule)",
             python::return_value_policy<python::manage_new_object>());
  };
};

}  // end of namespace
void wrap_EditableMol() { RDKit::EditableMol_wrapper::wrap(); }


@@ -167,13 +167,18 @@ void SYCLInternal::initialize(const sycl::queue& q) {
 void SYCLInternal::finalize() {
   SYCL().fence();
   was_finalized = true;
-  if (nullptr != m_scratchSpace || nullptr != m_scratchFlags) {
-    // FIXME_SYCL
-    std::abort();
-  }

-  using RecordSYCL =
-      Kokkos::Impl::SharedAllocationRecord<Experimental::SYCLDeviceUSMSpace>;
+  using RecordSYCL = Kokkos::Impl::SharedAllocationRecord<SYCLDeviceUSMSpace>;
+  if (nullptr != m_scratchSpace)
+    RecordSYCL::decrement(RecordSYCL::get_record(m_scratchSpace));
+  if (nullptr != m_scratchFlags)
+    RecordSYCL::decrement(RecordSYCL::get_record(m_scratchFlags));
+  m_syclDev           = -1;
+  m_scratchSpaceCount = 0;
+  m_scratchSpace      = nullptr;
+  m_scratchFlagsCount = 0;
+  m_scratchFlags      = nullptr;
+
   RecordSYCL::decrement(RecordSYCL::get_record(m_scratchConcurrentBitset));
   m_scratchConcurrentBitset = nullptr;

/*
//@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_Concepts.hpp>
#include <SYCL/Kokkos_SYCL_Instance.hpp>
#include <KokkosCore_Config_DeclareBackend.hpp>
#include <Kokkos_SYCL.hpp>
#include <Kokkos_HostSpace.hpp>
#include <Kokkos_Serial.hpp>
#include <impl/Kokkos_ConcurrentBitset.hpp>
#include <impl/Kokkos_Error.hpp>

namespace Kokkos {
namespace Experimental {
namespace Impl {

std::vector<std::optional<sycl::queue>*> SYCLInternal::all_queues;
std::mutex SYCLInternal::mutex;

SYCLInternal::~SYCLInternal() {
  if (!was_finalized || m_scratchSpace || m_scratchFlags ||
      m_scratchConcurrentBitset) {
    std::cerr << "Kokkos::Experimental::SYCL ERROR: Failed to call "
                 "Kokkos::Experimental::SYCL::finalize()"
              << std::endl;
    std::cerr.flush();
  }
}

int SYCLInternal::verify_is_initialized(const char* const label) const {
  if (!is_initialized()) {
    std::cerr << "Kokkos::Experimental::SYCL::" << label
              << " : ERROR device not initialized" << std::endl;
  }
  return is_initialized();
}
SYCLInternal& SYCLInternal::singleton() {
  static SYCLInternal self;
  return self;
}

void SYCLInternal::initialize(const sycl::device& d) {
  auto exception_handler = [](sycl::exception_list exceptions) {
    bool asynchronous_error = false;
    for (std::exception_ptr const& e : exceptions) {
      try {
        std::rethrow_exception(e);
      } catch (sycl::exception const& e) {
        std::cerr << e.what() << '\n';
        asynchronous_error = true;
      }
    }
    if (asynchronous_error)
      Kokkos::Impl::throw_runtime_exception(
          "There was an asynchronous SYCL error!\n");
  };
  initialize(sycl::queue{d, exception_handler});
}

// FIXME_SYCL
void SYCLInternal::initialize(const sycl::queue& q) {
  if (was_finalized)
    Kokkos::abort("Calling SYCL::initialize after SYCL::finalize is illegal\n");

  if (is_initialized()) return;

  if (!HostSpace::execution_space::impl_is_initialized()) {
    const std::string msg(
        "SYCL::initialize ERROR : HostSpace::execution_space is not "
        "initialized");
    Kokkos::Impl::throw_runtime_exception(msg);
  }

  const bool ok_init = nullptr == m_scratchSpace || nullptr == m_scratchFlags;
  const bool ok_dev  = true;
  if (ok_init && ok_dev) {
    m_queue = q;
    // guard pushing to all_queues
    {
      std::lock_guard<std::mutex> lock(mutex);
      all_queues.push_back(&m_queue);
    }
    const sycl::device& d = m_queue->get_device();
    std::cout << SYCL::SYCLDevice(d) << '\n';

    m_maxWorkgroupSize =
        d.template get_info<sycl::info::device::max_work_group_size>();
    // FIXME_SYCL this should give the correct value for NVIDIA GPUs
    m_maxConcurrency =
        m_maxWorkgroupSize * 2 *
        d.template get_info<sycl::info::device::max_compute_units>();

    // Setup concurent bitset for obtaining unique tokens from within an
    // executing kernel.
    {
      const int32_t buffer_bound =
          Kokkos::Impl::concurrent_bitset::buffer_bound(m_maxConcurrency);
      using Record = Kokkos::Impl::SharedAllocationRecord<
          Kokkos::Experimental::SYCLDeviceUSMSpace, void>;
      Record* const r =
          Record::allocate(Kokkos::Experimental::SYCLDeviceUSMSpace(),
                           "Kokkos::SYCL::InternalScratchBitset",
                           sizeof(uint32_t) * buffer_bound);
      Record::increment(r);
      m_scratchConcurrentBitset = reinterpret_cast<uint32_t*>(r->data());
      auto event                = m_queue->memset(m_scratchConcurrentBitset, 0,
                                   sizeof(uint32_t) * buffer_bound);
      fence(event);
    }

    m_maxShmemPerBlock =
        d.template get_info<sycl::info::device::local_mem_size>();
    m_indirectKernelMem.reset(*m_queue);
    m_indirectReducerMem.reset(*m_queue);
  } else {
    std::ostringstream msg;
    msg << "Kokkos::Experimental::SYCL::initialize(...) FAILED";

    if (!ok_init) {
      msg << " : Already initialized";
    }
    Kokkos::Impl::throw_runtime_exception(msg.str());
  }
}

void SYCLInternal::finalize() {
  SYCL().fence();
  was_finalized = true;
  if (nullptr != m_scratchSpace || nullptr != m_scratchFlags) {
    // FIXME_SYCL
    std::abort();
  }

  using RecordSYCL =
      Kokkos::Impl::SharedAllocationRecord<Experimental::SYCLDeviceUSMSpace>;
  RecordSYCL::decrement(RecordSYCL::get_record(m_scratchConcurrentBitset));
  m_scratchConcurrentBitset = nullptr;

  m_indirectKernelMem.reset();
  m_indirectReducerMem.reset();
  // guard erasing from all_queues
  {
    std::lock_guard<std::mutex> lock(mutex);
    all_queues.erase(std::find(all_queues.begin(), all_queues.end(), &m_queue));
  }
  m_queue.reset();
}

}  // namespace Impl
}  // namespace Experimental
}  // namespace Kokkos


@@ -91,8 +91,21 @@ void StorageHttpIngestHandler::onError(ProxygenError error) noexcept {
                << proxygen::getErrorString(error);
 }

-bool StorageHttpIngestHandler::ingestSSTFiles(GraphSpaceID space) {
-    auto code = kvstore_->ingest(space);
+bool StorageHttpIngestHandler::ingestSSTFiles() {
+    kvstore::ResultCode code;
+    if (edge_.has_value()) {
+        LOG(INFO) << folly::stringPrintf(
+            "ingest space %d edge %d", spaceID_, edge_.value());
+        code = kvstore_->ingestEdge(spaceID_, edge_.value());
+    } else if (tag_.has_value()) {
+        LOG(INFO) << folly::stringPrintf(
+            "ingest space %d tag %d", spaceID_, tag_.value());
+        code = kvstore_->ingestTag(spaceID_, tag_.value());
+    } else {
+        LOG(INFO) << folly::stringPrintf(
+            "ingest space %d", spaceID_);
+        code = kvstore_->ingest(spaceID_);
+    }
     if (code == kvstore::ResultCode::SUCCEEDED) {
         return true;
     } else {

/* 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 "storage/http/StorageHttpIngestHandler.h"
#include <proxygen/httpserver/RequestHandler.h>
#include <proxygen/lib/http/ProxygenErrorEnum.h>
#include <proxygen/httpserver/ResponseBuilder.h>

namespace nebula {
namespace storage {

using proxygen::HTTPMessage;
using proxygen::HTTPMethod;
using proxygen::ProxygenError;
using proxygen::UpgradeProtocol;
using proxygen::ResponseBuilder;

void StorageHttpIngestHandler::init(nebula::kvstore::KVStore *kvstore) {
    kvstore_ = kvstore;
    CHECK_NOTNULL(kvstore_);
}

void StorageHttpIngestHandler::onRequest(std::unique_ptr<HTTPMessage> headers) noexcept {
    if (headers->getMethod().value() != HTTPMethod::GET) {
        // Unsupported method
        err_ = HttpCode::E_UNSUPPORTED_METHOD;
        return;
    }

    if (!headers->hasQueryParam("space")) {
        err_ = HttpCode::E_ILLEGAL_ARGUMENT;
        return;
    }

    space_ = headers->getIntQueryParam("space");
}

void StorageHttpIngestHandler::onBody(std::unique_ptr<folly::IOBuf>) noexcept {
    // Do nothing, we only support GET
}

void StorageHttpIngestHandler::onEOM() noexcept {
    switch (err_) {
        case HttpCode::E_UNSUPPORTED_METHOD:
            ResponseBuilder(downstream_)
                .status(WebServiceUtils::to(HttpStatusCode::METHOD_NOT_ALLOWED),
                        WebServiceUtils::toString(HttpStatusCode::METHOD_NOT_ALLOWED))
                .sendWithEOM();
            return;
        case HttpCode::E_ILLEGAL_ARGUMENT:
            ResponseBuilder(downstream_)
                .status(WebServiceUtils::to(HttpStatusCode::BAD_REQUEST),
                        WebServiceUtils::toString(HttpStatusCode::BAD_REQUEST))
                .sendWithEOM();
            return;
        default:
            break;
    }

    if (ingestSSTFiles(space_)) {
        LOG(ERROR) << "SSTFile ingest successfully ";
        ResponseBuilder(downstream_)
            .status(WebServiceUtils::to(HttpStatusCode::OK),
                    WebServiceUtils::toString(HttpStatusCode::OK))
            .body("SSTFile ingest successfully")
            .sendWithEOM();
    } else {
        LOG(ERROR) << "SSTFile ingest failed";
        ResponseBuilder(downstream_)
            .status(WebServiceUtils::to(HttpStatusCode::FORBIDDEN),
                    WebServiceUtils::toString(HttpStatusCode::FORBIDDEN))
            .body("SSTFile ingest failed")
            .sendWithEOM();
    }
}

void StorageHttpIngestHandler::onUpgrade(UpgradeProtocol) noexcept {
    // Do nothing
}

void StorageHttpIngestHandler::requestComplete() noexcept {
    delete this;
}

void StorageHttpIngestHandler::onError(ProxygenError error) noexcept {
    LOG(ERROR) << "Web Service MetaHttpIngestHandler Failed: "
               << proxygen::getErrorString(error);
}

bool StorageHttpIngestHandler::ingestSSTFiles(GraphSpaceID space) {
    auto code = kvstore_->ingest(space);
    if (code == kvstore::ResultCode::SUCCEEDED) {
        return true;
    } else {
        LOG(ERROR) << "SSTFile Ingest Failed: " << code;
        return false;
    }
}

}  // namespace storage
}  // namespace nebula


@@ -92,7 +92,7 @@ StatusOr<std::vector<cpp2::HostItem>> ListHostsProcessor::allHostsWithStatus(
         if (kvRet != kvstore::ResultCode::SUCCEEDED) {
             LOG(ERROR) << "List Hosts Failed: No partitions";
             resp_.set_code(cpp2::ErrorCode::E_NOT_FOUND);
-            return Status::Error("Cant't find any partitions");
+            return Status::Error("Can't find any partitions");
         }
         while (iter->valid()) {
             PartitionID partId = MetaServiceUtils::parsePartKeyPartId(iter->key());

/* 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 "meta/processors/partsMan/ListHostsProcessor.h"
#include "meta/ActiveHostsMan.h"
#include "meta/processors/admin/AdminClient.h"

DECLARE_int32(expired_threshold_sec);
DEFINE_int32(removed_threshold_sec, 24 * 60 * 60,
                     "Hosts will be removed in this time if no heartbeat received");

namespace nebula {
namespace meta {

void ListHostsProcessor::process(const cpp2::ListHostsReq& req) {
    UNUSED(req);
    std::unordered_map<GraphSpaceID, std::string> spaceIdNameMap;
    std::vector<cpp2::HostItem> hostItems;
    {
        folly::SharedMutex::ReadHolder rHolder(LockUtils::spaceLock());
        auto status = allHostsWithStatus(spaceIdNameMap);
        if (!status.ok()) {
            onFinished();
            return;
        }
        hostItems = std::move(status.value());
    }
    getLeaderDist(hostItems, spaceIdNameMap);
    resp_.set_hosts(std::move(hostItems));
    onFinished();
}

StatusOr<std::vector<cpp2::HostItem>> ListHostsProcessor::allHostsWithStatus(
                                    std::unordered_map<GraphSpaceID, std::string>& spaceIdNameMap) {
    std::vector<cpp2::HostItem> hostItems;

    const auto& hostPrefix = MetaServiceUtils::hostPrefix();
    std::unique_ptr<kvstore::KVIterator> iter;
    auto kvRet = kvstore_->prefix(kDefaultSpaceId, kDefaultPartId, hostPrefix, &iter);
    if (kvRet != kvstore::ResultCode::SUCCEEDED) {
        LOG(ERROR) << "List Hosts Failed: No hosts";
        resp_.set_code(cpp2::ErrorCode::E_NO_HOSTS);
        return Status::Error("Can't access kvstore, ret = %d", static_cast<int32_t>(kvRet));
    }

    auto now = time::WallClock::fastNowInMilliSec();
    std::vector<std::string> removeHostsKey;
    while (iter->valid()) {
        cpp2::HostItem item;
        auto host = MetaServiceUtils::parseHostKey(iter->key());
        item.set_hostAddr(std::move(host));
        HostInfo info = HostInfo::decode(iter->val());
        if (now - info.lastHBTimeInMilliSec_ < FLAGS_removed_threshold_sec * 1000) {
            if (now - info.lastHBTimeInMilliSec_ < FLAGS_expired_threshold_sec * 1000) {
                item.set_status(cpp2::HostStatus::ONLINE);
            } else {
                item.set_status(cpp2::HostStatus::OFFLINE);
            }
            hostItems.emplace_back(item);
        } else {
            removeHostsKey.emplace_back(iter->key());
        }
        iter->next();
    }

    // Get all spaces
    std::vector<GraphSpaceID> spaces;
    const auto& spacePrefix = MetaServiceUtils::spacePrefix();
    kvRet = kvstore_->prefix(kDefaultSpaceId, kDefaultPartId, spacePrefix, &iter);
    if (kvRet != kvstore::ResultCode::SUCCEEDED) {
        return hostItems;
    }
    while (iter->valid()) {
        auto spaceId = MetaServiceUtils::spaceId(iter->key());
        spaces.emplace_back(spaceId);
        spaceIdNameMap.emplace(spaceId, MetaServiceUtils::spaceName(iter->val()));
        iter->next();
    }

    std::unordered_map<HostAddr,
                       std::unordered_map<std::string, std::vector<PartitionID>>> allParts;
    for (const auto& spaceId : spaces) {
        // get space name by space id
        auto spaceName = spaceIdNameMap[spaceId];

        std::unordered_map<HostAddr, std::vector<PartitionID>> hostParts;
        const auto& partPrefix = MetaServiceUtils::partPrefix(spaceId);
        kvRet = kvstore_->prefix(kDefaultSpaceId, kDefaultPartId, partPrefix, &iter);
        if (kvRet != kvstore::ResultCode::SUCCEEDED) {
            LOG(ERROR) << "List Hosts Failed: No partitions";
            resp_.set_code(cpp2::ErrorCode::E_NOT_FOUND);
            return Status::Error("Cant't find any partitions");
        }
        while (iter->valid()) {
            PartitionID partId = MetaServiceUtils::parsePartKeyPartId(iter->key());
            auto partHosts = MetaServiceUtils::parsePartVal(iter->val());
            for (auto& host : partHosts) {
                hostParts[HostAddr(host.ip, host.port)].emplace_back(partId);
            }
            iter->next();
        }

        for (const auto& hostEntry : hostParts) {
            allParts[hostEntry.first][spaceName] = std::move(hostEntry.second);
        }
    }

    for (const auto& hostEntry : allParts) {
        auto hostAddr = toThriftHost(hostEntry.first);
        auto it = std::find_if(hostItems.begin(), hostItems.end(), [&](const auto& item) {
            return item.get_hostAddr() == hostAddr;
        });
        if (it != hostItems.end()) {
            // set default leader parts of all space to empty
            std::unordered_map<std::string, std::vector<PartitionID>> leaderParts;
            for (auto& spaceEntry : hostEntry.second) {
                leaderParts[spaceEntry.first] = {};
            }
            it->set_leader_parts(std::move(leaderParts));
            it->set_all_parts(std::move(hostEntry.second));
        }
    }

    // Remove hosts that long time at OFFLINE status
    if (!removeHostsKey.empty()) {
        kvstore_->asyncMultiRemove(kDefaultSpaceId,
                                   kDefaultPartId,
                                   std::move(removeHostsKey),
                                   [] (kvstore::ResultCode code) {
                if (code != kvstore::ResultCode::SUCCEEDED) {
                    LOG(ERROR) << "Async remove long time offline hosts failed: " << code;
                }
            });
    }
    return hostItems;
}

void ListHostsProcessor::getLeaderDist(
                                std::vector<cpp2::HostItem>& hostItems,
                                std::unordered_map<GraphSpaceID, std::string>& spaceIdNameMap) {
    if (adminClient_ == nullptr) {
        return;
    }
    HostLeaderMap hostLeaderMap;
    auto ret = adminClient_->getLeaderDist(&hostLeaderMap).get();
    if (!ret.ok()) {
        LOG(ERROR) << "Get leader distribution failed";
        return;
    }
    for (auto& hostEntry : hostLeaderMap) {
        auto hostAddr = toThriftHost(hostEntry.first);
        auto it = std::find_if(hostItems.begin(), hostItems.end(), [&](const auto& item) {
            return item.get_hostAddr() == hostAddr;
        });

        if (it != hostItems.end()) {
            for (auto& leaderEntry : hostEntry.second) {
                // get space name by space id
                auto spaceId = leaderEntry.first;
                auto spaceIter = spaceIdNameMap.find(spaceId);
                if (spaceIter == spaceIdNameMap.end()) {
                    continue;
                }
                auto spaceName = spaceIter->second;

                it->leader_parts[spaceName] = std::move(leaderEntry.second);
            }
        }
    }
}

}  // namespace meta
}  // namespace nebula


@@ -61,6 +61,10 @@ double convertInt64ToDouble(const Int64 &src)
   return (double) src;
 }

+double convertUInt64ToDouble(const UInt64 &src)
+{
+  return (double) src;
+}

 Int64 uint32ArrayToInt64(const UInt32 array[2])
 {

/**********************************************************************
// @@@ 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 @@@
**********************************************************************/
/* -*-C++-*-
**************************************************************************
*
* File:         Int64.C
* Description:  64-bit integer
* Created:      3/5/96
* Language:     C++
*
*
*
*
**************************************************************************
*/

#include "Int64.h"
#include "NABoolean.h"
#include "str.h"
#include "NAStdlib.h"

Int64 uint32ToInt64(UInt32 value)
{
  return (Int64) value;
}

Int32 int64ToInt32(Int64 value)
{
  UInt32 val32u;
  Int32 val32;

  val32u = (UInt32) value;
  val32 = (Int32)val32u;

  return val32;
}

double convertInt64ToDouble(const Int64 &src)
{
  return (double) src;
}

Int64 uint32ArrayToInt64(const UInt32 array[2])
{
  Int64 result = uint32ToInt64(array[0]);
  Int64 array1 = uint32ToInt64(array[1]);
  Int64 shift = INT_MAX;	// 2^31 - 1
  shift  += 1;			// 2^31
  result *= shift;
  result *= 2;			// 2*32, so result now has array[0] in high word
  result += array1;		// and array[1] in low word
  return result;
}

Int32 aToInt32(const char* src)
{
  NABoolean isNeg = FALSE;
  if (*src == '-')
  {
    isNeg = TRUE;
    src++;
  }

  Int32 tgt = 0;
  while ((*src >= '0') && (*src <= '9')) {
    tgt = tgt * 10 + (*src - '0');
    src++;
  }

  if (isNeg)
    return -tgt;
  else
    return tgt;
}

Int64 atoInt64(const char* src)
{
  NABoolean isNeg = FALSE;
  if (*src == '-')
  {
    isNeg = TRUE;
    src++;
  }

  Int64 tgt = 0;
  while ((*src >= '0') && (*src <= '9')) {
    tgt = tgt * 10 + (*src - '0');
    src++;
  }

  if (isNeg)
    return -tgt;
  else
    return tgt;

}

void convertInt64ToAscii(const Int64 &src, char* tgt)
{
  Int64 temp = src;  // (src >= 0) ? src : - src;
  char buffer[21];
  char *s = &buffer[21];
  *--s = '\0';
  do {
    char c = (char) (temp % 10);
    if (c < 0)
      c = -c;
    *--s = (char)(c + '0');
    temp /= 10;
  } while (temp != 0);
  if (src < 0)
    *--s = '-';
  strcpy(tgt, s);
}

void convertInt64ToUInt32Array(const Int64 &src, UInt32 *tgt)
{
  Lng32 *tPtr = (Lng32 *) &src;
#ifdef NA_LITTLE_ENDIAN
  tgt[0] = tPtr[1];
  tgt[1] = tPtr[0];
#else
  tgt[0] = tPtr[0];
  tgt[1] = tPtr[1];
#endif
}

//
// End of File
//


@@ -114,10 +114,10 @@ template <typename Dtype>
 void im2col_nd_cpu(const Dtype* data_im, const int num_spatial_axes,
     const int* im_shape, const int* col_shape,
     const int* kernel_shape, const int* pad, const int* stride,
-    Dtype* data_col) {
+    const int* dilation, Dtype* data_col) {
   const bool kIm2Col = true;
   im2col_nd_core_cpu(data_im, kIm2Col, num_spatial_axes, im_shape, col_shape,
-                  kernel_shape, pad, stride, data_col);
+                  kernel_shape, pad, stride, dilation, data_col);
 }

 // Explicit instantiation

#include <vector>

#include "caffe/util/im2col.hpp"
#include "caffe/util/math_functions.hpp"

namespace caffe {

template <typename Dtype>
void im2col_cpu(const Dtype* data_im, const int channels,
    const int height, const int width, const int kernel_h, const int kernel_w,
    const int pad_h, const int pad_w,
    const int stride_h, const int stride_w,
    Dtype* data_col) {
  const int height_col = (height + 2 * pad_h - kernel_h) / stride_h + 1;
  const int width_col = (width + 2 * pad_w - kernel_w) / stride_w + 1;
  const int channels_col = channels * kernel_h * kernel_w;
  for (int c_col = 0; c_col < channels_col; ++c_col) {
    int w_offset = c_col % kernel_w;
    int h_offset = (c_col / kernel_w) % kernel_h;
    int c_im = c_col / kernel_h / kernel_w;
    for (int h_col = 0; h_col < height_col; ++h_col) {
      for (int w_col = 0; w_col < width_col; ++w_col) {
        int h_im = h_col * stride_h - pad_h + h_offset;
        int w_im = w_col * stride_w - pad_w + w_offset;
        data_col[(c_col * height_col + h_col) * width_col + w_col] =
            (h_im >= 0 && w_im >= 0 && h_im < height && w_im < width) ?
            data_im[(c_im * height + h_im) * width + w_im] : 0;
      }
    }
  }
}

// Explicit instantiation
template void im2col_cpu<float>(const float* data_im, const int channels,
    const int height, const int width, const int kernel_h, const int kernel_w,
    const int pad_h, const int pad_w, const int stride_h,
    const int stride_w, float* data_col);
template void im2col_cpu<double>(const double* data_im, const int channels,
    const int height, const int width, const int kernel_h, const int kernel_w,
    const int pad_h, const int pad_w, const int stride_h,
    const int stride_w, double* data_col);

template <typename Dtype>
inline void im2col_nd_core_cpu(const Dtype* data_input, const bool im2col,
    const int num_spatial_axes, const int* im_shape, const int* col_shape,
    const int* kernel_shape, const int* pad, const int* stride,
    Dtype* data_output) {
  if (!im2col) {
    int im_size = im_shape[0];
    for (int i = 0; i < num_spatial_axes; ++i) {
      im_size *= im_shape[1 + i];
    }
    caffe_set(im_size, Dtype(0), data_output);
  }
  int kernel_size = 1;
  for (int i = 0; i < num_spatial_axes; ++i) {
    kernel_size *= kernel_shape[i];
  }
  const int channels_col = col_shape[0];
  vector<int> d_offset(num_spatial_axes, 0);
  vector<int> d_iter(num_spatial_axes, 0);
  for (int c_col = 0; c_col < channels_col; ++c_col) {
    // Loop over spatial axes in reverse order to compute a per-axis offset.
    int offset = c_col;
    for (int d_i = num_spatial_axes - 1; d_i >= 0; --d_i) {
      if (d_i < num_spatial_axes - 1) {
        offset /= kernel_shape[d_i + 1];
      }
      d_offset[d_i] = offset % kernel_shape[d_i];
    }
    for (bool incremented = true; incremented; ) {
      // Loop over spatial axes in forward order to compute the indices in the
      // image and column, and whether the index lies in the padding.
      int index_col = c_col;
      int index_im = c_col / kernel_size;
      bool is_padding = false;
      for (int d_i = 0; d_i < num_spatial_axes; ++d_i) {
        const int d = d_iter[d_i];
        const int d_im = d * stride[d_i] - pad[d_i] + d_offset[d_i];
        is_padding |= d_im < 0 || d_im >= im_shape[d_i + 1];
        index_col *= col_shape[d_i + 1];
        index_col += d;
        index_im *= im_shape[d_i + 1];
        index_im += d_im;
      }
      if (im2col) {
        if (is_padding) {
          data_output[index_col] = 0;
        } else {
          data_output[index_col] = data_input[index_im];
        }
      } else if (!is_padding) {  // col2im
        data_output[index_im] += data_input[index_col];
      }
      // Loop over spatial axes in reverse order to choose an index,
      // like counting.
      incremented = false;
      for (int d_i = num_spatial_axes - 1; d_i >= 0; --d_i) {
        const int d_max = col_shape[d_i + 1];
        DCHECK_LT(d_iter[d_i], d_max);
        if (d_iter[d_i] == d_max - 1) {
          d_iter[d_i] = 0;
        } else {  // d_iter[d_i] < d_max - 1
          ++d_iter[d_i];
          incremented = true;
          break;
        }
      }
    }  // while(incremented) {
  }  // for (int c = 0; c < channels_col; ++c) {
}

template <typename Dtype>
void im2col_nd_cpu(const Dtype* data_im, const int num_spatial_axes,
    const int* im_shape, const int* col_shape,
    const int* kernel_shape, const int* pad, const int* stride,
    Dtype* data_col) {
  const bool kIm2Col = true;
  im2col_nd_core_cpu(data_im, kIm2Col, num_spatial_axes, im_shape, col_shape,
                  kernel_shape, pad, stride, data_col);
}

// Explicit instantiation
template void im2col_nd_cpu<float>(const float* data_im,
    const int num_spatial_axes,
    const int* im_shape, const int* col_shape,
    const int* kernel_shape, const int* pad, const int* stride,
    float* data_col);
template void im2col_nd_cpu<double>(const double* data_im,
    const int num_spatial_axes,
    const int* im_shape, const int* col_shape,
    const int* kernel_shape, const int* pad, const int* stride,
    double* data_col);

template <typename Dtype>
void col2im_cpu(const Dtype* data_col, const int channels,
    const int height, const int width, const int kernel_h, const int kernel_w,
    const int pad_h, const int pad_w,
    const int stride_h, const int stride_w,
    Dtype* data_im) {
  caffe_set(height * width * channels, Dtype(0), data_im);
  const int height_col = (height + 2 * pad_h - kernel_h) / stride_h + 1;
  const int width_col = (width + 2 * pad_w - kernel_w) / stride_w + 1;
  const int channels_col = channels * kernel_h * kernel_w;
  for (int c_col = 0; c_col < channels_col; ++c_col) {
    int w_offset = c_col % kernel_w;
    int h_offset = (c_col / kernel_w) % kernel_h;
    int c_im = c_col / kernel_h / kernel_w;
    for (int h_col = 0; h_col < height_col; ++h_col) {
      for (int w_col = 0; w_col < width_col; ++w_col) {
        int h_im = h_col * stride_h - pad_h + h_offset;
        int w_im = w_col * stride_w - pad_w + w_offset;
        if (h_im >= 0 && h_im < height && w_im >= 0 && w_im < width)
          data_im[(c_im * height + h_im) * width + w_im] +=
              data_col[(c_col * height_col + h_col) * width_col + w_col];
      }
    }
  }
}

// Explicit instantiation
template void col2im_cpu<float>(const float* data_col, const int channels,
    const int height, const int width, const int kernel_h, const int kernel_w,
    const int pad_h, const int pad_w, const int stride_h,
    const int stride_w, float* data_im);
template void col2im_cpu<double>(const double* data_col, const int channels,
    const int height, const int width, const int kernel_h, const int kernel_w,
    const int pad_h, const int pad_w, const int stride_h,
    const int stride_w, double* data_im);

template <typename Dtype>
void col2im_nd_cpu(const Dtype* data_col, const int num_spatial_axes,
    const int* im_shape, const int* col_shape,
    const int* kernel_shape, const int* pad, const int* stride,
    Dtype* data_im) {
  const bool kIm2Col = false;
  im2col_nd_core_cpu(data_col, kIm2Col, num_spatial_axes, im_shape, col_shape,
                     kernel_shape, pad, stride, data_im);
}

// Explicit instantiation
template void col2im_nd_cpu<float>(const float* data_col,
    const int num_spatial_axes,
    const int* im_shape, const int* col_shape,
    const int* kernel_shape, const int* pad, const int* stride,
    float* data_im);
template void col2im_nd_cpu<double>(const double* data_col,
    const int num_spatial_axes,
    const int* im_shape, const int* col_shape,
    const int* kernel_shape, const int* pad, const int* stride,
    double* data_im);

}  // namespace caffe


@@ -104,7 +104,8 @@ Status TablePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
             {
                 const auto &table_index = row * num_destinations + column;
                 BOOST_ASSERT(table_index < result_tables_pair.first.size());
-                if (result_tables_pair.first[table_index] == MAXIMAL_EDGE_DURATION)
+                if (params.fallback_speed > 0 &&
+                    result_tables_pair.first[table_index] == MAXIMAL_EDGE_DURATION)
                 {
                     const auto &source =
                         snapped_phantoms[params.sources.empty() ? row : params.sources[row]];

#include "engine/plugins/table.hpp"

#include "engine/api/table_api.hpp"
#include "engine/api/table_parameters.hpp"
#include "engine/routing_algorithms/many_to_many.hpp"
#include "engine/search_engine_data.hpp"
#include "util/coordinate_calculation.hpp"
#include "util/json_container.hpp"
#include "util/string_util.hpp"

#include <cstdlib>

#include <algorithm>
#include <memory>
#include <string>
#include <vector>

#include <boost/assert.hpp>

namespace osrm
{
namespace engine
{
namespace plugins
{

TablePlugin::TablePlugin(const int max_locations_distance_table)
    : max_locations_distance_table(max_locations_distance_table)
{
}

Status TablePlugin::HandleRequest(const RoutingAlgorithmsInterface &algorithms,
                                  const api::TableParameters &params,
                                  util::json::Object &result) const
{
    if (!algorithms.HasManyToManySearch())
    {
        return Error("NotImplemented",
                     "Many to many search is not implemented for the chosen search algorithm.",
                     result);
    }

    BOOST_ASSERT(params.IsValid());

    if (!CheckAllCoordinates(params.coordinates))
    {
        return Error("InvalidOptions", "Coordinates are invalid", result);
    }

    if (params.bearings.size() > 0 && params.coordinates.size() != params.bearings.size())
    {
        return Error(
            "InvalidOptions", "Number of bearings does not match number of coordinates", result);
    }

    // Empty sources or destinations means the user wants all of them included, respectively
    // The ManyToMany routing algorithm we dispatch to below already handles this perfectly.
    const auto num_sources =
        params.sources.empty() ? params.coordinates.size() : params.sources.size();
    const auto num_destinations =
        params.destinations.empty() ? params.coordinates.size() : params.destinations.size();

    if (max_locations_distance_table > 0 &&
        ((num_sources * num_destinations) >
         static_cast<std::size_t>(max_locations_distance_table * max_locations_distance_table)))
    {
        return Error("TooBig", "Too many table coordinates", result);
    }

    if (!CheckAlgorithms(params, algorithms, result))
        return Status::Error;

    const auto &facade = algorithms.GetFacade();
    auto phantom_nodes = GetPhantomNodes(facade, params);

    if (phantom_nodes.size() != params.coordinates.size())
    {
        return Error("NoSegment",
                     std::string("Could not find a matching segment for coordinate ") +
                         std::to_string(phantom_nodes.size()),
                     result);
    }

    auto snapped_phantoms = SnapPhantomNodes(phantom_nodes);

    bool request_distance = params.annotations & api::TableParameters::AnnotationsType::Distance;
    bool request_duration = params.annotations & api::TableParameters::AnnotationsType::Duration;

    auto result_tables_pair = algorithms.ManyToManySearch(
        snapped_phantoms, params.sources, params.destinations, request_distance);

    if ((request_duration && result_tables_pair.first.empty()) ||
        (request_distance && result_tables_pair.second.empty()))
    {
        return Error("NoTable", "No table found", result);
    }

    // Scan table for null results - if any exist, replace with distance estimates
    if (params.fallback_speed > 0)
    {
        for (std::size_t row = 0; row < num_sources; row++)
        {
            for (std::size_t column = 0; column < num_destinations; column++)
            {
                const auto &table_index = row * num_destinations + column;
                BOOST_ASSERT(table_index < result_tables_pair.first.size());
                if (result_tables_pair.first[table_index] == MAXIMAL_EDGE_DURATION)
                {
                    const auto &source =
                        snapped_phantoms[params.sources.empty() ? row : params.sources[row]];
                    const auto &destination =
                        snapped_phantoms[params.destinations.empty() ? column
                                                                     : params.destinations[column]];

                    auto distance_estimate =
                        params.fallback_coordinate_type ==
                                api::TableParameters::FallbackCoordinateType::Input
                            ? util::coordinate_calculation::fccApproximateDistance(
                                  source.input_location, destination.input_location)
                            : util::coordinate_calculation::fccApproximateDistance(
                                  source.location, destination.location);

                    result_tables_pair.first[table_index] =
                        distance_estimate / (double)params.fallback_speed;
                    if (!result_tables_pair.second.empty())
                    {
                        result_tables_pair.second[table_index] = distance_estimate;
                    }
                }
            }
        }
    }

    api::TableAPI table_api{facade, params};
    table_api.MakeResponse(result_tables_pair, snapped_phantoms, result);

    return Status::Ok;
}
}
}
}


@@ -55,6 +55,23 @@ void AddListenerProcessor::process(const cpp2::AddListenerReq& req) {
     data.emplace_back(MetaKeyUtils::listenerKey(space, parts[i], type),
                       MetaKeyUtils::serializeHostAddr(hosts[i % hosts.size()]));
   }
+
+  nebula::cpp2::ErrorCode code = nebula::cpp2::ErrorCode::SUCCEEDED;
+  for (auto& host : hosts) {
+    auto machineKey = MetaKeyUtils::machineKey(host.host, host.port);
+    if (machineExist(machineKey) == nebula::cpp2::ErrorCode::SUCCEEDED) {
+      LOG(ERROR) << "The host " << host << " have existed!";
+      code = nebula::cpp2::ErrorCode::E_EXISTED;
+      break;
+    }
+    data.emplace_back(machineKey, "");
+  }
+
+  if (code != nebula::cpp2::ErrorCode::SUCCEEDED) {
+    handleErrorCode(code);
+    onFinished();
+    return;
+  }
   doSyncPutAndUpdate(std::move(data));
 }

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

#include "meta/processors/listener/ListenerProcessor.h"

#include "meta/ActiveHostsMan.h"

DECLARE_int32(heartbeat_interval_secs);
DECLARE_uint32(expired_time_factor);

namespace nebula {
namespace meta {

void AddListenerProcessor::process(const cpp2::AddListenerReq& req) {
  auto space = req.get_space_id();
  CHECK_SPACE_ID_AND_RETURN(space);
  auto type = req.get_type();
  const auto& hosts = req.get_hosts();
  auto ret = listenerExist(space, type);
  if (ret != nebula::cpp2::ErrorCode::E_LISTENER_NOT_FOUND) {
    if (ret == nebula::cpp2::ErrorCode::SUCCEEDED) {
      LOG(ERROR) << "Add listener failed, listener already exists.";
      ret = nebula::cpp2::ErrorCode::E_EXISTED;
    } else {
      LOG(ERROR) << "Add listener failed, error: " << apache::thrift::util::enumNameSafe(ret);
    }
    handleErrorCode(ret);
    onFinished();
    return;
  }

  // TODO : (sky) if type is elasticsearch, need check text search service.
  folly::SharedMutex::WriteHolder wHolder(LockUtils::listenerLock());
  folly::SharedMutex::ReadHolder rHolder(LockUtils::spaceLock());
  const auto& prefix = MetaKeyUtils::partPrefix(space);
  auto iterRet = doPrefix(prefix);
  if (!nebula::ok(iterRet)) {
    auto retCode = nebula::error(iterRet);
    LOG(ERROR) << "List parts failed, error: " << apache::thrift::util::enumNameSafe(retCode);
    handleErrorCode(retCode);
    onFinished();
    return;
  }

  std::vector<PartitionID> parts;
  auto iter = nebula::value(iterRet).get();
  while (iter->valid()) {
    parts.emplace_back(MetaKeyUtils::parsePartKeyPartId(iter->key()));
    iter->next();
  }
  std::vector<kvstore::KV> data;
  for (size_t i = 0; i < parts.size(); i++) {
    data.emplace_back(MetaKeyUtils::listenerKey(space, parts[i], type),
                      MetaKeyUtils::serializeHostAddr(hosts[i % hosts.size()]));
  }
  doSyncPutAndUpdate(std::move(data));
}

void RemoveListenerProcessor::process(const cpp2::RemoveListenerReq& req) {
  auto space = req.get_space_id();
  CHECK_SPACE_ID_AND_RETURN(space);
  auto type = req.get_type();
  auto ret = listenerExist(space, type);
  if (ret != nebula::cpp2::ErrorCode::SUCCEEDED) {
    if (ret == nebula::cpp2::ErrorCode::E_LISTENER_NOT_FOUND) {
      LOG(ERROR) << "Remove listener failed, listener not exists.";
    } else {
      LOG(ERROR) << "Remove listener failed, error: " << apache::thrift::util::enumNameSafe(ret);
    }
    handleErrorCode(ret);
    onFinished();
    return;
  }

  folly::SharedMutex::WriteHolder wHolder(LockUtils::listenerLock());
  std::vector<std::string> keys;
  const auto& prefix = MetaKeyUtils::listenerPrefix(space, type);
  auto iterRet = doPrefix(prefix);
  if (!nebula::ok(iterRet)) {
    auto retCode = nebula::error(iterRet);
    LOG(ERROR) << "Remove listener failed, error: " << apache::thrift::util::enumNameSafe(retCode);
    handleErrorCode(retCode);
    onFinished();
    return;
  }

  auto iter = nebula::value(iterRet).get();
  while (iter->valid()) {
    keys.emplace_back(iter->key());
    iter->next();
  }
  doSyncMultiRemoveAndUpdate(std::move(keys));
}

void ListListenerProcessor::process(const cpp2::ListListenerReq& req) {
  auto space = req.get_space_id();
  CHECK_SPACE_ID_AND_RETURN(space);
  folly::SharedMutex::ReadHolder rHolder(LockUtils::listenerLock());
  const auto& prefix = MetaKeyUtils::listenerPrefix(space);
  auto iterRet = doPrefix(prefix);
  if (!nebula::ok(iterRet)) {
    auto retCode = nebula::error(iterRet);
    LOG(ERROR) << "List listener failed, error: " << apache::thrift::util::enumNameSafe(retCode);
    handleErrorCode(retCode);
    onFinished();
    return;
  }

  auto activeHostsRet =
      ActiveHostsMan::getActiveHosts(kvstore_,
                                     FLAGS_heartbeat_interval_secs * FLAGS_expired_time_factor,
                                     cpp2::HostRole::LISTENER);
  if (!nebula::ok(activeHostsRet)) {
    handleErrorCode(nebula::error(activeHostsRet));
    onFinished();
    return;
  }

  std::vector<nebula::meta::cpp2::ListenerInfo> listeners;
  auto activeHosts = std::move(nebula::value(activeHostsRet));
  auto iter = nebula::value(iterRet).get();
  while (iter->valid()) {
    cpp2::ListenerInfo listener;
    listener.set_type(MetaKeyUtils::parseListenerType(iter->key()));
    listener.set_host(MetaKeyUtils::deserializeHostAddr(iter->val()));
    listener.set_part_id(MetaKeyUtils::parseListenerPart(iter->key()));
    if (std::find(activeHosts.begin(), activeHosts.end(), *listener.host_ref()) !=
        activeHosts.end()) {
      listener.set_status(cpp2::HostStatus::ONLINE);
    } else {
      listener.set_status(cpp2::HostStatus::OFFLINE);
    }
    listeners.emplace_back(std::move(listener));
    iter->next();
  }
  resp_.set_listeners(std::move(listeners));
  handleErrorCode(nebula::cpp2::ErrorCode::SUCCEEDED);
  onFinished();
}

}  // namespace meta
}  // namespace nebula


@@ -65,8 +65,7 @@ def EStateIndices(mol, force=True):
         tmp = (Is[i] - Is[j]) / (p * p)
         accum[i] += tmp
         accum[j] -= tmp
-
-  res = accum + Is
+  res = numpy.add(accum, Is, dtype='float')
   mol._eStateIndices = res
   return res

# $Id$
#
# Copyright (C) 2002-2006 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.
#
""" Basic EState definitions

"""

import numpy
from rdkit import Chem

def GetPrincipleQuantumNumber(atNum):
  """ Get principal quantum number for atom number """
  if atNum <= 2:
    return 1
  elif atNum <= 10:
    return 2
  elif atNum <= 18:
    return 3
  elif atNum <= 36:
    return 4
  elif atNum <= 54:
    return 5
  elif atNum <= 86:
    return 6
  else:
    return 7

def EStateIndices(mol, force=True):
  """ returns a tuple of EState indices for the molecule

    Reference: Hall, Mohney and Kier. JCICS _31_ 76-81 (1991)

  """
  if not force and hasattr(mol, '_eStateIndices'):
    return mol._eStateIndices

  tbl = Chem.GetPeriodicTable()
  nAtoms = mol.GetNumAtoms()
  Is = numpy.zeros(nAtoms, numpy.float)
  for i in range(nAtoms):
    at = mol.GetAtomWithIdx(i)
    atNum = at.GetAtomicNum()
    d = at.GetDegree()
    if d > 0:
      h = at.GetTotalNumHs()
      dv = tbl.GetNOuterElecs(atNum) - h
      N = GetPrincipleQuantumNumber(atNum)
      Is[i] = (4. / (N * N) * dv + 1) / d
  dists = Chem.GetDistanceMatrix(mol, useBO=0, useAtomWts=0)
  dists += 1
  accum = numpy.zeros(nAtoms, numpy.float)
  for i in range(nAtoms):
    for j in range(i + 1, nAtoms):
      p = dists[i, j]
      if p < 1e6:
        tmp = (Is[i] - Is[j]) / (p * p)
        accum[i] += tmp
        accum[j] -= tmp

  res = accum + Is
  mol._eStateIndices = res
  return res

EStateIndices.version = '1.0.0'

def MaxEStateIndex(mol, force=1):
  return max(EStateIndices(mol, force))

MaxEStateIndex.version = "1.0.0"

def MinEStateIndex(mol, force=1):
  return min(EStateIndices(mol, force))

MinEStateIndex.version = "1.0.0"

def MaxAbsEStateIndex(mol, force=1):
  return max([abs(x) for x in EStateIndices(mol, force)])

MaxAbsEStateIndex.version = "1.0.0"

def MinAbsEStateIndex(mol, force=1):
  return min([abs(x) for x in EStateIndices(mol, force)])

MinAbsEStateIndex.version = "1.0.0"

def _exampleCode():
  """ Example code for calculating E-state indices """
  smis = ['CCCC', 'CCCCC', 'CCCCCC', 'CC(N)C(=O)O', 'CC(N)C(=O)[O-].[Na+]']
  for smi in smis:
    m = Chem.MolFromSmiles(smi)
    print(smi)
    inds = EStateIndices(m)
    print('\t', inds)

if __name__ == '__main__':  # pragma: nocover
  _exampleCode()


@@ -117,16 +117,18 @@ void ShowExecutor::showSpaces() {
         onFinish_();
     };

-    auto error = [this] (auto &&e) {
-        LOG(ERROR) << "Exception caught: " << e.what();
-        DCHECK(onError_);
-        onError_(Status::Error("Internal error"));
-        return;
-    };
-
+    LOG_AND_PROCESS_ERROR();
     std::move(future).via(runner).thenValue(cb).thenError(error);
 }

+void ShowExecutor::showTags() {
+    // TODO(darion) support show tags via MetaClient
+}
+
+void ShowExecutor::showEdges() {
+    // TODO(darion) support show edges via MetaClient
+}
+
 void ShowExecutor::setupResponse(cpp2::ExecutionResponse &resp) {
     resp = std::move(*resp_);
 }

/* 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 "graph/ShowExecutor.h"
#include "network/NetworkUtils.h"

namespace nebula {
namespace graph {

using nebula::network::NetworkUtils;

ShowExecutor::ShowExecutor(Sentence *sentence,
                           ExecutionContext *ectx) : Executor(ectx) {
    sentence_ = static_cast<ShowSentence*>(sentence);
}

Status ShowExecutor::prepare() {
    return Status::OK();
}

void ShowExecutor::execute() {
    auto showType = sentence_->showType();
    switch (showType) {
        case ShowSentence::ShowType::kShowHosts:
            showHosts();
            break;
        case ShowSentence::ShowType::kShowSpaces:
            showSpaces();
            break;
        case ShowSentence::ShowType::kUnknown:
            onError_(Status::Error("Type unknown"));
            break;
        // intentionally no `default'
    }
}

void ShowExecutor::showHosts() {
    auto future = ectx()->getMetaClient()->listHosts();
    auto *runner = ectx()->rctx()->runner();

    auto cb = [this] (auto &&resp) {
        if (!resp.ok()) {
            DCHECK(onError_);
            onError_(std::move(resp).status());
            return;
        }

        auto retShowHosts = std::move(resp).value();
        std::vector<cpp2::RowValue> rows;
        std::vector<std::string> header;
        resp_ = std::make_unique<cpp2::ExecutionResponse>();

        header.push_back("Ip");
        header.push_back("Port");
        resp_->set_column_names(std::move(header));

        for (auto &host : retShowHosts) {
            std::vector<cpp2::ColumnValue> row;
            row.resize(2);
            row[0].set_str(NetworkUtils::ipFromHostAddr(host));
            row[1].set_str(folly::to<std::string>(NetworkUtils::portFromHostAddr(host)));
            rows.emplace_back();
            rows.back().set_columns(std::move(row));
        }
        resp_->set_rows(std::move(rows));

        DCHECK(onFinish_);
        onFinish_();
    };

    auto error = [this] (auto &&e) {
        LOG(ERROR) << "Exception caught: " << e.what();
        DCHECK(onError_);
        onError_(Status::Error("Internal error"));
        return;
    };

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

void ShowExecutor::showSpaces() {
    auto future = ectx()->getMetaClient()->listSpaces();
    auto *runner = ectx()->rctx()->runner();

    auto cb = [this] (auto &&resp) {
        if (!resp.ok()) {
            DCHECK(onError_);
            onError_(std::move(resp).status());
            return;
        }

        auto retShowSpaces = std::move(resp).value();
        std::vector<cpp2::RowValue> rows;
        std::vector<std::string> header;
        resp_ = std::make_unique<cpp2::ExecutionResponse>();

        header.push_back("Name");
        resp_->set_column_names(std::move(header));

        for (auto &space : retShowSpaces) {
            std::vector<cpp2::ColumnValue> row;
            row.emplace_back();
            row.back().set_str(std::move(space.second));
            rows.emplace_back();
            rows.back().set_columns(std::move(row));
        }
        resp_->set_rows(std::move(rows));

        DCHECK(onFinish_);
        onFinish_();
    };

    auto error = [this] (auto &&e) {
        LOG(ERROR) << "Exception caught: " << e.what();
        DCHECK(onError_);
        onError_(Status::Error("Internal error"));
        return;
    };

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

void ShowExecutor::setupResponse(cpp2::ExecutionResponse &resp) {
    resp = std::move(*resp_);
}

}   // namespace graph
}   // namespace nebula


@@ -19,6 +19,7 @@

 #include <fastdds/rtps/writer/StatefulWriter.h>
 #include <fastdds/rtps/history/WriterHistory.h>
+#include <fastdds/rtps/history/ReaderHistory.h>

 #include <fastdds/dds/log/Log.hpp>

// Copyright 2020 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// 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.

/**
 * @file EDPServerListener2.cpp
 *
 */

#include <fastdds/rtps/writer/StatefulWriter.h>
#include <fastdds/rtps/history/WriterHistory.h>

#include <fastdds/dds/log/Log.hpp>

#include "./EDPServerListeners2.hpp"
#include "./EDPServer2.hpp"
#include "../participant/PDPServer2.hpp"

namespace eprosima {
namespace fastdds {
namespace rtps {

using namespace eprosima::fastrtps::rtps;

EDPServerPUBListener2::EDPServerPUBListener2(
        EDPServer2* sedp)
    : EDPBasePUBListener(sedp->mp_RTPSParticipant->getAttributes().allocation.locators,
            sedp->mp_RTPSParticipant->getAttributes().allocation.data_limits)
    , sedp_(sedp)
{
}

void EDPServerPUBListener2::onNewCacheChangeAdded(
        RTPSReader* reader,
        const CacheChange_t* const change_in)
{
    (void)reader;
    (void)change_in;
    // TODO DISCOVERY SERVER VERSION 2
}

void EDPServerPUBListener2::onWriterChangeReceivedByAll(
        RTPSWriter* writer,
        CacheChange_t* change)
{
    (void)writer;

    if (ChangeKind_t::NOT_ALIVE_DISPOSED_UNREGISTERED == change->kind)
    {
        WriterHistory* writer_history =
                sedp_->publications_writer_.second;

        writer_history->remove_change(change);
    }
}

EDPServerSUBListener2::EDPServerSUBListener2(
        EDPServer2* sedp)
    : EDPBaseSUBListener(sedp->mp_RTPSParticipant->getAttributes().allocation.locators,
            sedp->mp_RTPSParticipant->getAttributes().allocation.data_limits)
    , sedp_(sedp)
{
}

void EDPServerSUBListener2::onNewCacheChangeAdded(
        RTPSReader* reader,
        const CacheChange_t* const change_in)
{
    (void)reader;
    (void)change_in;
    // TODO DISCOVERY SERVER VERSION 2
}

void EDPServerSUBListener2::onWriterChangeReceivedByAll(
        RTPSWriter* writer,
        CacheChange_t* change)
{
    (void)writer;

    if (ChangeKind_t::NOT_ALIVE_DISPOSED_UNREGISTERED == change->kind)
    {
        WriterHistory* writer_history =
                sedp_->subscriptions_writer_.second;

        writer_history->remove_change(change);
    }

}

} /* namespace rtps */
} // namespace fastdds
} /* namespace eprosima */


@@ -82,8 +82,8 @@ shaderc_shader_kind MapShadercType(VkShaderStageFlagBits vkShader) {

 // Compile a given string containing GLSL into SPIR-V
 // Return value of false means an error was encountered
-bool VkTestFramework::GLSLtoSPV(const VkShaderStageFlagBits shader_type, const char *pshader, std::vector<unsigned int> &spirv,
-                                bool debug, uint32_t spirv_minor_version) {
+bool VkTestFramework::GLSLtoSPV(VkPhysicalDeviceLimits const *const device_limits, const VkShaderStageFlagBits shader_type,
+                                const char *pshader, std::vector<unsigned int> &spirv, bool debug, uint32_t spirv_minor_version) {
     // On Android, use shaderc instead.
     shaderc::Compiler compiler;
     shaderc::CompileOptions options;

//  VK tests
//
//  Copyright (c) 2015-2019 The Khronos Group Inc.
//  Copyright (c) 2015-2019 Valve Corporation
//  Copyright (c) 2015-2019 LunarG, Inc.
//  Copyright (c) 2015-2019 Google, Inc.
//
// 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 "vktestframeworkandroid.h"
#include "shaderc/shaderc.hpp"
#include <android/log.h>

VkTestFramework::VkTestFramework() {}
VkTestFramework::~VkTestFramework() {}

// Define static elements
bool VkTestFramework::m_devsim_layer = false;
ANativeWindow *VkTestFramework::window = nullptr;

VkFormat VkTestFramework::GetFormat(VkInstance instance, vk_testing::Device *device) {
    VkFormatProperties format_props;
    vk::GetPhysicalDeviceFormatProperties(device->phy().handle(), VK_FORMAT_B8G8R8A8_UNORM, &format_props);
    if (format_props.linearTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT ||
        format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) {
        return VK_FORMAT_B8G8R8A8_UNORM;
    }
    vk::GetPhysicalDeviceFormatProperties(device->phy().handle(), VK_FORMAT_R8G8B8A8_UNORM, &format_props);
    if (format_props.linearTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT ||
        format_props.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT) {
        return VK_FORMAT_R8G8B8A8_UNORM;
    }
    printf("Error - device does not support VK_FORMAT_B8G8R8A8_UNORM nor VK_FORMAT_R8G8B8A8_UNORM - exiting\n");
    exit(0);
}

void VkTestFramework::InitArgs(int *argc, char *argv[]) {}
void VkTestFramework::Finish() {}

void TestEnvironment::SetUp() {
    vk_testing::set_error_callback(test_error_callback);

    vk::InitDispatchTable();
}

void TestEnvironment::TearDown() {}

// Android specific helper functions for shaderc.
struct shader_type_mapping {
    VkShaderStageFlagBits vkshader_type;
    shaderc_shader_kind shaderc_type;
};

static const shader_type_mapping shader_map_table[] = {
    {VK_SHADER_STAGE_VERTEX_BIT, shaderc_glsl_vertex_shader},
    {VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, shaderc_glsl_tess_control_shader},
    {VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, shaderc_glsl_tess_evaluation_shader},
    {VK_SHADER_STAGE_GEOMETRY_BIT, shaderc_glsl_geometry_shader},
    {VK_SHADER_STAGE_FRAGMENT_BIT, shaderc_glsl_fragment_shader},
    {VK_SHADER_STAGE_COMPUTE_BIT, shaderc_glsl_compute_shader},
};

shaderc_shader_kind MapShadercType(VkShaderStageFlagBits vkShader) {
    for (auto shader : shader_map_table) {
        if (shader.vkshader_type == vkShader) {
            return shader.shaderc_type;
        }
    }
    assert(false);
    return shaderc_glsl_infer_from_source;
}

// Compile a given string containing GLSL into SPIR-V
// Return value of false means an error was encountered
bool VkTestFramework::GLSLtoSPV(const VkShaderStageFlagBits shader_type, const char *pshader, std::vector<unsigned int> &spirv,
                                bool debug, uint32_t spirv_minor_version) {
    // On Android, use shaderc instead.
    shaderc::Compiler compiler;
    shaderc::CompileOptions options;
    if (debug) {
        options.SetOptimizationLevel(shaderc_optimization_level_zero);
        options.SetGenerateDebugInfo();
    }

    switch (spirv_minor_version) {
        default:
        case 0:
            options.SetTargetSpirv(shaderc_spirv_version_1_0);
            break;
        case 1:
            options.SetTargetSpirv(shaderc_spirv_version_1_1);
            break;
        case 2:
            options.SetTargetSpirv(shaderc_spirv_version_1_2);
            break;
        case 3:
            options.SetTargetSpirv(shaderc_spirv_version_1_3);
            break;
        case 4:
            options.SetTargetSpirv(shaderc_spirv_version_1_4);
            break;
    }

    shaderc::SpvCompilationResult result =
        compiler.CompileGlslToSpv(pshader, strlen(pshader), MapShadercType(shader_type), "shader", options);
    if (result.GetCompilationStatus() != shaderc_compilation_status_success) {
        __android_log_print(ANDROID_LOG_ERROR, "VulkanLayerValidationTests", "GLSLtoSPV compilation failed: %s",
                            result.GetErrorMessage().c_str());
        return false;
    }

    for (auto iter = result.begin(); iter != result.end(); iter++) {
        spirv.push_back(*iter);
    }

    return true;
}

//
// Compile a given string containing SPIR-V assembly into SPV for use by VK
// Return value of false means an error was encountered.
//
bool VkTestFramework::ASMtoSPV(const spv_target_env target_env, const uint32_t options, const char *pasm,
                               std::vector<unsigned int> &spv) {
    spv_binary binary;
    spv_diagnostic diagnostic = nullptr;
    spv_context context = spvContextCreate(target_env);
    spv_result_t error = spvTextToBinaryWithOptions(context, pasm, strlen(pasm), options, &binary, &diagnostic);
    spvContextDestroy(context);
    if (error) {
        __android_log_print(ANDROID_LOG_ERROR, "VkLayerValidationTest", "ASMtoSPV compilation failed");
        spvDiagnosticDestroy(diagnostic);
        return false;
    }
    spv.insert(spv.end(), binary->code, binary->code + binary->wordCount);
    spvBinaryDestroy(binary);

    return true;
}


@@ -120,21 +120,26 @@ void embedding_layer<data_layout::DATA_PARALLEL,El::Device::CPU>::bp_compute() {
   auto& opt = *m_weights[0]->get_optimizer();

   // Local data
-  const auto& local_input = get_local_prev_activations();
-  auto& local_dict_grad = m_dictionary_gradient.Matrix();
-  const auto& local_output_grad = get_local_prev_error_signals();
+  const auto& local_input = dynamic_cast<const CPUMat&>(get_local_prev_activations());
+  auto& local_dict_grad = dynamic_cast<CPUMat&>(m_dictionary_gradient.Matrix());
+  const auto& local_output_grad = dynamic_cast<const CPUMat&>(get_local_prev_error_signals());
   const auto& local_width = local_input.Width();
   const auto& c = static_cast<const sgd_execution_context&>(this->m_model->get_execution_context());
   const auto& mini_batch_size = c.get_effective_mini_batch_size();

   // Update appropriate columns of gradient w.r.t. dictionary
+  // Note: Don't update gradient for padding index
   El::Zero(local_dict_grad);
   CPUMat dict_grad_v, output_grad_v;
   for (El::Int col = 0; col < local_width; ++ col) {
-    const El::Int ind = static_cast<El::Int>(local_input(0, col));
-    El::View(dict_grad_v, local_dict_grad, El::ALL, El::IR(ind));
-    El::LockedView(output_grad_v, local_output_grad, El::ALL, El::IR(col));
-    El::Axpy(DataType{1}, output_grad_v, dict_grad_v);
+    const El::Int ind = static_cast<El::Int>(std::floor(local_input(0, col)));
+    if (0 <= ind
+        && ind < static_cast<El::Int>(m_num_embeddings)
+        && ind != m_padding_idx) {
+      El::View(dict_grad_v, local_dict_grad, El::ALL, El::IR(ind));
+      El::LockedView(output_grad_v, local_output_grad, El::ALL, El::IR(col));
+      El::Axpy(DataType{1}, output_grad_v, dict_grad_v);
+    }
   }
   opt.add_to_gradient(m_dictionary_gradient,
                       DataType{1} / mini_batch_size,

////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2014-2019, 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.
////////////////////////////////////////////////////////////////////////////////

#define LBANN_EMBEDDING_LAYER_INSTANTIATE
#include "lbann/layers/learning/embedding.hpp"
#include "lbann/models/model.hpp"
#include "lbann/execution_contexts/sgd_execution_context.hpp"

namespace lbann {

template <>
void embedding_layer<data_layout::DATA_PARALLEL,El::Device::CPU>::setup_matrices(const El::Grid& grid) {
  Layer::setup_matrices(grid);
  m_dictionary_gradient = StarMat<El::Device::CPU>(grid);
}

template <>
void embedding_layer<data_layout::DATA_PARALLEL,El::Device::CPU>::setup_dims() {
  Layer::setup_dims();

  // Make sure input dimensions are valid
  if (this->get_input_size() != 1) {
    const auto& input_dims = this->get_input_dims();
    std::ostringstream err;
    err << get_type() << " layer \"" << get_name() << "\" "
        << "recieved an input tensor with invalid dimensions "
        << "(expected 1, got ";
    for (size_t i = 0; i < input_dims.size(); ++i) {
      err << (i > 0 ? "x" : "") << input_dims[i];
    }
    err << ")";
    LBANN_ERROR(err.str());
  }

  // Output is size of embedding vector
  this->set_output_dims({static_cast<int>(m_embedding_size)});

}

template <>
void embedding_layer<data_layout::DATA_PARALLEL,El::Device::CPU>::setup_data() {
  Layer::setup_data();

  // Make sure layer has weights for dictionary
  if (this->m_weights.size() != 1) {
    std::ostringstream err;
    err << "attempted to setup "
        << this->get_type() << " layer \"" << this->get_name() << "\" "
        << "with an invalid number of weights "
        << "(expected 1, "
        << "found " << this->m_weights.size() << ")";
    LBANN_ERROR(err.str());
  }

  // Initialize dictionary
  auto& dict = *m_weights[0];
  auto matrix_dist = get_prev_activations().DistData();
  matrix_dist.colDist = El::STAR;
  matrix_dist.rowDist = El::STAR;
  dict.set_dims({static_cast<int>(m_embedding_size)},
                {static_cast<int>(m_dictionary_size)});
  dict.set_matrix_distribution(matrix_dist);

  // Initialize gradient w.r.t. dictionary
  m_dictionary_gradient.Resize(m_embedding_size, m_dictionary_size);

}

template <>
void embedding_layer<data_layout::DATA_PARALLEL,El::Device::CPU>::fp_compute() {

  // Local data
  const auto& local_dict = m_weights[0]->get_values().LockedMatrix();
  const auto& local_input = get_local_prev_activations();
  auto& local_output = get_local_activations();
  const auto& local_width = local_input.Width();

  // Populate output matrix with appropriate columns of dictionary
  CPUMat dict_v, output_v;
  for (El::Int col = 0; col < local_width; ++ col) {
    const El::Int ind = static_cast<El::Int>(local_input(0, col));
    El::LockedView(dict_v, local_dict, El::ALL, El::IR(ind));
    El::View(output_v, local_output, El::ALL, El::IR(col));
    El::Copy(dict_v, output_v);
  }

}

template <>
void embedding_layer<data_layout::DATA_PARALLEL,El::Device::CPU>::bp_compute() {

  // Embedding layer is not differentiable w.r.t. inputs
  El::Zero(get_error_signals());

  // Nothing to be done if dictionary is not being optimized
  if (m_weights[0]->get_optimizer() == nullptr) { return; }
  auto& opt = *m_weights[0]->get_optimizer();

  // Local data
  const auto& local_input = get_local_prev_activations();
  auto& local_dict_grad = m_dictionary_gradient.Matrix();
  const auto& local_output_grad = get_local_prev_error_signals();
  const auto& local_width = local_input.Width();
  const auto& c = static_cast<const sgd_execution_context&>(this->m_model->get_execution_context());
  const auto& mini_batch_size = c.get_effective_mini_batch_size();

  // Update appropriate columns of gradient w.r.t. dictionary
  El::Zero(local_dict_grad);
  CPUMat dict_grad_v, output_grad_v;
  for (El::Int col = 0; col < local_width; ++ col) {
    const El::Int ind = static_cast<El::Int>(local_input(0, col));
    El::View(dict_grad_v, local_dict_grad, El::ALL, El::IR(ind));
    El::LockedView(output_grad_v, local_output_grad, El::ALL, El::IR(col));
    El::Axpy(DataType{1}, output_grad_v, dict_grad_v);
  }
  opt.add_to_gradient(m_dictionary_gradient,
                      DataType{1} / mini_batch_size,
                      true);

}

// Explicit instantiation
template class embedding_layer<data_layout::DATA_PARALLEL, El::Device::CPU>;

} // namespace lbann


@@ -141,6 +141,28 @@ struct compute_kernel_gpu<Float, method::dense, task::compute> {
                         const input_t& input) const {
         return compute<Float>(ctx, desc, input);
     }
+
+#ifdef ONEDAL_DATA_PARALLEL
+    void operator()(const context_gpu& ctx,
+                    const descriptor_t& desc,
+                    const table& x,
+                    const table& y,
+                    homogen_table& res) {
+        ONEDAL_ASSERT(x.get_row_count() == res.get_row_count());
+        ONEDAL_ASSERT(y.get_row_count() == res.get_column_count());
+        ONEDAL_ASSERT(x.get_column_count() == y.get_column_count());
+
+        auto& queue = ctx.get_queue();
+        const auto x_nd = pr::table2ndarray<Float>(queue, x, sycl::usm::alloc::device);
+        const auto y_nd = pr::table2ndarray<Float>(queue, y, sycl::usm::alloc::device);
+
+        auto res_ptr = res.get_data<Float>();
+        auto res_nd = pr::ndarray<Float, 2>::wrap(const_cast<Float*>(res_ptr),
+                                                  { res.get_row_count(), res.get_column_count() });
+
+        compute_rbf(queue, x_nd, y_nd, res_nd, desc.get_sigma());
+    }
+#endif
 };

 template struct compute_kernel_gpu<float, method::dense, task::compute>;

/*******************************************************************************
* Copyright 2020-2021 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/rbf_kernel/backend/gpu/compute_kernel.hpp"
#include "oneapi/dal/backend/primitives/reduction.hpp"
#include "oneapi/dal/backend/primitives/blas.hpp"
#include "oneapi/dal/backend/math.hpp"
#include "oneapi/dal/backend/primitives/utils.hpp"

namespace oneapi::dal::rbf_kernel::backend {

using dal::backend::context_gpu;
using input_t = compute_input<task::compute>;
using result_t = compute_result<task::compute>;
using descriptor_t = detail::descriptor_base<task::compute>;

namespace pr = dal::backend::primitives;

template <typename Float>
inline auto compute_exponents(sycl::queue& queue,
                              const pr::ndview<Float, 1>& sqr_x_nd,
                              const pr::ndview<Float, 1>& sqr_y_nd,
                              pr::ndview<Float, 2>& res_nd,
                              double sigma,
                              const dal::backend::event_vector& deps = {}) {
    const std::int64_t x_row_count = sqr_x_nd.get_dimension(0);
    const std::int64_t y_row_count = sqr_y_nd.get_dimension(0);
    ONEDAL_ASSERT(res_nd.get_count() == x_row_count * y_row_count);

    const Float coeff = static_cast<Float>(-0.5 / (sigma * sigma));

    const Float* sqr_x_ptr = sqr_x_nd.get_data();
    const Float* sqr_y_ptr = sqr_y_nd.get_data();
    Float* res_ptr = res_nd.get_mutable_data();

    const Float threshold = dal::backend::exp_low_threshold<Float>();

    const auto wg_size = dal::backend::propose_wg_size(queue);
    const auto range =
        dal::backend::make_multiple_nd_range_2d({ x_row_count, y_row_count }, { wg_size, 1 });

    auto compute_rbf_event = queue.submit([&](sycl::handler& cgh) {
        cgh.depends_on(deps);
        const std::size_t ld = y_row_count;

        cgh.parallel_for(range, [=](sycl::nd_item<2> item) {
            const std::size_t i = item.get_global_id(0);
            const std::size_t j = item.get_global_id(1);
            const Float sqr_x_i = sqr_x_ptr[i];
            const Float sqr_y_j = sqr_y_ptr[j];
            const Float res_rbf_ij = res_ptr[i * ld + j];
            const Float arg = sycl::fmax((sqr_x_i + sqr_y_j + res_rbf_ij) * coeff, threshold);

            res_ptr[i * ld + j] = sycl::exp(arg);
        });
    });

    return compute_rbf_event;
}

template <typename Float>
inline auto compute_rbf(sycl::queue& queue,
                        const pr::ndview<Float, 2>& x_nd,
                        const pr::ndview<Float, 2>& y_nd,
                        pr::ndview<Float, 2>& res_nd,
                        double sigma,
                        const dal::backend::event_vector& deps = {}) {
    const std::int64_t x_row_count = x_nd.get_dimension(0);
    const std::int64_t y_row_count = y_nd.get_dimension(0);

    auto sqr_x_nd = pr::ndarray<Float, 1>::empty(queue, { x_row_count }, sycl::usm::alloc::device);
    auto sqr_y_nd = pr::ndarray<Float, 1>::empty(queue, { y_row_count }, sycl::usm::alloc::device);

    auto reduce_x_event =
        pr::reduce_by_rows(queue, x_nd, sqr_x_nd, pr::sum<Float>{}, pr::square<Float>{}, deps);
    auto reduce_y_event =
        pr::reduce_by_rows(queue, y_nd, sqr_y_nd, pr::sum<Float>{}, pr::square<Float>{}, deps);

    constexpr Float alpha = -2.0;
    constexpr Float beta = 0.0;
    auto gemm_event = pr::gemm(queue, x_nd, y_nd.t(), res_nd, alpha, beta);

    auto compute_exponents_event =
        compute_exponents(queue,
                          sqr_x_nd,
                          sqr_y_nd,
                          res_nd,
                          sigma,
                          { reduce_x_event, reduce_y_event, gemm_event });

    auto smart_event =
        dal::backend::smart_event{ compute_exponents_event }.attach(sqr_x_nd).attach(sqr_y_nd);

    return smart_event;
}

template <typename Float>
static result_t compute(const context_gpu& ctx, const descriptor_t& desc, const input_t& input) {
    const auto x = input.get_x();
    const auto y = input.get_y();

    auto& queue = ctx.get_queue();

    const std::int64_t x_row_count = x.get_row_count();
    const std::int64_t y_row_count = y.get_row_count();

    ONEDAL_ASSERT(x.get_column_count() == y.get_column_count());
    dal::detail::check_mul_overflow(x_row_count, y_row_count);

    const auto x_nd = pr::table2ndarray<Float>(queue, x, sycl::usm::alloc::device);
    const auto y_nd = pr::table2ndarray<Float>(queue, y, sycl::usm::alloc::device);

    auto res_nd =
        pr::ndarray<Float, 2>::empty(queue, { x_row_count, y_row_count }, sycl::usm::alloc::device);

    auto compute_rbf_event = compute_rbf(queue, x_nd, y_nd, res_nd, desc.get_sigma());

    const auto res_array = res_nd.flatten(queue, { compute_rbf_event });
    auto res_table = homogen_table::wrap(res_array, x_row_count, y_row_count);

    return result_t{}.set_values(res_table);
}

template <typename Float>
struct compute_kernel_gpu<Float, method::dense, task::compute> {
    result_t operator()(const context_gpu& ctx,
                        const descriptor_t& desc,
                        const input_t& input) const {
        return compute<Float>(ctx, desc, input);
    }
};

template struct compute_kernel_gpu<float, method::dense, task::compute>;
template struct compute_kernel_gpu<double, method::dense, task::compute>;

} // namespace oneapi::dal::rbf_kernel::backend


@@ -55,7 +55,7 @@ def plot_importance(booster, ax=None, height=0.2,
     try:
         import matplotlib.pyplot as plt
     except ImportError:
-        raise ImportError('You must install matplotlib for plotting library')
+        raise ImportError('You must install matplotlib to plot importance.')

     if isinstance(booster, LGBMModel):
         importance = booster.booster_.feature_importance(importance_type=importance_type)

# coding: utf-8
# pylint: disable = C0103
"""Plotting Library."""
from __future__ import absolute_import

import numpy as np

from .basic import Booster, is_numpy_1d_array
from .sklearn import LGBMModel

def plot_importance(booster, ax=None, height=0.2,
                    xlim=None, ylim=None, title='Feature importance',
                    xlabel='Feature importance', ylabel='Features',
                    importance_type='split', max_num_features=None,
                    ignore_zero=True, grid=True, **kwargs):
    """Plot model feature importances.

    Parameters
    ----------
    booster : Booster, LGBMModel or array
        Booster or LGBMModel instance, or array of feature importances
    ax : matplotlib Axes
        Target axes instance. If None, new figure and axes will be created.
    height : float
        Bar height, passed to ax.barh()
    xlim : tuple
        Tuple passed to axes.xlim()
    ylim : tuple
        Tuple passed to axes.ylim()
    title : str
        Axes title. Pass None to disable.
    xlabel : str
        X axis title label. Pass None to disable.
    ylabel : str
        Y axis title label. Pass None to disable.
    importance_type : str
        How the importance is calculated: "split" or "gain"
        "split" is the number of times a feature is used in a model
        "gain" is the total gain of splits which use the feature
    max_num_features : int
        Max number of top features displayed on plot.
        If None or smaller than 1, all features will be displayed.
    ignore_zero : bool
        Ignore features with zero importance
    grid : bool
        Whether add grid for axes
    **kwargs :
        Other keywords passed to ax.barh()

    Returns
    -------
    ax : matplotlib Axes
    """
    try:
        import matplotlib.pyplot as plt
    except ImportError:
        raise ImportError('You must install matplotlib for plotting library')

    if isinstance(booster, LGBMModel):
        importance = booster.booster_.feature_importance(importance_type=importance_type)
    elif isinstance(booster, Booster):
        importance = booster.feature_importance(importance_type=importance_type)
    elif is_numpy_1d_array(booster) or isinstance(booster, list):
        importance = booster
    else:
        raise ValueError('booster must be Booster or array instance')

    if not len(importance):
        raise ValueError('Booster feature_importances are empty')

    tuples = sorted(enumerate(importance), key=lambda x: x[1])
    if ignore_zero:
        tuples = [x for x in tuples if x[1] > 0]
    if max_num_features is not None and max_num_features > 0:
        tuples = tuples[-max_num_features:]
    labels, values = zip(*tuples)

    if ax is None:
        _, ax = plt.subplots(1, 1)

    ylocs = np.arange(len(values))
    ax.barh(ylocs, values, align='center', height=height, **kwargs)

    for x, y in zip(values, ylocs):
        ax.text(x + 1, y, x, va='center')

    ax.set_yticks(ylocs)
    ax.set_yticklabels(labels)

    if xlim is not None:
        if not isinstance(xlim, tuple) or len(xlim) != 2:
            raise ValueError('xlim must be a tuple of 2 elements')
    else:
        xlim = (0, max(values) * 1.1)
    ax.set_xlim(xlim)

    if ylim is not None:
        if not isinstance(ylim, tuple) or len(ylim) != 2:
            raise ValueError('ylim must be a tuple of 2 elements')
    else:
        ylim = (-1, len(values))
    ax.set_ylim(ylim)

    if title is not None:
        ax.set_title(title)
    if xlabel is not None:
        ax.set_xlabel(xlabel)
    if ylabel is not None:
        ax.set_ylabel(ylabel)
    ax.grid(grid)
    return ax


@@ -21,7 +21,7 @@ void AddEdgesProcessor::process(const cpp2::AddEdgesRequest& req) {
         std::vector<kvstore::KV> data;
         std::for_each(partEdges.second.begin(), partEdges.second.end(), [&](auto& edge){
             auto key = KeyUtils::edgeKey(partId, edge.key.src, edge.key.edge_type,
-                                         edge.key.ranking, edge.key.dst, now);
+                                         edge.key.ranking, edge.key.dst, version);
             data.emplace_back(std::move(key), std::move(edge.get_props()));
         });
         doPut(spaceId, partId, std::move(data));

/* 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 "storage/AddEdgesProcessor.h"
#include <algorithm>
#include "time/TimeUtils.h"
#include "storage/KeyUtils.h"

namespace nebula {
namespace storage {

void AddEdgesProcessor::process(const cpp2::AddEdgesRequest& req) {
    auto spaceId = req.get_space_id();
    auto now = time::TimeUtils::nowInMSeconds();
    callingNum_ = req.parts.size();
    CHECK_NOTNULL(kvstore_);
    std::for_each(req.parts.begin(), req.parts.end(), [&](auto& partEdges){
        auto partId = partEdges.first;
        std::vector<kvstore::KV> data;
        std::for_each(partEdges.second.begin(), partEdges.second.end(), [&](auto& edge){
            auto key = KeyUtils::edgeKey(partId, edge.key.src, edge.key.edge_type,
                                         edge.key.ranking, edge.key.dst, now);
            data.emplace_back(std::move(key), std::move(edge.get_props()));
        });
        doPut(spaceId, partId, std::move(data));
    });
}

}  // namespace storage
}  // namespace nebula


@@ -128,6 +128,7 @@ void WANZmq::Write(const char *buffer, size_t size)
                                          ", in call to WANZmq write\n");
         }
     }
+    */
 }

 void WANZmq::Flush() {}

/*
 * Distributed under the OSI-approved Apache License, Version 2.0.  See
 * accompanying file Copyright.txt for details.
 *
 * WANZmq.cpp
 *
 *  Created on: May 26, 2017
 *      Author: Jason Wang wangr1@ornl.gov
 */

#include "WANZmq.h"

#include <zmq.h>

namespace adios2
{
namespace transport
{

WANZmq::WANZmq(const std::string ipAddress, const std::string port,
               MPI_Comm mpiComm, const bool debugMode)
: Transport("wan", "zmq", mpiComm, debugMode), m_IPAddress(ipAddress),
  m_Port(port)
{

    if (m_DebugMode)
    {
        // TODO verify port is unsigned int
    }
}

WANZmq::~WANZmq()
{
    if (m_Socket)
    {
        zmq_close(m_Socket);
    }
}

void WANZmq::Open(const std::string &name, const OpenMode openMode)
{
    m_Name = name;
    m_OpenMode = openMode;

    if (m_OpenMode == OpenMode::Write)
    {
        if (m_Profiler.IsActive)
        {
            m_Profiler.Timers.at("open").Resume();
        }

        m_Socket = zmq_socket(m_Context, ZMQ_REQ);
        const std::string fullIP("tcp://" + m_IPAddress + ":" + m_Port);
        zmq_connect(m_Socket, fullIP.c_str());

        if (m_Profiler.IsActive)
        {
            m_Profiler.Timers.at("open").Pause();
        }
    }
    else if (m_OpenMode == OpenMode::Append)
    {
        if (m_DebugMode)
        {
            throw std::invalid_argument(
                "ERROR: WAN transport " + m_Name +
                " only supports "
                "OpenMode:w (write/sender) and "
                "OpenMode:r (read/receiver), in call to Open\n");
        }
    }
    else if (m_OpenMode == OpenMode::Read)
    {
        if (m_Profiler.IsActive)
        {
            m_Profiler.Timers.at("open").Resume();
        }

        m_Socket = zmq_socket(m_Context, ZMQ_REP);
        const std::string fullIP("tcp://" + m_IPAddress + ":" + m_Port);
        zmq_bind(m_Socket, fullIP.c_str());

        if (m_Profiler.IsActive)
        {
            m_Profiler.Timers.at("open").Pause();
        }
    }

    if (m_DebugMode)
    {
        if (m_Socket == NULL) // something goes wrong
        {
            throw std::ios_base::failure(
                "ERROR: couldn't open socket for address " + m_Name +
                ", in call to WANZmq Open\n");
        }
    }
    m_IsOpen = true;
}

void WANZmq::SetBuffer(char *buffer, size_t size) {}

void WANZmq::Write(const char *buffer, size_t size)
{

    if (m_Profiler.IsActive)
    {
        m_Profiler.Timers.at("write").Resume();
    }

    int status = zmq_send(m_Socket, buffer, size, 0);
    char ret[10];
    zmq_recv(m_Socket, ret, 10, 0);

    if (m_Profiler.IsActive)
    {
        m_Profiler.Timers.at("write").Pause();
    }

    if (m_DebugMode)
    {
        const std::string retString(ret);

        if (status == -1 || retString != "OK") // TODO : verify this
        {
            throw std::ios_base::failure("ERROR: couldn't send message " +
                                         m_Name +
                                         ", in call to WANZmq write\n");
        }
    }
}

void WANZmq::Flush() {}

void WANZmq::Close()
{
    if (m_Socket)
    {
        zmq_close(m_Socket);
    }
}

} // end namespace transport
} // end namespace adios


@@ -68,10 +68,21 @@ bool generateDataStoreOptions(const int argc,
     // declare a group of options that will be allowed both on command line
     // as well as in a config file
     boost::program_options::options_description config_options("Configuration");
-    config_options.add_options()("max-wait",
-                                 boost::program_options::value<int>(&max_wait)->default_value(-1),
-                                 "Maximum number of seconds to wait on a running data update "
-                                 "before aquiring the lock by force.");
+    config_options.add_options() //
+        ("max-wait",
+         boost::program_options::value<int>(&max_wait)->default_value(-1),
+         "Maximum number of seconds to wait on a running data update "
+         "before aquiring the lock by force.") //
+        ("dataset-name",
+         boost::program_options::value<std::string>(&dataset_name)->default_value(""),
+         "Name of the dataset to load into memory. This allows having multiple datasets in memory "
+         "at the same time.") //
+        ("list",
+         boost::program_options::value<bool>(&list_datasets)
+             ->default_value(false)
+             ->implicit_value(true),
+         "Name of the dataset to load into memory. This allows having multiple datasets in memory "
+         "at the same time.");

     // hidden options, will be allowed on command line but will not be shown to the user
     boost::program_options::options_description hidden_options("Hidden options");

#include "storage/shared_memory.hpp"
#include "storage/shared_monitor.hpp"
#include "storage/storage.hpp"
#include "osrm/exception.hpp"
#include "util/log.hpp"
#include "util/meminfo.hpp"
#include "util/typedefs.hpp"
#include "util/version.hpp"

#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>

#include <csignal>
#include <cstdlib>

using namespace osrm;

void removeLocks() { storage::SharedMonitor<storage::SharedDataTimestamp>::remove(); }

void deleteRegion(const storage::SharedDataType region)
{
    if (storage::SharedMemory::RegionExists(region) && !storage::SharedMemory::Remove(region))
    {
        util::Log(logWARNING) << "could not delete shared memory region "
                              << storage::regionToString(region);
    }
}

void springClean()
{
    osrm::util::Log() << "Releasing all locks";
    osrm::util::Log() << "ATTENTION! BE CAREFUL!";
    osrm::util::Log() << "----------------------";
    osrm::util::Log() << "This tool may put osrm-routed into an undefined state!";
    osrm::util::Log() << "Type 'Y' to acknowledge that you know what your are doing.";
    osrm::util::Log() << "\n\nDo you want to purge all shared memory allocated "
                      << "by osrm-datastore? [type 'Y' to confirm]";

    const auto letter = getchar();
    if (letter != 'Y')
    {
        osrm::util::Log() << "aborted.";
    }
    else
    {
        deleteRegion(storage::REGION_1);
        deleteRegion(storage::REGION_2);
        removeLocks();
    }
}

// generate boost::program_options object for the routing part
bool generateDataStoreOptions(const int argc,
                              const char *argv[],
                              std::string &verbosity,
                              boost::filesystem::path &base_path,
                              int &max_wait)
{
    // declare a group of options that will be allowed only on command line
    boost::program_options::options_description generic_options("Options");
    generic_options.add_options()("version,v", "Show version")("help,h", "Show this help message")(
        "verbosity,l",
        boost::program_options::value<std::string>(&verbosity)->default_value("INFO"),
        std::string("Log verbosity level: " + util::LogPolicy::GetLevels()).c_str())(
        "remove-locks,r", "Remove locks")("spring-clean,s",
                                          "Spring-cleaning all shared memory regions");

    // declare a group of options that will be allowed both on command line
    // as well as in a config file
    boost::program_options::options_description config_options("Configuration");
    config_options.add_options()("max-wait",
                                 boost::program_options::value<int>(&max_wait)->default_value(-1),
                                 "Maximum number of seconds to wait on a running data update "
                                 "before aquiring the lock by force.");

    // hidden options, will be allowed on command line but will not be shown to the user
    boost::program_options::options_description hidden_options("Hidden options");
    hidden_options.add_options()("base,b",
                                 boost::program_options::value<boost::filesystem::path>(&base_path),
                                 "base path to .osrm file");

    // positional option
    boost::program_options::positional_options_description positional_options;
    positional_options.add("base", 1);

    // combine above options for parsing
    boost::program_options::options_description cmdline_options;
    cmdline_options.add(generic_options).add(config_options).add(hidden_options);

    const auto *executable = argv[0];
    boost::program_options::options_description visible_options(
        boost::filesystem::path(executable).filename().string() + " [<options>] <configuration>");
    visible_options.add(generic_options).add(config_options);

    // print help options if no infile is specified
    if (argc < 2)
    {
        util::Log() << visible_options;
        return false;
    }

    // parse command line options
    boost::program_options::variables_map option_variables;

    try
    {
        boost::program_options::store(boost::program_options::command_line_parser(argc, argv)
                                          .options(cmdline_options)
                                          .positional(positional_options)
                                          .run(),
                                      option_variables);
    }
    catch (const boost::program_options::error &e)
    {
        util::Log(logERROR) << e.what();
        return false;
    }

    if (option_variables.count("version"))
    {
        util::Log() << OSRM_VERSION;
        return false;
    }

    if (option_variables.count("help"))
    {
        util::Log() << visible_options;
        return false;
    }

    if (option_variables.count("remove-locks"))
    {
        removeLocks();
        return false;
    }

    if (option_variables.count("spring-clean"))
    {
        springClean();
        return false;
    }

    boost::program_options::notify(option_variables);

    return true;
}

[[noreturn]] void CleanupSharedBarriers(int signum)
{ // Here the lock state of named mutexes is unknown, make a hard cleanup
    removeLocks();
    std::_Exit(128 + signum);
}

int main(const int argc, const char *argv[]) try
{
    int signals[] = {SIGTERM, SIGSEGV, SIGINT, SIGILL, SIGABRT, SIGFPE};
    for (auto sig : signals)
    {
        std::signal(sig, CleanupSharedBarriers);
    }

    util::LogPolicy::GetInstance().Unmute();

    std::string verbosity;
    boost::filesystem::path base_path;
    int max_wait = -1;
    if (!generateDataStoreOptions(argc, argv, verbosity, base_path, max_wait))
    {
        return EXIT_SUCCESS;
    }

    util::LogPolicy::GetInstance().SetLevel(verbosity);

    storage::StorageConfig config(base_path);
    if (!config.IsValid())
    {
        util::Log(logERROR) << "Config contains invalid file paths. Exiting!";
        return EXIT_FAILURE;
    }
    storage::Storage storage(std::move(config));

    return storage.Run(max_wait);
}
catch (const osrm::RuntimeError &e)
{
    util::Log(logERROR) << e.what();
    return e.GetCode();
}
catch (const std::bad_alloc &e)
{
    util::DumpMemoryStats();
    util::Log(logERROR) << "[exception] " << e.what();
    util::Log(logERROR) << "Please provide more memory or disable locking the virtual "
                           "address space (note: this makes OSRM swap, i.e. slow)";
    return EXIT_FAILURE;
}