text:
// https://AudioProcessingFramework.github.io/

/// @file
/// A (under certain circumstances) realtime-safe list.

#ifndef APF_RTLIST_H
#define APF_RTLIST_H

#include <list>
#include <algorithm>  // for std::find()

#include "apf/commandqueue.h"

namespace apf
{

template<typename T> class RtList; // no implementation, use <T*>!

/** A list for realtime access and non-realtime modification.
 * It is normally used by a realtime thread and a non-realtime thread at the
 * same time.
 *
 * The list is created and modified (using add(), rem(), ...) by the
 * non-realtime thread. These functions are not safe for multiple non-realtime
 * threads; access has to be locked in this case.
 *
 * Before the realtime thread can access the list elements, it has to call
 * CommandQueue::process_commands() to synchronize.
 *
 * TODO: more information about which functions are allowed in which thread.
 **/
template<typename T>
class RtList<T*> : NonCopyable
{
  public:
    using list_t = typename std::list<T*>;
    using value_type = typename list_t::value_type;
    using size_type = typename list_t::size_type;
    using iterator = typename list_t::iterator;
    using const_iterator = typename list_t::const_iterator;

    class AddCommand;  // no implementation, use <T*>!
    class RemCommand;  // no implementation, use <T*>!
    class ClearCommand;  // no implementation, use <T*>!

    // Default constructor is not allowed!

    /// Constructor.
    /// @param fifo the CommandQueue
    explicit RtList(CommandQueue& fifo)
      : _fifo(fifo)
    {}

    /// Destructor.
    /// Elements can be removed - via rem() or clear() - before
    /// the destructor is called. But if not, they are deleted here.
    ~RtList()
    {
      for (auto& delinquent: _the_actual_list) delete delinquent;
      _the_actual_list.clear();
    }

    /// Add an element to the list.
    /// @param item Pointer to the list item
    /// @return the same pointer
    /// @note Ownership is passed to the list!
    template<typename X>
    X* add(X* item)
    {
      _fifo.push(new AddCommand(_the_actual_list, item));
      return item;
    }

    /// Add a range of elements to the list.
    /// @param first Begin of range to be added
    /// @param last End of range to be added
    /// @note Ownership is passed to the list!
    template<typename ForwardIterator>
    void add(ForwardIterator first, ForwardIterator last)
    {
      _fifo.push(new AddCommand(_the_actual_list, first, last));
    }

    /// Remove an element from the list.
    void rem(T* to_rem)
    {
      _fifo.push(new RemCommand(_the_actual_list, to_rem));
    }

    /// Remove a range of elements from the list.
    /// @param first Iterator to the first item
    /// @param last Past-the-end iterator
    template<typename ForwardIterator>
    void rem(ForwardIterator first, ForwardIterator last)
    {
      _fifo.push(new RemCommand(_the_actual_list, first, last));
    }

    /// Remove all elements from the list.
    void clear()
    {
      _fifo.push(new ClearCommand(_the_actual_list));
    }

    /// Splice another RtList into the RtList. @see @c std::list::splice()
    void splice(iterator position, RtList& x)
    {
      assert(&_fifo == &x._fifo);
      _the_actual_list.splice(position, x._the_actual_list);
    }

    /// Splice a part of another RtList into the RtList.
    void splice(iterator position, RtList& x, iterator first, iterator last)
    {
      assert(&_fifo == &x._fifo);
      _the_actual_list.splice(position, x._the_actual_list, first, last);
    }

    ///@{ @name Functions to be called from the realtime thread
    iterator       begin()       { return _the_actual_list.begin(); }
    const_iterator begin() const { return _the_actual_list.begin(); }
    iterator       end()         { return _the_actual_list.end(); }
    const_iterator end()   const { return _the_actual_list.end(); }
    bool           empty() const { return _the_actual_list.empty(); }
    size_type      size()  const { return _the_actual_list.size(); }
    ///@}

  private:
    CommandQueue& _fifo;
    list_t _the_actual_list;
};

/// Command to add an element to a list.
template<typename T>
class RtList<T*>::AddCommand : public CommandQueue::Command
{
  public:
    /// Constructor to add a single item.
    /// @param dst_list List to which the element will be added
    /// @param element Pointer to the element that will be added
    AddCommand(list_t& dst_list, T* element)
      : _splice_list(1, element) // make list with one element
      , _dst_list(dst_list)
    {
      assert(element != nullptr);
    }

    /// Constructor to add a bunch of items at once.
    /// @param dst_list List to which the elements will be added
    /// @param first Iterator to the first item to be added
    /// @param last Past-the-end iterator
    template<typename InputIterator>
    AddCommand(list_t& dst_list, InputIterator first, InputIterator last)
      : _splice_list(first, last)
      , _dst_list(dst_list)
    {}

    virtual void execute()
    {
      _dst_list.splice(_dst_list.end(), _splice_list);
    }

    // Empty function, because no cleanup is necessary
    virtual void cleanup() {}

  private:
    list_t _splice_list;  // List of elements to be added
    list_t& _dst_list;  // Destination list
};

/// Command to remove an element from a list.
template<typename T>
class RtList<T*>::RemCommand : public CommandQueue::Command
{
  public:
    /// Constructor to remove a single item.
    /// @param dst_list List from which the item will be removed
    /// @param delinquent Pointer to the item which will be removed
    RemCommand(list_t& dst_list, T* delinquent)
      : _dst_list(dst_list)
      , _delinquents(1, delinquent)
    {}

    /// Constructor to remove a bunch of items at once.
    /// @param dst_list List from which the elements will be removed
    /// @param first Iterator to first item to be removed
    /// @param last Past-the-end iterator
    template<typename InputIterator>
    RemCommand(list_t& dst_list, InputIterator first, InputIterator last)
      : _dst_list(dst_list)
      , _delinquents(first, last)
    {}

    /// The actual implementation of the command.
    /// @throw std::logic_error if item(s) is/are not found
    virtual void execute()
    {
      for (auto& i: _delinquents)
      {
        auto delinquent = std::find(_dst_list.begin(), _dst_list.end(), i);
        if (delinquent != _dst_list.end())
        {
          // Note: destruction order is reverse
          _splice_list.splice(_splice_list.begin(), _dst_list, delinquent);
        }
        else
        {
          throw std::logic_error("RemCommand: Item not found!");
        }
      }
    }

    // this might be dangerous/unexpected.
    // but i would need a synchronized Command, which waited
    // for the operation to complete, otherwise.
    virtual void cleanup()
    {
      for (auto& delinquent: _splice_list) delete delinquent;
      _splice_list.clear();
    }

  private:
    list_t _splice_list;  // List of elements to be removed
    list_t& _dst_list;  // Destination list
    list_t _delinquents;  // Temporary list of elements to be removed
};

/// Command to remove all elements from a list.
template<typename T>
class RtList<T*>::ClearCommand : public CommandQueue::Command
{
  public:
    /// Constructor.
    /// @param dst_list List from which all elements will be removed
    ClearCommand(list_t& dst_list)
      : _dst_list(dst_list)
    {}

    virtual void execute()
    {
      _delinquents.swap(_dst_list);
    }

    virtual void cleanup()
    {
      for (auto& delinquent: _delinquents) delete delinquent;
      _delinquents.clear();
    }

  private:
    list_t _delinquents;  ///< List of elements to be removed
    list_t& _dst_list;  ///< Destination list
};

}  // namespace apf

#endif


text:
#include "tensorflow/contrib/tensorrt/segment/segment.h"

#include <set>
#include <unordered_map>
#include <vector>

#include "tensorflow/contrib/tensorrt/segment/union_find.h"
#include "tensorflow/core/graph/algorithm.h"
#include "tensorflow/core/graph/graph.h"
#include "tensorflow/core/graph/graph_constructor.h"
#include "tensorflow/core/lib/core/errors.h"
#include "tensorflow/core/lib/core/status.h"
#include "tensorflow/core/lib/strings/strcat.h"
#include "tensorflow/core/platform/types.h"

namespace tensorflow {
namespace tensorrt {
namespace segment {
using ::tensorflow::strings::StrAppend;
// A simple graph representation to mirror tensorflow::Graph. This structure
// helps saving memory since segmenter modifies the graph in place, preventing
// the need to create a copy of the graph. It is composed of edges and nodes.
// Nodes keep pointers to original TF nodes.
class SimpleNode;
class SimpleGraph;
class SimpleEdge {
 public:
  SimpleEdge(int id, SimpleNode* src, int src_port, SimpleNode* dst,
             int dst_port, bool is_control = false)
      : id_(id),
        src_(src),
        src_port_(src_port),
        dst_(dst),
        dst_port_(dst_port),
        control_(is_control) {}
  ~SimpleEdge() {}

  SimpleNode* src() const { return src_; }
  SimpleNode* dst() const { return dst_; }
  int src_output() const { return src_port_; }
  int dst_input() const { return dst_port_; }
  int id() const { return id_; }
  bool IsControlEdge() const { return control_; }

 private:
  int id_;
  SimpleNode* src_;
  int src_port_;
  SimpleNode* dst_;
  int dst_port_;
  bool control_;
};

class SimpleNode {
 public:
  SimpleNode(const tensorflow::Node* node, const int id);

  const std::vector<SimpleEdge*>& in_edges() const { return in_edges_; }
  const std::vector<SimpleEdge*>& out_edges() const { return out_edges_; }
  std::vector<SimpleNode*> in_nodes() const {
    std::vector<SimpleNode*> res;
    res.reserve(in_edges_.size());
    for (const auto e : in_edges_) {
      if (e) res.push_back(e->src());
    }
    return res;
  }
  const string& name() const { return node_->name(); }
  const tensorflow::Node* tf_node() const { return node_; }
  int id() const { return id_; }

 private:
  const tensorflow::Node* node_;
  std::vector<SimpleEdge*> in_edges_;
  std::vector<SimpleEdge*> out_edges_;
  int id_;

  friend class SimpleGraph;
};

class SimpleGraph {
 public:
  explicit SimpleGraph(const tensorflow::Graph* g);
  ~SimpleGraph();

  void AddControlEdge(SimpleNode* src, SimpleNode* dst);
  void AddEdge(SimpleNode* src, int out_port, SimpleNode* dst, int in_port);
  void RemoveEdge(const SimpleEdge*);
  SimpleNode* FindNodeId(int node_id) {
    if (node_id < 0 || node_id > static_cast<int>(nodes_.size())) {
      return nullptr;
    }
    return nodes_[node_id];
  }
  int num_node_ids() const { return nodes_.size(); }
  const SimpleNode* source_node() const {
    return nodes_[tensorflow::Graph::kSourceId];
  }
  const SimpleNode* sink_node() const {
    return nodes_[tensorflow::Graph::kSinkId];
  }

 private:
  const tensorflow::Graph* g_;
  std::vector<SimpleNode*> nodes_;
  std::vector<SimpleEdge*> edges_;
  // free_edge_ids_ and free_node_ids_ contain freed indices.
  std::set<int> free_edge_ids_;
  std::set<int> free_node_ids_;
};

SimpleNode::SimpleNode(const tensorflow::Node* node, const int id)
    : node_(node), id_(id) {
  if (node_) {
    in_edges_.reserve(node_->in_edges().size());
    out_edges_.reserve(node_->out_edges().size());
  }
}

SimpleGraph::SimpleGraph(const tensorflow::Graph* g) : g_(g) {
  int n_nodes = g_->num_node_ids();
  nodes_.resize(n_nodes, nullptr);
  nodes_[g->kSourceId] = new SimpleNode(g->source_node(), g->kSourceId);
  nodes_[g->kSinkId] = new SimpleNode(g->sink_node(), g->kSinkId);
  int n_edges = g->num_edge_ids();
  edges_.resize(n_edges, nullptr);
  for (int i = 2; i < n_nodes; i++) {
    const auto n = g->FindNodeId(i);
    if (n) {
      nodes_[i] = new SimpleNode(n, i);
    } else {
      free_node_ids_.insert(i);
    }
  }
  for (int i = 0; i < n_edges; i++) {
    const auto e = g->FindEdgeId(i);
    if (e) {
      const auto tfsrc = e->src();
      const auto tfdst = e->dst();
      bool is_control = e->IsControlEdge();
      auto src = nodes_[tfsrc->id()];
      auto dst = nodes_[tfdst->id()];
      auto edge = new SimpleEdge(i, src, e->src_output(), dst, e->dst_input(),
                                 is_control);
      edges_[i] = edge;
      src->out_edges_.push_back(edge);
      dst->in_edges_.push_back(edge);
    } else {
      free_edge_ids_.insert(i);
    }
  }
}

void SimpleGraph::AddEdge(SimpleNode* src, int out_port, SimpleNode* dst,
                          int in_port) {
  int i = edges_.size();
  if (!free_edge_ids_.empty()) {
    auto it = free_edge_ids_.begin();
    i = *it;
    free_edge_ids_.erase(it);
  } else {
    edges_.push_back(nullptr);
  }
  bool is_control = (out_port == tensorflow::Graph::kControlSlot);
  is_control |= (in_port == tensorflow::Graph::kControlSlot);
  auto edge = new SimpleEdge(i, src, out_port, dst, in_port, is_control);
  edges_[i] = edge;
  src->out_edges_.push_back(edge);
  dst->in_edges_.push_back(edge);
}

void SimpleGraph::AddControlEdge(SimpleNode* src, SimpleNode* dst) {
  AddEdge(src, tensorflow::Graph::kControlSlot, dst,
          tensorflow::Graph::kControlSlot);
}

void SimpleGraph::RemoveEdge(const SimpleEdge* edge) {
  auto src = edge->src();
  auto dst = edge->dst();
  for (auto it = src->out_edges_.begin(); it != src->out_edges_.end(); ++it) {
    if (*it == edge) {
      src->out_edges_.erase(it);
      break;
    }
  }
  for (auto it = dst->in_edges_.begin(); it != dst->in_edges_.end(); ++it) {
    if (*it == edge) {
      dst->in_edges_.erase(it);
      break;
    }
  }
}

SimpleGraph::~SimpleGraph() {
  for (auto x : nodes_) delete x;
  for (auto x : edges_) delete x;
}

namespace {

bool CheckCycles(const std::unique_ptr<SimpleGraph>& g, const SimpleNode* src,
                 const std::vector<SimpleNode*>& start) {
  // copied from TF ReverseDFS.
  struct Work {
    SimpleNode* node;
    bool leave;  // Are we entering or leaving n?
  };

  std::vector<Work> stack(start.size());
  for (int i = 0; i < start.size(); ++i) {
    stack[i] = Work{start[i], false};
  }

  std::vector<bool> visited(g->num_node_ids(), false);
  while (!stack.empty()) {
    Work w = stack.back();
    stack.pop_back();

    auto n = w.node;
    if (w.leave) {
      if (n == src) {
        return true;
      }
      continue;
    }

    if (visited[n->id()]) continue;
    visited[n->id()] = true;
    // Arrange to call leave(n) when all done with descendants.
    stack.push_back(Work{n, true});

    auto nodes = n->in_nodes();
    for (const auto node : nodes) {
      if (!visited[node->id()]) {
        stack.push_back(Work{node, false});
      }
    }
  }
  return false;
}

bool CanContractEdge(const SimpleEdge* edge,
                     const std::unique_ptr<SimpleGraph>& graph) {
  const auto src = edge->src();
  const auto dst = edge->dst();

  // Can't contract edge if doing so would cause a cycle in the
  // graph. So, if there is a directed path from 'src' to 'dst', other
  // than 'edge' (or any other direct edge from 'src' to 'dst'), then
  // combining 'src' and 'dst' will cause a cycle along that path.
  //
  // In practice, to avoid modifying the graph and to take advantage
  // of existing graph functions, we perform an equivalent.
  //   1. Get all nodes incoming to 'dst', excluding 'src'
  //   2. Reverse DFS from those nodes
  //   3. If reverse DFS reaches 'src' then we have a cycle
  std::vector<SimpleNode*> dfs_start_nodes;
  for (SimpleNode* node : dst->in_nodes()) {
    if (node != src) {
      dfs_start_nodes.push_back(node);
    }
  }

  bool is_cycle = CheckCycles(graph, src, dfs_start_nodes);
  return !is_cycle;
}
}  // namespace

void ContractEdge(SimpleEdge* edge, SimpleGraph* graph,
                  std::vector<const SimpleEdge*>* remove_edges) {
  // Transfer all inputs and outputs of 'dst' to 'src' except edges
  // connecting the two.
  auto src = edge->src();
  auto dst = edge->dst();

  // We can use '0' for input/output index because we don't need them
  // to be accurate for the way we are using the graph.
  std::vector<const SimpleEdge*> in_edges(dst->in_edges().begin(),
                                          dst->in_edges().end());
  for (const SimpleEdge* in_edge : in_edges) {
    if (in_edge->IsControlEdge()) {
      if (in_edge->src() != src) {
        SimpleEdge* e = const_cast<SimpleEdge*>(in_edge);
        graph->AddControlEdge(e->src(), src);
      }
    } else {
      if (in_edge->src() != src) {
        SimpleEdge* e = const_cast<SimpleEdge*>(in_edge);
        if (e->src() == graph->source_node()) {
          graph->AddEdge(e->src(), e->src_output(), src,
                         tensorflow::Graph::kControlSlot);
        } else {
          graph->AddEdge(e->src(), e->src_output(), src, 0 /* input index */);
        }
      }
    }
  }

  std::vector<const SimpleEdge*> out_edges(dst->out_edges().begin(),
                                           dst->out_edges().end());
  for (const SimpleEdge* out_edge : out_edges) {
    if (out_edge->IsControlEdge()) {
      SimpleEdge* e = const_cast<SimpleEdge*>(out_edge);
      graph->AddControlEdge(src, e->dst());
    } else {
      SimpleEdge* e = const_cast<SimpleEdge*>(out_edge);
      if (e->dst() == graph->sink_node()) {
        VLOG(1) << " edge to sink node " << src->name() << " -> "
                << e->dst()->name();
        graph->AddEdge(src, tensorflow::Graph::kControlSlot, e->dst(),
                       e->dst_input());
      } else {
        graph->AddEdge(src, 0 /* output index */, e->dst(), e->dst_input());
      }
    }
  }

  // Return the edges that must be removed to disconnect 'dst' from
  // the graph. We don't actually remove 'dst' since the caller holds
  // references to all the nodes.
  for (const auto& in_edge : dst->in_edges()) {
    remove_edges->push_back(in_edge);
  }
  for (const auto& out_edge : dst->out_edges()) {
    remove_edges->push_back(out_edge);
  }
}

tensorflow::Status SegmentGraph(
    const tensorflow::GraphDef& gdef,
    const std::function<bool(const tensorflow::Node*)>& candidate_fn,
    const SegmentOptions& options, SegmentNodesVector* segments) {
  // Create a Graph representation of the GraphDef.
  tensorflow::FunctionLibraryDefinition flib(tensorflow::OpRegistry::Global(),
                                             gdef.library());
  tensorflow::Graph graph(flib);
  TF_RETURN_IF_ERROR(tensorflow::ConvertGraphDefToGraph(
      tensorflow::GraphConstructorOptions(), gdef, &graph));
  return SegmentGraph(&graph, candidate_fn, options, segments);
}

tensorflow::Status SegmentGraph(
    tensorflow::Graph* tf_graph,
    const std::function<bool(const tensorflow::Node*)>& candidate_fn,
    const SegmentOptions& options, SegmentNodesVector* segments) {
  auto graph = std::unique_ptr<SimpleGraph>(new SimpleGraph(tf_graph));
  // Use a union-find to collect the nodes that belong to the same
  // segment. A node value of nullptr indicates that the node is not a candidate
  // for TRT.
  std::vector<UnionFind<SimpleNode*>> node_segments;
  for (int i = 0; i < graph->num_node_ids(); ++i) {
    SimpleNode* node = graph->FindNodeId(i);
    if (options.exclude_node_list.count(node->name()) != 0 ||
        !candidate_fn(node->tf_node())) {
      node = nullptr;
    }
    node_segments.emplace_back(node);
  }

  // The segmentation algorithm below visits nodes in reverse
  // topological order and attempts to merge nodes along output
  // edges. That means that subgraphs grow from the output-side of the
  // network towards the inputs. In general this is not guaranteed to
  // produce a globally optimal segmentation. In the future if we have
  // a measure of how beneficial it is to include a given node in a
  // TRT subgraph then we can revisit this algorithm to take advantage
  // of that information.
  std::vector<tensorflow::Node*> tforder;
  tensorflow::GetPostOrder(*tf_graph, &tforder);
  // use postorder implementation from tensorflow and construct mirror in
  // internal format
  std::vector<SimpleNode*> order;
  order.reserve(tforder.size());
  for (const auto tfnode : tforder) {
    order.push_back(graph->FindNodeId(tfnode->id()));
  }
  for (const SimpleNode* node : order) {
    // All output nodes of 'node' have been visited...
    VLOG(2) << "Trying node " << node->name() << " id=" << node->id();

    // 'node' must be a TRT candidate...
    if (node_segments[node->id()].Value() == nullptr) {
      VLOG(2) << "... not a TRT candidate";
      continue;
    }

    // Contract output edges to combine 'node' with output
    // nodes. Iterate since combining two nodes may unblock other
    // combining.
    while (true) {
      std::set<const SimpleEdge*> contract_edges;
      for (const SimpleEdge* out_edge : node->out_edges()) {
        VLOG(2) << "... out node " << out_edge->dst()->name() << " ( "
                << out_edge->dst()->id() << " <- " << node->id() << " )";
        if (out_edge->IsControlEdge()) {
          VLOG(2) << "... ... Control Edge, Skipping";
          continue;
        }
        // Out node must be TRT candidate...
        if (node_segments[out_edge->dst()->id()].Value() == nullptr) {
          VLOG(2) << "... ... not a TRT candidate";
          continue;
        }

        if (CanContractEdge(out_edge, graph)) {
          VLOG(2) << "... ... can contract";
          contract_edges.insert(out_edge);
        } else {
          VLOG(2) << "... ... cannot contract, would form cycle";
        }
      }

      if (contract_edges.empty()) {
        break;
      }

      // Contract edges and collect the adjacent nodes into the same
      // segment/subgraph.
      while (!contract_edges.empty()) {
        const SimpleEdge* contract_edge = *contract_edges.begin();
        const SimpleNode* src = contract_edge->src();
        const SimpleNode* dst = contract_edge->dst();

        VLOG(2) << "Merge " << src->name() << " <- " << dst->name() << " ("
                << src->id() << " <- " << dst->id();
        node_segments[src->id()].Merge(&node_segments[dst->id()]);

        // Contracting the edge leaves disconnected graph edges.
        // Remove these from the graph and from 'contract_edges' so we
        // don't visit them again.
        SimpleEdge* e = const_cast<SimpleEdge*>(contract_edge);
        std::vector<const SimpleEdge*> remove_edges;
        ContractEdge(e, graph.get(), &remove_edges);

        for (const SimpleEdge* r : remove_edges) {
          contract_edges.erase(r);
          graph->RemoveEdge(r);
        }
      }
    }
  }

  // Collect the segments/subgraphs. Each subgraph is represented by a
  // set of the names of the nodes in that subgraph.
  std::unordered_map<string, std::set<string>> sg_map;
  std::unordered_map<string, std::set<string>> device_maps;
  for (auto& u : node_segments) {
    if ((u.Value() != nullptr) && (u.ParentValue() != nullptr)) {
      sg_map[u.ParentValue()->name()].insert(u.Value()->name());
      auto tf_node = u.Value()->tf_node();
      // has_assigned_device_name() is expected to return true
      // when called from optimization pass. However, since graph
      // is converted back and forth between graph and graphdef,
      // assigned devices demoted to requested devices. If the graph
      // is passed directly to this module, assigned devices will be set.
      if (tf_node->has_assigned_device_name()) {
        device_maps[u.ParentValue()->name()].insert(
            tf_node->assigned_device_name());
      } else if (!tf_node->requested_device().empty()) {
        device_maps[u.ParentValue()->name()].insert(
            tf_node->requested_device());
      } else {
        VLOG(1) << "Node " << tf_node->name()
                << " has no device assigned requested device is: "
                << tf_node->requested_device();
      }
    }
  }

  // Convert the segments into the expected return format
  for (const auto& itr : sg_map) {
    const auto& segment_node_names = itr.second;
    if (VLOG_IS_ON(1)) {
      string s;
      for (const auto& name : segment_node_names) {
        s += " " + name;
      }
      VLOG(1) << "Segment " << segments->size() << ":" << s;
    }

    // Don't use small segments.
    if (static_cast<int>(segment_node_names.size()) <
        options.minimum_segment_size) {
      VLOG(1) << "Segment " << segments->size() << " has only "
              << segment_node_names.size() << " nodes, dropping";
      continue;
    }
    // TODO(sami): Make segmenter placement aware once trtscopes are in place
    const auto& dev_itr = device_maps.find(itr.first);
    if (dev_itr == device_maps.end() || dev_itr->second.empty()) {
      VLOG(1) << "No device assigned to segment " << segments->size();
      segments->emplace_back(std::make_pair(segment_node_names, string()));
    } else if (dev_itr->second.size() > 1) {
      string s("Segment ");
      StrAppend(&s, segments->size(), " has multiple devices attached: ");
      for (const auto& dev : dev_itr->second) {
        StrAppend(&s, dev, ", ");
      }
      LOG(WARNING) << s << " choosing " << *(dev_itr->second.begin());
      segments->emplace_back(
          std::make_pair(segment_node_names, *(dev_itr->second.begin())));
    } else {
      segments->emplace_back(
          std::make_pair(segment_node_names, *(dev_itr->second.begin())));
    }
  }
  if (VLOG_IS_ON(1)) {
    for (const auto& d : device_maps) {
      string s("Segment ");
      StrAppend(&s, ": '", d.first, "' ");
      for (const auto& dd : d.second) {
        StrAppend(&s, dd, ", ");
      }
      VLOG(1) << "Devices " << s;
    }
  }
  return tensorflow::Status::OK();
}

}  // namespace segment
}  // namespace tensorrt
}  // namespace tensorflow

redpajama_set_name: RedPajamaGithub


text:
r"""
This is a Bot to add a text at the end of the content of the page.

By default it adds the text above categories, interwiki and template
for the stars of the interwiki.

Alternatively it may also add a text at the top of the page.
These command line parameters can be used to specify which pages to work on:

&params;

Furthermore, the following command line parameters are supported:

-talkpage         Put the text onto the talk page instead the generated on
-talk

-text             Define which text to add. "\n" are interpreted as newlines.

-textfile         Define a texfile name which contains the text to add

-summary          Define the summary to use

-except           Use a regex to check if the text is already in the page

-excepturl        Use the html page as text where you want to see if there's
                  the text, not the wiki-page.

-newimages        Add text in the new images

-always           If used, the bot won't ask if it should add the text
                  specified

-up               If used, put the text at the top of the page

-noreorder        Avoid to reorder cats and interwiki

--- Example ---
1.
# This is a script to add a template to the top of the pages with
# category:catname
# Warning! Put it in one line, otherwise it won't work correctly.
from __future__ import unicode_literals

python add_text.py -cat:catname -summary:"Bot: Adding a template"
-text:"{{Something}}" -except:"\{\{([Tt]emplate:|)[Ss]omething" -up

2.
# Command used on it.wikipedia to put the template in the page without any
# category.
# Warning! Put it in one line, otherwise it won't work correctly.

python add_text.py -excepturl:"class='catlinks'>" -uncat
-text:"{{Categorizzare}}" -except:"\{\{([Tt]emplate:|)[Cc]ategorizzare"
-summary:"Bot: Aggiungo template Categorizzare"

--- Credits and Help ---
This script has been written by Botwiki's staff, if you want to help us
or you need some help regarding this script, you can find us here:

* http://botwiki.sno.cc/wiki/Main_Page

"""

#
# (C) Filnik, 2007-2010
# (C) Pywikibot team, 2007-2015
#
# Distributed under the terms of the MIT license.
#
__version__ = '$Id$'
#

import re
import codecs
import time

import pywikibot
from pywikibot import config, i18n, pagegenerators, textlib

docuReplacements = {
    '&params;': pagegenerators.parameterHelp,
}

starsList = [
    u'bueno',
    u'bom interwiki',
    u'cyswllt[ _]erthygl[ _]ddethol', u'dolen[ _]ed',
    u'destacado', u'destaca[tu]',
    u'enllaç[ _]ad',
    u'enllaz[ _]ad',
    u'leam[ _]vdc',
    u'legătură[ _]a[bcf]',
    u'liamm[ _]pub',
    u'lien[ _]adq',
    u'lien[ _]ba',
    u'liên[ _]kết[ _]bài[ _]chất[ _]lượng[ _]tốt',
    u'liên[ _]kết[ _]chọn[ _]lọc',
    u'ligam[ _]adq',
    u'ligazón[ _]a[bd]',
    u'ligoelstara',
    u'ligoleginda',
    u'link[ _][afgu]a', u'link[ _]adq', u'link[ _]f[lm]', u'link[ _]km',
    u'link[ _]sm', u'linkfa',
    u'na[ _]lotura',
    u'nasc[ _]ar',
    u'tengill[ _][úg]g',
    u'ua',
    u'yüm yg',
    u'רא',
    u'وصلة مقالة جيدة',
    u'وصلة مقالة مختارة',
]

def add_text(page, addText, summary=None, regexSkip=None,
             regexSkipUrl=None, always=False, up=False, putText=True,
             oldTextGiven=None, reorderEnabled=True, create=False):
    """
    Add text to a page.

    @rtype: tuple of (text, newtext, always)
    """
    site = page.site
    if not summary:
        summary = i18n.twtranslate(site, 'add_text-adding',
                                   {'adding': addText[:200]})

    # When a page is tagged as "really well written" it has a star in the
    # interwiki links. This is a list of all the templates used (in regex
    # format) to make the stars appear.

    errorCount = 0

    if putText:
        pywikibot.output(u'Loading %s...' % page.title())
    if oldTextGiven is None:
        try:
            text = page.get()
        except pywikibot.NoPage:
            if create:
                pywikibot.output(u"%s doesn't exist, creating it!"
                                 % page.title())
                text = u''
            else:
                pywikibot.output(u"%s doesn't exist, skip!" % page.title())
                return (False, False, always)
        except pywikibot.IsRedirectPage:
            pywikibot.output(u"%s is a redirect, skip!" % page.title())
            return (False, False, always)
    else:
        text = oldTextGiven
    # Understand if the bot has to skip the page or not
    # In this way you can use both -except and -excepturl
    if regexSkipUrl is not None:
        url = site.nice_get_address(page.title(asUrl=True))
        result = re.findall(regexSkipUrl, site.getUrl(url))
        if result != []:
            pywikibot.output(
u'''Exception! regex (or word) used with -exceptUrl is in the page. Skip!
Match was: %s''' % result)
            return (False, False, always)
    if regexSkip is not None:
        result = re.findall(regexSkip, text)
        if result != []:
            pywikibot.output(
u'''Exception! regex (or word) used with -except is in the page. Skip!
Match was: %s''' % result)
            return (False, False, always)
    # If not up, text put below
    if not up:
        newtext = text
        # Translating the \\n into binary \n
        addText = addText.replace('\\n', config.line_separator)
        if (reorderEnabled):
            # Getting the categories
            categoriesInside = textlib.getCategoryLinks(newtext, site)
            # Deleting the categories
            newtext = textlib.removeCategoryLinks(newtext, site)
            # Getting the interwiki
            interwikiInside = textlib.getLanguageLinks(newtext, site)
            # Removing the interwiki
            newtext = textlib.removeLanguageLinks(newtext, site)

            # Adding the text
            newtext += u"%s%s" % (config.line_separator, addText)
            # Reputting the categories
            newtext = textlib.replaceCategoryLinks(newtext,
                                                   categoriesInside, site,
                                                   True)
            # Dealing the stars' issue
            allstars = []
            starstext = textlib.removeDisabledParts(text)
            for star in starsList:
                regex = re.compile('(\{\{(?:template:|)%s\|.*?\}\}[\s]*)'
                                   % star, re.I)
                found = regex.findall(starstext)
                if found != []:
                    newtext = regex.sub('', newtext)
                    allstars += found
            if allstars != []:
                newtext = newtext.strip() + config.line_separator * 2
                allstars.sort()
                for element in allstars:
                    newtext += '%s%s' % (element.strip(), config.LS)
            # Adding the interwiki
            newtext = textlib.replaceLanguageLinks(newtext, interwikiInside,
                                                   site)
        else:
            newtext += u"%s%s" % (config.line_separator, addText)
    else:
        newtext = addText + config.line_separator + text
    if putText and text != newtext:
        pywikibot.output(u"\n\n>>> \03{lightpurple}%s\03{default} <<<"
                         % page.title())
        pywikibot.showDiff(text, newtext)
    # Let's put the changes.
    while True:
        # If someone load it as module, maybe it's not so useful to put the
        # text in the page
        if putText:
            if not always:
                choice = pywikibot.input_choice(
                    u'Do you want to accept these changes?',
                    [('Yes', 'y'), ('No', 'n'), ('All', 'a'),
                     ('open in Browser', 'b')], 'n', automatic_quit=False)
                if choice == 'a':
                    always = True
                elif choice == 'n':
                    return (False, False, always)
                elif choice == 'b':
                    pywikibot.bot.open_webbrowser(page)
            if always or choice == 'y':
                try:
                    if always:
                        page.put(newtext, summary,
                                 minorEdit=page.namespace() != 3)
                    else:
                        page.put_async(newtext, summary,
                                       minorEdit=page.namespace() != 3)
                except pywikibot.EditConflict:
                    pywikibot.output(u'Edit conflict! skip!')
                    return (False, False, always)
                except pywikibot.ServerError:
                    errorCount += 1
                    if errorCount < config.max_retries:
                        pywikibot.output(u'Server Error! Wait..')
                        time.sleep(config.retry_wait)
                        continue
                    else:
                        raise pywikibot.ServerError(u'Fifth Server Error!')
                except pywikibot.SpamfilterError as e:
                    pywikibot.output(
                        u'Cannot change %s because of blacklist entry %s'
                        % (page.title(), e.url))
                    return (False, False, always)
                except pywikibot.LockedPage:
                    pywikibot.output(u'Skipping %s (locked page)'
                                     % page.title())
                    return (False, False, always)
                except pywikibot.PageNotSaved as error:
                    pywikibot.output(u'Error putting page: %s' % error.args)
                    return (False, False, always)
                else:
                    # Break only if the errors are one after the other...
                    errorCount = 0
                    return (True, True, always)
        else:
            return (text, newtext, always)

def main(*args):
    """
    Process command line arguments and invoke bot.

    If args is an empty list, sys.argv is used.

    @param args: command line arguments
    @type args: list of unicode
    """
    # If none, the var is setted only for check purpose.
    summary = None
    addText = None
    regexSkip = None
    regexSkipUrl = None
    always = False
    textfile = None
    talkPage = False
    reorderEnabled = True

    # Put the text above or below the text?
    up = False

    # Process global args and prepare generator args parser
    local_args = pywikibot.handle_args(args)
    genFactory = pagegenerators.GeneratorFactory()

    # Loading the arguments
    for arg in local_args:
        if arg.startswith('-textfile'):
            if len(arg) == 9:
                textfile = pywikibot.input(
                    u'Which textfile do you want to add?')
            else:
                textfile = arg[10:]
        elif arg.startswith('-text'):
            if len(arg) == 5:
                addText = pywikibot.input(u'What text do you want to add?')
            else:
                addText = arg[6:]
        elif arg.startswith('-summary'):
            if len(arg) == 8:
                summary = pywikibot.input(u'What summary do you want to use?')
            else:
                summary = arg[9:]
        elif arg.startswith('-excepturl'):
            if len(arg) == 10:
                regexSkipUrl = pywikibot.input(u'What text should I skip?')
            else:
                regexSkipUrl = arg[11:]
        elif arg.startswith('-except'):
            if len(arg) == 7:
                regexSkip = pywikibot.input(u'What text should I skip?')
            else:
                regexSkip = arg[8:]
        elif arg == '-up':
            up = True
        elif arg == '-noreorder':
            reorderEnabled = False
        elif arg == '-always':
            always = True
        elif arg == '-talk' or arg == '-talkpage':
            talkPage = True
        else:
            genFactory.handleArg(arg)
    if textfile and not addText:
        with codecs.open(textfile, 'r', config.textfile_encoding) as f:
            addText = f.read()
    generator = genFactory.getCombinedGenerator()
    if not generator:
        pywikibot.showHelp()
        return
    if not addText:
        pywikibot.error("The text to add wasn't given.")
        return
    if talkPage:
        generator = pagegenerators.PageWithTalkPageGenerator(generator, True)
    for page in generator:
        (text, newtext, always) = add_text(page, addText, summary, regexSkip,
                                           regexSkipUrl, always, up, True,
                                           reorderEnabled=reorderEnabled,
                                           create=talkPage)

if __name__ == "__main__":
    main()


text:
package org.insightech.er.db.impl.postgres.tablespace;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;

import org.insightech.er.editor.model.diagram_contents.not_element.tablespace.TablespaceProperties;
import org.insightech.er.util.Check;

public class PostgresTablespaceProperties implements TablespaceProperties {

    private static final long serialVersionUID = -1168759105844875794L;

    private String location;

    private String owner;

    /**
     * location を取得します.
     *
     * @return location
     */
    public String getLocation() {
        return location;
    }

    /**
     * location を設定します.
     *
     * @param location
     *            location
     */
    public void setLocation(final String location) {
        this.location = location;
    }

    /**
     * owner を取得します.
     *
     * @return owner
     */
    public String getOwner() {
        return owner;
    }

    /**
     * owner を設定します.
     *
     * @param owner
     *            owner
     */
    public void setOwner(final String owner) {
        this.owner = owner;
    }

    @Override
    public TablespaceProperties clone() {
        final PostgresTablespaceProperties properties = new PostgresTablespaceProperties();

        properties.location = location;
        properties.owner = owner;

        return properties;
    }

    @Override
    public LinkedHashMap<String, String> getPropertiesMap() {
        final LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();

        map.put("label.tablespace.location", getLocation());
        map.put("label.tablespace.owner", getOwner());

        return map;
    }

    @Override
    public List<String> validate() {
        final List<String> errorMessage = new ArrayList<String>();

        if (Check.isEmptyTrim(getLocation())) {
            errorMessage.add("error.tablespace.location.empty");
        }

        return errorMessage;
    }
}


text:
_[www.codever.land/bookmarks/t/concurrency](https://www.codever.land/bookmarks/t/concurrency)_
---
#### [alpaka](https://github.com/ComputationalRadiationPhysics/alpaka)
_https://github.com/ComputationalRadiationPhysics/alpaka_

Abstraction library for parallel kernel acceleration. [LGPLv3+]
* **tags**: [cpp](../tagged/cpp.md), [concurrency](../tagged/concurrency.md)
* :octocat: **[source code](https://github.com/ComputationalRadiationPhysics/alpaka)**
---
#### [ArrayFire](https://github.com/arrayfire/arrayfire)
_https://github.com/arrayfire/arrayfire_

A general purpose GPU library. [BSD]
* **tags**: [cpp](../tagged/cpp.md), [concurrency](../tagged/concurrency.md)
* :octocat: **[source code](https://github.com/arrayfire/arrayfire)**
---
#### [Async++](https://github.com/Amanieu/asyncplusplus)
_https://github.com/Amanieu/asyncplusplus_

A lightweight concurrency framework for C++11, inspired by the Microsoft PPL library and the N3428 C++ standard proposal. [MIT]
* **tags**: [cpp](../tagged/cpp.md), [concurrency](../tagged/concurrency.md)
* :octocat: **[source code](https://github.com/Amanieu/asyncplusplus)**
---
#### [Boost.Compute](https://github.com/boostorg/compute)
_https://github.com/boostorg/compute_

A C++ GPU Computing Library for OpenCL. [Boost]
* **tags**: [cpp](../tagged/cpp.md), [concurrency](../tagged/concurrency.md)
* :octocat: **[source code](https://github.com/boostorg/compute)**
---
#### [Bolt](https://github.com/HSA-Libraries/Bolt)
_https://github.com/HSA-Libraries/Bolt_

A C++ template library optimized for GPUs. [Apache2]
* **tags**: [cpp](../tagged/cpp.md), [concurrency](../tagged/concurrency.md)
* :octocat: **[source code](https://github.com/HSA-Libraries/Bolt)**
---
#### [ck](https://github.com/concurrencykit/ck)
_https://github.com/concurrencykit/ck_

Concurrency primitives, safe memory reclamation mechanisms and non-blocking data structures. [BSD]
* **tags**: [cpp](../tagged/cpp.md), [concurrency](../tagged/concurrency.md)
* :octocat: **[source code](https://github.com/concurrencykit/ck)**
---
#### [concurrentqueue](https://github.com/cameron314/concurrentqueue)
_https://github.com/cameron314/concurrentqueue_

A fast multi-producer, multi-consumer lock-free concurrent queue for C++11. [BSD,Boost]
* **tags**: [cpp](../tagged/cpp.md), [concurrency](../tagged/concurrency.md)
* :octocat: **[source code](https://github.com/cameron314/concurrentqueue)**
---
#### [Cpp-Taskflow](https://github.com/cpp-taskflow/cpp-taskflow)
_https://github.com/cpp-taskflow/cpp-taskflow_

Fast C++ Parallel Programming with Task Dependencies. [MIT]
* **tags**: [cpp](../tagged/cpp.md), [concurrency](../tagged/concurrency.md)
* :octocat: **[source code](https://github.com/cpp-taskflow/cpp-taskflow)**
---
#### [CUB](https://github.com/NVlabs/cub)
_https://github.com/NVlabs/cub_

CUB provides state-of-the-art, reusable software components for every layer of the CUDA programming mode. [New BSD]
* **tags**: [cpp](../tagged/cpp.md), [concurrency](../tagged/concurrency.md)
* :octocat: **[source code](https://github.com/NVlabs/cub)**
---
#### [cupla](https://github.com/ComputationalRadiationPhysics/cupla)
_https://github.com/ComputationalRadiationPhysics/cupla_

C++ API to run CUDA/C++ on OpenMP, Threads, TBB, ... through Alpaka. [LGPLv3+]
* **tags**: [cpp](../tagged/cpp.md), [concurrency](../tagged/concurrency.md)
* :octocat: **[source code](https://github.com/ComputationalRadiationPhysics/cupla)**
---
#### [C++React](https://github.com/schlangster/cpp.react)
_https://github.com/schlangster/cpp.react_

A reactive programming library for C++11. [Boost]
* **tags**: [cpp](../tagged/cpp.md), [concurrency](../tagged/concurrency.md)
* :octocat: **[source code](https://github.com/schlangster/cpp.react)**
---
#### [FiberTaskingLib](https://github.com/RichieSams/FiberTaskingLib)
_https://github.com/RichieSams/FiberTaskingLib_

Task-based multi-threading library that supports task graphs with arbitrary dependencies. [Apache]
* **tags**: [cpp](../tagged/cpp.md), [concurrency](../tagged/concurrency.md)
* :octocat: **[source code](https://github.com/RichieSams/FiberTaskingLib)**
---
#### [Intel Games Task Scheduler](https://github.com/GameTechDev/GTS-GamesTaskScheduler)
_https://github.com/GameTechDev/GTS-GamesTaskScheduler_

A task scheduling framework designed for the needs of game developers. [MIT]
* **tags**: [cpp](../tagged/cpp.md), [concurrency](../tagged/concurrency.md)
* :octocat: **[source code](https://github.com/GameTechDev/GTS-GamesTaskScheduler)**
---
#### [Intel Parallel STL](https://github.com/intel/parallelstl)
_https://github.com/intel/parallelstl_

Intel® implementation of C++17 STL for C++11 and above. [Apache2]
* **tags**: [cpp](../tagged/cpp.md), [concurrency](../tagged/concurrency.md)
* :octocat: **[source code](https://github.com/intel/parallelstl)**
---
#### [Intel TBB](https://www.threadingbuildingblocks.org/)
_https://www.threadingbuildingblocks.org/_

Intel® Threading Building Blocks. [Apache2]
* **tags**: [cpp](../tagged/cpp.md), [concurrency](../tagged/concurrency.md)
---
#### [junction](https://github.com/preshing/junction)
_https://github.com/preshing/junction_

A library of concurrent data structures in C++. [BSD]
* **tags**: [cpp](../tagged/cpp.md), [concurrency](../tagged/concurrency.md)
* :octocat: **[source code](https://github.com/preshing/junction)**
---
#### [libcds](https://github.com/khizmax/libcds)
_https://github.com/khizmax/libcds_

A C++ library of Concurrent Data Structures. [BSD]
* **tags**: [cpp](../tagged/cpp.md), [concurrency](../tagged/concurrency.md)
* :octocat: **[source code](https://github.com/khizmax/libcds)**
---
#### [Libclsph](https://github.com/libclsph/libclsph)
_https://github.com/libclsph/libclsph_

An OpenCL based GPU accelerated SPH fluid simulation library. [MIT]
* **tags**: [cpp](../tagged/cpp.md), [concurrency](../tagged/concurrency.md)
* :octocat: **[source code](https://github.com/libclsph/libclsph)**
---
#### [libdill](https://github.com/sustrik/libdill/)
_https://github.com/sustrik/libdill/_

Introduces structured concurrency in C. [MIT]
* **tags**: [cpp](../tagged/cpp.md), [concurrency](../tagged/concurrency.md)
* :octocat: **[source code](https://github.com/sustrik/libdill/)**
---
#### [libdispatch](https://github.com/apple/swift-corelibs-libdispatch)
_https://github.com/apple/swift-corelibs-libdispatch_

Grand Central Dispatch (GCD), developed by Apple Inc., is a task parallelism technology based on the thread pool pattern. libdispatch is a library that provides the implementation of GCD's services. [...
* **tags**: [cpp](../tagged/cpp.md), [concurrency](../tagged/concurrency.md)
* :octocat: **[source code](https://github.com/apple/swift-corelibs-libdispatch)**
---
#### [libmill](https://github.com/sustrik/libmill/)
_https://github.com/sustrik/libmill/_

Introduces Go-style concurrency in C. [MIT]
* **tags**: [cpp](../tagged/cpp.md), [concurrency](../tagged/concurrency.md)
* :octocat: **[source code](https://github.com/sustrik/libmill/)**
---
#### [moderngpu](https://github.com/moderngpu/moderngpu)
_https://github.com/moderngpu/moderngpu_

moderngpu is a productivity library for general-purpose computing on GPUs. It is a header-only C++ library written for CUDA. The unique value of the library is in its accelerated primitives for solvin...
* **tags**: [cpp](../tagged/cpp.md), [concurrency](../tagged/concurrency.md)
* :octocat: **[source code](https://github.com/moderngpu/moderngpu)**
---
#### [NCCL](https://github.com/NVIDIA/nccl)
_https://github.com/NVIDIA/nccl_

Optimized primitives for collective multi-GPU communication. [BSD]
* **tags**: [cpp](../tagged/cpp.md), [concurrency](../tagged/concurrency.md)
* :octocat: **[source code](https://github.com/NVIDIA/nccl)**
---
#### [OpenCL](https://www.khronos.org/opencl/)
_https://www.khronos.org/opencl/_

The open standard for parallel programming of heterogeneous systems.
* **tags**: [cpp](../tagged/cpp.md), [concurrency](../tagged/concurrency.md)
---
#### [OpenMP](http://openmp.org/)
_http://openmp.org/_

The OpenMP API.
* **tags**: [cpp](../tagged/cpp.md), [concurrency](../tagged/concurrency.md)
---
#### [RaftLib](http://raftlib.io/)
_http://raftlib.io/_

The RaftLib C++ library, streaming/dataflow concurrency via C++ iostream-like operators [Apache2]
* **tags**: [cpp](../tagged/cpp.md), [concurrency](../tagged/concurrency.md)
---
#### [readerwriterqueue](https://github.com/cameron314/readerwriterqueue)
_https://github.com/cameron314/readerwriterqueue_

A fast single-producer, single-consumer lock-free queue for C++. [BSD]
* **tags**: [cpp](../tagged/cpp.md), [concurrency](../tagged/concurrency.md)
* :octocat: **[source code](https://github.com/cameron314/readerwriterqueue)**
---
#### [Thrust](http://thrust.github.io/)
_http://thrust.github.io/_

A parallel algorithms library which resembles the C++ Standard Template Library (STL). [Apache2]
* **tags**: [cpp](../tagged/cpp.md), [concurrency](../tagged/concurrency.md)
---
#### [transwarp](https://github.com/bloomen/transwarp)
_https://github.com/bloomen/transwarp_

A header-only C++ library for task concurrency. [MIT]
* **tags**: [cpp](../tagged/cpp.md), [concurrency](../tagged/concurrency.md)
* :octocat: **[source code](https://github.com/bloomen/transwarp)**
---
#### [HPX](https://github.com/STEllAR-GROUP/hpx/)
_https://github.com/STEllAR-GROUP/hpx/_

A general purpose C++ runtime system for parallel and distributed applications of any scale. [Boost]
* **tags**: [cpp](../tagged/cpp.md), [concurrency](../tagged/concurrency.md)
* :octocat: **[source code](https://github.com/STEllAR-GROUP/hpx/)**
---
#### [VexCL](https://github.com/ddemidov/vexcl)
_https://github.com/ddemidov/vexcl_

A C++ vector expression template library for OpenCL/CUDA. [MIT]
* **tags**: [cpp](../tagged/cpp.md), [concurrency](../tagged/concurrency.md)
* :octocat: **[source code](https://github.com/ddemidov/vexcl)**
---
#### [Quantum](https://github.com/bloomberg/quantum)
_https://github.com/bloomberg/quantum_

A powerful C++ coroutine dispatcher framework built on top of [boost::coroutines2](https://www.boost.org/doc/libs/1_65_0/libs/coroutine2/doc/html/index.html).
* **tags**: [cpp](../tagged/cpp.md), [concurrency](../tagged/concurrency.md)
* :octocat: **[source code](https://github.com/bloomberg/quantum)**
---
#### [aymanmadkour/glock](https://github.com/aymanmadkour/glock)
_https://github.com/aymanmadkour/glock_

Granular locking crate for Rust. Contribute to aymanmadkour/glock development by creating an account on GitHub.
* **tags**: [rust](../tagged/rust.md), [concurrency](../tagged/concurrency.md)
* :octocat: **[source code](https://github.com/aymanmadkour/glock)**
---
#### [crossbeam-rs/crossbeam](https://github.com/crossbeam-rs/crossbeam)
_https://github.com/crossbeam-rs/crossbeam_

Tools for concurrent programming in Rust. Contribute to crossbeam-rs/crossbeam development by creating an account on GitHub.
* **tags**: [rust](../tagged/rust.md), [concurrency](../tagged/concurrency.md)
* :octocat: **[source code](https://github.com/crossbeam-rs/crossbeam)**
---
#### [pop-os/bus-writer](https://github.com/pop-os/bus-writer)
_https://github.com/pop-os/bus-writer_

Generic single-reader, multi-writer
* **tags**: [rust](../tagged/rust.md), [concurrency](../tagged/concurrency.md)
* :octocat: **[source code](https://github.com/pop-os/bus-writer)**
---
#### [Rayon](https://github.com/rayon-rs/rayon)
_https://github.com/rayon-rs/rayon_

Rayon: A data parallelism library for Rust. Contribute to rayon-rs/rayon development by creating an account on GitHub.
* **tags**: [rust](../tagged/rust.md), [concurrency](../tagged/concurrency.md)
* :octocat: **[source code](https://github.com/rayon-rs/rayon)**
---
#### [rustcc/coroutine-rs](https://github.com/rustcc/coroutine-rs)
_https://github.com/rustcc/coroutine-rs_

Coroutine Library in Rust. Contribute to rustcc/coroutine-rs development by creating an account on GitHub.
* **tags**: [rust](../tagged/rust.md), [concurrency](../tagged/concurrency.md)
* :octocat: **[source code](https://github.com/rustcc/coroutine-rs)**
---
#### [zonyitoo/coio-rs](https://github.com/zonyitoo/coio-rs)
_https://github.com/zonyitoo/coio-rs_

Coroutine I/O for Rust. Contribute to zonyitoo/coio-rs development by creating an account on GitHub.
* **tags**: [rust](../tagged/rust.md), [concurrency](../tagged/concurrency.md)
* :octocat: **[source code](https://github.com/zonyitoo/coio-rs)**
---
#### [Celluloid](http://celluloid.io)
_http://celluloid.io_

Actor-based concurrent object framework for Ruby.
* **tags**: [ruby](../tagged/ruby.md), [concurrency](../tagged/concurrency.md), [parallelism](../tagged/parallelism.md)
---
#### [Concurrent Ruby](https://github.com/ruby-concurrency/concurrent-ruby)
_https://github.com/ruby-concurrency/concurrent-ruby_

Modern concurrency tools including agents, futures, promises, thread pools, supervisors, and more. Inspired by Erlang, Clojure, Scala, Go, Java, JavaScript, and classic concurrency patterns.
* **tags**: [ruby](../tagged/ruby.md), [concurrency](../tagged/concurrency.md), [parallelism](../tagged/parallelism.md)
* :octocat: **[source code](https://github.com/ruby-concurrency/concurrent-ruby)**
---
#### [EventMachine](https://github.com/eventmachine/eventmachine)
_https://github.com/eventmachine/eventmachine_

An event-driven I/O and lightweight concurrency library for Ruby.
* **tags**: [ruby](../tagged/ruby.md), [concurrency](../tagged/concurrency.md), [parallelism](../tagged/parallelism.md)
* :octocat: **[source code](https://github.com/eventmachine/eventmachine)**
---
#### [forkoff](https://github.com/ahoward/forkoff)
_https://github.com/ahoward/forkoff_

brain-dead simple parallel processing for ruby.
* **tags**: [ruby](../tagged/ruby.md), [concurrency](../tagged/concurrency.md), [parallelism](../tagged/parallelism.md)
* :octocat: **[source code](https://github.com/ahoward/forkoff)**
---
#### [Parallel](https://github.com/grosser/parallel)
_https://github.com/grosser/parallel_

Run any code in parallel Processes (> use all CPUs) or Threads (> speedup blocking operations).
* **tags**: [ruby](../tagged/ruby.md), [concurrency](../tagged/concurrency.md), [parallelism](../tagged/parallelism.md)
* :octocat: **[source code](https://github.com/grosser/parallel)**
---
#### [concurrent.futures](https://docs.python.org/3/library/concurrent.futures.html)
_https://docs.python.org/3/library/concurrent.futures.html_

(Python standard library) A high-level interface for asynchronously executing callables.
* **tags**: [python](../tagged/python.md), [concurrency](../tagged/concurrency.md), [parallelism](../tagged/parallelism.md)
---
#### [multiprocessing](https://docs.python.org/3/library/multiprocessing.html)
_https://docs.python.org/3/library/multiprocessing.html_

(Python standard library) Process-based parallelism.
* **tags**: [python](../tagged/python.md), [concurrency](../tagged/concurrency.md), [parallelism](../tagged/parallelism.md)
---
#### [eventlet](http://eventlet.net/)
_http://eventlet.net/_

Asynchronous framework with WSGI support.
* **tags**: [python](../tagged/python.md), [concurrency](../tagged/concurrency.md), [parallelism](../tagged/parallelism.md)
---
#### [gevent](http://www.gevent.org/)
_http://www.gevent.org/_

A coroutine-based Python networking library that uses [greenlet](https://github.com/python-greenlet/greenlet).
* **tags**: [python](../tagged/python.md), [concurrency](../tagged/concurrency.md), [parallelism](../tagged/parallelism.md)
---
#### [uvloop](https://github.com/MagicStack/uvloop)
_https://github.com/MagicStack/uvloop_

Ultra fast implementation of `asyncio` event loop on top of `libuv`.
* **tags**: [python](../tagged/python.md), [concurrency](../tagged/concurrency.md), [parallelism](../tagged/parallelism.md)
* :octocat: **[source code](https://github.com/MagicStack/uvloop)**
---
#### [scoop](https://github.com/soravux/scoop)
_https://github.com/soravux/scoop_

Scalable Concurrent Operations in Python.
* **tags**: [python](../tagged/python.md), [concurrency](../tagged/concurrency.md), [parallelism](../tagged/parallelism.md)
* :octocat: **[source code](https://github.com/soravux/scoop)**
---
#### [java.util.concurrent - Java Concurrency Utilities](http://tutorials.jenkov.com/java-util-concurrent/index.html)
_http://tutorials.jenkov.com/java-util-concurrent/index.html_

In this tutorial I will take you through the new java.util.concurrent classes, one by one, so you can learn how to use them. I will use the versions in Java 6. I am not sure if there are any differenc...
* **tags**: [java](../tagged/java.md), [concurrency](../tagged/concurrency.md), [asynchronous](../tagged/asynchronous.md)
---
#### [Richard Clayton - Speaking Intelligently about "Java vs Node" Performance](https://rclayton.silvrback.com/speaking-intelligently-about-java-vs-node-performance)
_https://rclayton.silvrback.com/speaking-intelligently-about-java-vs-node-performance_

Speaking Intelligently about "Java vs Node" Performance - Please understand what's really important when it comes to the benefits of a platform.
* **tags**: [java](../tagged/java.md), [node.js](../tagged/node.js.md), [performance](../tagged/performance.md), [concurrency](../tagged/concurrency.md), [benchmarking](../tagged/benchmarking.md)
---


text:
Test Case Coverage Report

## Overview

## License

Test Case Coverage Report is released under the MIT license.  See the file [LICENSE](./LICENSE) for the full text.

##Documentation for SDK

You can find the documentation on our help [site.](https://help.rallydev.com/apps/2.1/doc/)


text:
1.30.x Stable Releases
======================

This document describes releases leading up to the ``1.30.x`` ``stable`` series.

See https://www.pantsbuild.org/v1.30/docs/release-notes-1-30 for an overview of the changes in this release.

1.30.5rc1 (10/7/2021)
---------------------

* Fix a deadlock involving ``scheduler.all_digests``, and add a note. (cherrypick of #11723) (#13149)
  `PR #13149 <https://github.com/pantsbuild/pants/pull/13149>`_

* Release the GIL while creating a Session. (cherrypick of #13127) (#13143)
  `PR #13143 <https://github.com/pantsbuild/pants/pull/13143>`_

1.30.5rc0 (4/5/2021)
--------------------

* Remove watchman. (#10114) (#11824)
  `PR #11824 <https://github.com/pantsbuild/pants/pull/11824>`_

* Update some deps to keep 1.30.x building. (#11843)
  `PR #11843 <https://github.com/pantsbuild/pants/pull/11843>`_

1.30.4 (3/19/2021)
------------------

The fifth stable release of the `1.30.x` series, with no changes since the previous rc.

1.30.4rc0 (3/9/2021)
--------------------

* Scala 2.13 support for 1.x (#11633)
  `PR #11633 <https://github.com/pantsbuild/pants/pull/11633>`_

1.30.3 (2/22/2021)
------------------

The fourth stable release in the 1.30.x series, with no changes since `rc0`.

Thanks to Dan Worth who uncovered `Issue #11579 <https://github.com/pantsbuild/pants/issues/11579>`_
and helped test rc0!

1.30.3rc0 (2/19/2021)
---------------------

This release fixes a bug in Pants fetching of some Go ``internal`` packages.

Bugfixes
~~~~~~~~

* Find remote roots for private internal packages. (#11581)
  `PR #11581 <https://github.com/pantsbuild/pants/pull/11581>`_

1.30.2 (12/21/2020)
-------------------

The third stable release in the 1.30.x series, with no changes since `rc3`.

Thank you to everyone who helped test the rcs!

1.30.2rc3 (12/16/2020)
----------------------

This release backports an upgrade to Pex 2.1.24 to bring support for macOS BigSur.

Bugfixes
~~~~~~~~

* Upgrade to Pex 2.1.24. (#11312) (#11317)
  `PR #11317 <https://github.com/pantsbuild/pants/pull/11317>`_

1.30.2rc2 (11/24/2020)
----------------------

Bugfixes
~~~~~~~~

* Add a specific error for target names containing slashes (cherry pick of #11115) (#11121)
  `PR #11121 <https://github.com/pantsbuild/pants/pull/11121>`_

1.30.2rc1 (9/30/2020)
---------------------

Bugfixes
~~~~~~~~

* Local process cache validates that digests exist locally before hitting (cherrypick of #10789) (#10879)
  `PR #10879 <https://github.com/pantsbuild/pants/pull/10879>`_

1.30.2rc0 (9/23/2020)
---------------------

New features
~~~~~~~~~~~~

* Backport `--test-extra-env-vars` feature (from #10715) (#10844)
  `PR #10844 <https://github.com/pantsbuild/pants/pull/10844>`_

1.30.1 (9/23/2020)
------------------

The second stable release of the ``1.30.x`` series, with no changes since the previous release candidate.

1.30.1rc2 (9/14/2020)
---------------------

Bugfixes
~~~~~~~~

* Fix `DictStringToStringField` not working with default values (Cherry-pick of #10776) (#10777)
  `PR #10777 <https://github.com/pantsbuild/pants/pull/10777>`_

1.30.1rc1 (9/11/2020)
---------------------

Bugfixes
~~~~~~~~

* Upgrade to Pex 2.1.14 (Cherry-pick of #10437) (#10763)
  `PR #10763 <https://github.com/pantsbuild/pants/pull/10763>`_

1.30.1rc0 (8/5/2020)
--------------------

Bugfixes
~~~~~~~~

* Remove self-inflicted invalidation caused by exception logging (cherrypick of #10521) (#10553)
  `PR #10553 <https://github.com/pantsbuild/pants/pull/10553>`_

* Fix bug that caused setup-py to hang if src root==buildroot (cherrypick of #10509) (#10552)
  `PR #10552 <https://github.com/pantsbuild/pants/pull/10552>`_

* Fix Protobuf when using source roots (cherrypick of #10453) (#10476)
  `PR #10476 <https://github.com/pantsbuild/pants/pull/10476>`_

* Fix `--print-exception-stacktrace` not invalidating pantsd (cherrypick of #10451) (#10461)
  `PR #10461 <https://github.com/pantsbuild/pants/pull/10461>`_

* Call instance method on instance rather than class (cherrypick of #10314) (#10426)
  `PR #10426 <https://github.com/pantsbuild/pants/pull/10426>`_

1.30.0 (7/17/2020)
------------------

The first stable release of the ``1.30.x`` series, with no changes since the previous rc!

1.30.0rc2 (7/14/2020)
---------------------

Bugfixes
~~~~~~~~

* Fix Pytest XML reports and Coverage breaking with remote execution (cherrypick of #10136) (#10324)
  `PR #10324 <https://github.com/pantsbuild/pants/pull/10324>`_

* Set dynamic-ui default based on CI (cherrypick of #10140) (#10325)
  `PR #10140 <https://github.com/pantsbuild/pants/pull/10140>`_

* Hotfix Bandit breaking from Stevedore 3.0 release (#10322)
  `PR #10322 <https://github.com/pantsbuild/pants/pull/10322>`_

Refactoring, Improvements, and Tooling
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

* Fix tests that relied on the docsite CNAME file. (cherrypick of #10337) (#10342)
  `PR #10342 <https://github.com/pantsbuild/pants/pull/10342>`_

1.30.0rc1 (6/27/2020)
---------------------

Bugfixes
~~~~~~~~

* Normalize paths before determining whether we can watch them. (#10130)
  `PR #10130 <https://github.com/pantsbuild/pants/pull/10130>`_

* Scrooge plugin: fix scala `compiler_option_sets` parameter passthrough (#10124)
  `PR #10124 <https://github.com/pantsbuild/pants/pull/10124>`_

1.30.0rc0 (6/19/2020)
---------------------

API Changes
~~~~~~~~~~~

* Upgrade to Pex 2.1.12. (#10099)
  `PR #10099 <https://github.com/pantsbuild/pants/pull/10099>`_

* Deprecate `pytest-coverage` scope in favor of `coverage-py` (#10091)
  `PR #10091 <https://github.com/pantsbuild/pants/pull/10091>`_

* Deprecate `--enable-pantsd` in favor of `--pantsd` (#10049)
  `PR #10049 <https://github.com/pantsbuild/pants/pull/10049>`_

* Set default source root patterns. (#10043)
  `PR #10043 <https://github.com/pantsbuild/pants/pull/10043>`_

New Features
~~~~~~~~~~~~

* Redesign v2 coverage mechanism (#10100)
  `PR #10100 <https://github.com/pantsbuild/pants/pull/10100>`_

* Add `--pytest-coverage-omit-test-sources` option to v2 (#10085)
  `PR #10085 <https://github.com/pantsbuild/pants/pull/10085>`_

* Control workunit levels at `@rule` execution time (#10053)
  `PR #10053 <https://github.com/pantsbuild/pants/pull/10053>`_

Bugfixes
~~~~~~~~

* Fix v2 Coverage erroring when a test failed to generate data (#10095)
  `PR #10095 <https://github.com/pantsbuild/pants/pull/10095>`_

* Fix the `coverage` field not working with v2 (#10082)
  `PR #10082 <https://github.com/pantsbuild/pants/pull/10082>`_

* Wait for ongoing runs to complete before shutting down pantsd (#10052)
  `PR #10052 <https://github.com/pantsbuild/pants/pull/10052>`_

* use try_into for a fallible conversion to hashing::Digest (#9994)
  `PR #9994 <https://github.com/pantsbuild/pants/pull/9994>`_

Refactoring, Improvements, and Tooling
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

* remoting: use debug level for remoting sub-workunits (#10098)
  `PR #10098 <https://github.com/pantsbuild/pants/pull/10098>`_

* Render the first visible parent of a workunit in --dynamic-ui. (#9957)
  `PR #9957 <https://github.com/pantsbuild/pants/pull/9957>`_

* Change StreamingWorkunitHandler default verbosity to DEBUG (#10090)
  `PR #10090 <https://github.com/pantsbuild/pants/pull/10090>`_

* Inline _wrap_type in `parser.py` (#10096)
  `PR #10096 <https://github.com/pantsbuild/pants/pull/10096>`_

* Make the `roots` goal display roots configured via marker files (#10079)
  `PR #10079 <https://github.com/pantsbuild/pants/pull/10079>`_

* Refactor v2 coverage and add an integration test (#10073)
  `PR #10073 <https://github.com/pantsbuild/pants/pull/10073>`_

* Extract member_type and type_arg in `parser.py` (#10063)
  `PR #10063 <https://github.com/pantsbuild/pants/pull/10063>`_

* Replace `TargetAdaptor` implementation of `list` with Target API implementation (#9912)
  `PR #9912 <https://github.com/pantsbuild/pants/pull/9912>`_

* Rename `InteractiveProcessRequest` to `InteractiveProcess` (#10050)
  `PR #10050 <https://github.com/pantsbuild/pants/pull/10050>`_

* Remove stale TODO (#10048)
  `PR #10048 <https://github.com/pantsbuild/pants/pull/10048>`_

* Reinitialize pantsd for most configuration changes (#10035)
  `PR #10035 <https://github.com/pantsbuild/pants/pull/10035>`_

* Remove unused FmtRequest union. (#9934)
  `PR #9934 <https://github.com/pantsbuild/pants/pull/9934>`_

* Use cargo-metadata not cargo to get packages (#10045)
  `PR #10045 <https://github.com/pantsbuild/pants/pull/10045>`_

* Expose new StreamingWorkunitContext on streaming workunits callback (#10034)
  `PR #10034 <https://github.com/pantsbuild/pants/pull/10034>`_

* Add report type to FilesystemCoverageReport (#10086)
  `PR #10086 <https://github.com/pantsbuild/pants/pull/10086>`_

Testing
~~~~~~~

* Increase timeout on test targets (#10097)
  `PR #10097 <https://github.com/pantsbuild/pants/pull/10097>`_

* Increase timeout for node_test_integration test target (#10094)
  `PR #10094 <https://github.com/pantsbuild/pants/pull/10094>`_

* Increase timeout for incomplete_custom_scala test target (#10089)
  `PR #10089 <https://github.com/pantsbuild/pants/pull/10089>`_

* remoting: add workunits for upload and execution (#10084)
  `PR #10084 <https://github.com/pantsbuild/pants/pull/10084>`_

* disable append-only cache in remoting (#10077)
  `PR #10077 <https://github.com/pantsbuild/pants/pull/10077>`_

* Push down process timeouts in remote execution (#10044)
  `PR #10044 <https://github.com/pantsbuild/pants/pull/10044>`_

* Add a __run.sh script to reproduce a process execution in a preserved chroot (#10030)
  `PR #10030 <https://github.com/pantsbuild/pants/pull/10030>`_

* Fix nightly build. (#10047)
  `PR #10047 <https://github.com/pantsbuild/pants/pull/10047>`_

Documentation
~~~~~~~~~~~~~
* Prepare the 1.28.1rc0 release.
  `Manual commit <https://github.com/pantsbuild/pants/commit/48b0ab940289ae7d440105224d93c9496fd59825>`_

* Prepare the 1.27.1rc0 release.
  `PR #10066 <https://github.com/pantsbuild/pants/pull/10066>`_

* Prepare the 1.26.1rc0 release.
  `PR #10067 <https://github.com/pantsbuild/pants/pull/10067>`_

* Prepare the 1.25.1rc1 release.
  `PR #10068 <https://github.com/pantsbuild/pants/pull/10068>`_

* Prepare the 1.24.1rc1 release.
  `PR #10069 <https://github.com/pantsbuild/pants/pull/10069>`_

* Prepare the 1.23.1rc0 release.
  `PR #10070 <https://github.com/pantsbuild/pants/pull/10070>`_

* Prepare the 1.22.1rc0 release.
  `PR #10071 <https://github.com/pantsbuild/pants/pull/10071>`_

* Prepare the 1.21.1rc0 release.
  `PR #10072 <https://github.com/pantsbuild/pants/pull/10072>`_

* Prepare 1.29.0. (#10074)
  `PR #10074 <https://github.com/pantsbuild/pants/pull/10074>`_

1.30.0.dev1 (6/12/2020)
-----------------------

API Changes
~~~~~~~~~~~

* Change the default MyPy version from 0.770 to 0.780 (#10001)
  `PR #10001 <https://github.com/pantsbuild/pants/pull/10001>`_

New Features
~~~~~~~~~~~~

* Add Python dependency inference for first-party imports (#10007)
  `PR #10007 <https://github.com/pantsbuild/pants/pull/10007>`_

* Add third party modules to Python dependency inference (#10025)
  `PR #10025 <https://github.com/pantsbuild/pants/pull/10025>`_

* Apply named caches to remote execution platform properties (#10009)
  `PR #10009 <https://github.com/pantsbuild/pants/pull/10009>`_

* remoting: add --remote-execution-overall-deadline-secs option (#10002)
  `PR #10002 <https://github.com/pantsbuild/pants/pull/10002>`_

* Add `--` style passthrough args to V2 `run` and `setup-py` goals (#9911)
  `PR #9911 <https://github.com/pantsbuild/pants/pull/9911>`_

* Add a configurable cap on total pantsd memory usage. (#10003)
  `PR #10003 <https://github.com/pantsbuild/pants/pull/10003>`_

Bugfixes
~~~~~~~~

* remoting: sort environment variables as per REv2 spec (#10038)
  `PR #10038 <https://github.com/pantsbuild/pants/pull/10038>`_

* Restore pytest coverage console report. (#10013)
  `PR #10013 <https://github.com/pantsbuild/pants/pull/10013>`_

Refactoring, Improvements, and Tooling
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

* Improve performance of Python dependency inference (#10031)
  `PR #10031 <https://github.com/pantsbuild/pants/pull/10031>`_

* Use f-strings. (#10039)
  `PR #10039 <https://github.com/pantsbuild/pants/pull/10039>`_

* Fix pants.toml contents appearing in engine error messages (#10033)
  `PR #10033 <https://github.com/pantsbuild/pants/pull/10033>`_

* Tweak `DescendantAddresses` so that call sites can no-op when no matches (#10012)
  `PR #10012 <https://github.com/pantsbuild/pants/pull/10012>`_

* Remove `pyopenssl`, `parametrized`, and `wheel` dependencies (#10023)
  `PR #10023 <https://github.com/pantsbuild/pants/pull/10023>`_

* Skip stdlib imports with dependency inference (#10011)
  `PR #10011 <https://github.com/pantsbuild/pants/pull/10011>`_

Documentation
~~~~~~~~~~~~~

* Fix release-strategy link (#10028)
  `PR #10028 <https://github.com/pantsbuild/pants/pull/10028>`_

1.30.0.dev0 (6/05/2020)
-----------------------

API Changes
~~~~~~~~~~~

* Remove deprecated ExternalTool functionality (#9996)
  `PR #9996 <https://github.com/pantsbuild/pants/pull/9996>`_

* Rename ReportType to CoverageReportType and move it to test.py (#9991)
  `PR #9991 <https://github.com/pantsbuild/pants/pull/9991>`_

* Remove the passthrough-arguments-with-multiple-goals deprecation. (#9984)
  `PR #9984 <https://github.com/pantsbuild/pants/pull/9984>`_

* Remove `--files-not-found-behavior=ignore` (#9986)
  `PR #9986 <https://github.com/pantsbuild/pants/pull/9986>`_

* Change --filedeps-absolute option to default to False. (#9983)
  `PR #9983 <https://github.com/pantsbuild/pants/pull/9983>`_

* Custom target types now need Target API bindings for full support (#9981)
  `PR #9981 <https://github.com/pantsbuild/pants/pull/9981>`_

* Remove deprecated source root trie. (#9936)
  `PR #9936 <https://github.com/pantsbuild/pants/pull/9936>`_

* Allow @rules to set their levels, and default to debug (#9940)
  `PR #9940 <https://github.com/pantsbuild/pants/pull/9940>`_

* Enable pantsd by default (#9935)
  `PR #9935 <https://github.com/pantsbuild/pants/pull/9935>`_

* Remove codeanalysis (Kythe) contrib plugin due to low usage (#9918)
  `PR #9918 <https://github.com/pantsbuild/pants/pull/9918>`_

* Remove AWS Lambda contrib plugin in favor of V2 backend (#9917)
  `PR #9917 <https://github.com/pantsbuild/pants/pull/9917>`_

* Remove V1 isort and `lint.pythonstyle` in favor of V2 isort and Flake8 (#9909)
  `PR #9909 <https://github.com/pantsbuild/pants/pull/9909>`_

* Upgrade typing-extensions from 3.7.4 to 3.7.4.2 (#9930)
  `PR #9930 <https://github.com/pantsbuild/pants/pull/9930>`_

* Upgrade pystache from 0.5.3 to 0.5.4 (#9929)
  `PR #9929 <https://github.com/pantsbuild/pants/pull/9929>`_

New Features
~~~~~~~~~~~~

* Create FFI functions for handling digests on workunits (#9965)
  `PR #9965 <https://github.com/pantsbuild/pants/pull/9965>`_
  `PR #9906 <https://github.com/pantsbuild/pants/pull/9906>`_

* Add support for returning multiple coverage reports for each MergedCoverageData. (#9992)
  `PR #9992 <https://github.com/pantsbuild/pants/pull/9992>`_

* Support for marking source roots via a specially-named file. (#9977)
  `PR #9977 <https://github.com/pantsbuild/pants/pull/9977>`_

* Expose v2 goals from RunTracker. (#9963)
  `PR #9963 <https://github.com/pantsbuild/pants/pull/9963>`_

* remoting: allow override of target_platform (#9954)
  `PR #9954 <https://github.com/pantsbuild/pants/pull/9954>`_

* remoting: add streaming remote execution client (#9897)
  `PR #9897 <https://github.com/pantsbuild/pants/pull/9897>`_

* Attach stdout/stderr digests to workunits (#9906)
  `PR #9906 <https://github.com/pantsbuild/pants/pull/9906>`_

* Log workunit creation and completion (#9894)
  `PR #9894 <https://github.com/pantsbuild/pants/pull/9894>`_

Bugfixes
~~~~~~~~

* Kill child processes on drop. (#9998)
  `PR #9998 <https://github.com/pantsbuild/pants/pull/9998>`_

* remoting: more unit tests and fix an edge case (#9980)
  `PR #9980 <https://github.com/pantsbuild/pants/pull/9980>`_

* Release the gil while polling workunits. (#9969)
  `PR #9969 <https://github.com/pantsbuild/pants/pull/9969>`_

* Fix lease extension, and make it recursive (#9956)
  `PR #9956 <https://github.com/pantsbuild/pants/pull/9956>`_

* Fix deadlock between Session and WorkunitStore. (#9959)
  `PR #9959 <https://github.com/pantsbuild/pants/pull/9959>`_

* Default to invalidating for `requirements.txt` to ameliorate #7022. (#9946)
  `PR #9946 <https://github.com/pantsbuild/pants/pull/9946>`_

* Fix a bug in pyest coverage report computation. (#9933)
  `PR #9933 <https://github.com/pantsbuild/pants/pull/9933>`_

* Fix ABI string when building pants.pex (#9908)
  `PR #9908 <https://github.com/pantsbuild/pants/pull/9908>`_

Refactoring, Improvements, and Tooling
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

* Add a Python import parser for dependency inference (#9900)
  `PR #9900 <https://github.com/pantsbuild/pants/pull/9900>`_

* Use f-strings, improve code readability. (#9990)
  `PR #9990 <https://github.com/pantsbuild/pants/pull/9990>`_

* Remove unnecessary string interpolation, use generator expression. (#9993)
  `PR #9993 <https://github.com/pantsbuild/pants/pull/9993>`_

* Use f-strings. (#9987)
  `PR #9987 <https://github.com/pantsbuild/pants/pull/9987>`_

* Enable more Flake8 checks internally (#9885)
  `PR #9885 <https://github.com/pantsbuild/pants/pull/9885>`_

* Reuse report_type (#9978)
  `PR #9978 <https://github.com/pantsbuild/pants/pull/9978>`_

* Bump to Rust 1.44.0 (#9972)
  `PR #9972 <https://github.com/pantsbuild/pants/pull/9972>`_

* Set the pex_root cache only at build time (#9958)
  `PR #9958 <https://github.com/pantsbuild/pants/pull/9958>`_

* Finish removing Bytes fields from FallibleProcessResultWithPlatform (#9955)
  `PR #9955 <https://github.com/pantsbuild/pants/pull/9955>`_

* Split client-related logic out of the PantsDaemon class. (#9949)
  `PR #9949 <https://github.com/pantsbuild/pants/pull/9949>`_

* Silence failures to close pantsd stdio handles. (#9943)
  `PR #9943 <https://github.com/pantsbuild/pants/pull/9943>`_

* Remove `buildrefactor` plugin that we never published (#9937)
  `PR #9937 <https://github.com/pantsbuild/pants/pull/9937>`_

* Remove redundant names and logging. (#9921)
  `PR #9921 <https://github.com/pantsbuild/pants/pull/9921>`_

* Remove unused union marker. (#9928)
  `PR #9928 <https://github.com/pantsbuild/pants/pull/9928>`_

* Ensure BuildConfiguration is immutable. (#9931)
  `PR #9931 <https://github.com/pantsbuild/pants/pull/9931>`_

* Make FrozenDict more ergonomic. (#9932)
  `PR #9932 <https://github.com/pantsbuild/pants/pull/9932>`_

* Port from cffi to the cpython crate. (#9593)
  `PR #9593 <https://github.com/pantsbuild/pants/pull/9593>`_

* Graph::get backs off on filesystem invalidation (#9920)
  `PR #9920 <https://github.com/pantsbuild/pants/pull/9920>`_

* Port the graph crate and dependent code in engine to async/await. (#9910)
  `PR #9910 <https://github.com/pantsbuild/pants/pull/9910>`_

* Improve pantsd waiting messages. (#9923)
  `PR #9923 <https://github.com/pantsbuild/pants/pull/9923>`_

* Use flake8-2020 plugin internally (#9913)
  `PR #9913 <https://github.com/pantsbuild/pants/pull/9913>`_

* Log timestamps should be in the local time zone (#9927)
  `PR #9927 <https://github.com/pantsbuild/pants/pull/9927>`_

Testing
~~~~~~~

* remoting: add initial unit tests for streaming client and fix a bug (#9966)
  `PR #9966 <https://github.com/pantsbuild/pants/pull/9966>`_

Documentation
~~~~~~~~~~~~~

* Prepare 1.29.0rc2 (#9971)
  `PR #9971 <https://github.com/pantsbuild/pants/pull/9971>`_

* Prepare 1.29.0rc1. (#9948)
  `PR #9948 <https://github.com/pantsbuild/pants/pull/9948>`_

* Fix typo in PR title (#9976)
  `PR #9976 <https://github.com/pantsbuild/pants/pull/9976>`_


text: Reports break statements outside of switch statements.


text:
.. _sec_phys_pkg_gridalt:

Gridalt - Alternate Grid Package
--------------------------------

Introduction
++++++++++++

The gridalt package :cite:`mol:09` is designed to allow different components of MITgcm
to be run using horizontal and/or vertical grids which are different
from the main model grid. The gridalt routines handle the definition of
the all the various alternative grid(s) and the mappings between them
and the MITgcm grid. The implementation of the gridalt package which
allows the high end atmospheric physics (fizhi) to be run on a high
resolution and quasi terrain-following vertical grid is documented here.
The package has also (with some user modifications) been used for other
calculations within the GCM.

The rationale for implementing the atmospheric physics on a high
resolution vertical grid involves the fact that the MITgcm :math:`p^*`
(or any pressure-type) coordinate cannot maintain the vertical
resolution near the surface as the bottom topography rises above sea
level. The vertical length scales near the ground are small and can vary
on small time scales, and the vertical grid must be adequate to resolve
them. Many studies with both regional and global atmospheric models have
demonstrated the improvements in the simulations when the vertical
resolution near the surface is increased (). Some of the benefit of
increased resolution near the surface is realized by employing the
higher resolution for the computation of the forcing due to turbulent
and convective processes in the atmosphere.

The parameterizations of atmospheric subgrid scale processes are all
essentially one-dimensional in nature, and the computation of the terms
in the equations of motion due to these processes can be performed for
the air column over one grid point at a time. The vertical grid on which
these computations take place can therefore be entirely independant of
the grid on which the equations of motion are integrated, and the
'tendency' terms can be interpolated to the vertical grid on which the
equations of motion are integrated. A modified :math:`p^*` coordinate,
which adjusts to the local terrain and adds additional levels between
the lower levels of the existing :math:`p^*` grid (and perhaps between
the levels near the tropopause as well), is implemented. The vertical
discretization is different for each grid point, although it consist of
the same number of levels. Additional 'sponge' levels aloft are added
when needed. The levels of the physics grid are constrained to fit
exactly into the existing :math:`p^*` grid, simplifying the mapping
between the two vertical coordinates. This is illustrated as follows:

 .. figure:: figs/vertical.*
    :width: 70%
    :align: center
    :alt: vertical discretisation
    :name: grid_alt_vertical

    Vertical discretization for MITgcm (dark grey lines) and for the atmospheric physics (light grey lines). In this implementation, all MITgcm level interfaces must coincide with atmospheric physics level interfaces.

The algorithm presented here retains the state variables on the high
resolution 'physics' grid as well as on the coarser resolution
'dynamics' grid, and ensures that the two estimates of the state 'agree'
on the coarse resolution grid. It would have been possible to implement
a technique in which the tendencies due to atmospheric physics are
computed on the high resolution grid and the state variables are
retained at low resolution only. This, however, for the case of the
turbulence parameterization, would mean that the turbulent kinetic
energy source terms, and all the turbulence terms that are written in
terms of gradients of the mean flow, cannot really be computed making
use of the fine structure in the vertical.

Equations on Both Grids
+++++++++++++++++++++++

In addition to computing the physical forcing terms of the momentum,
thermodynamic and humidity equations on the modified (higher resolution)
grid, the higher resolution structure of the atmosphere (the boundary
layer) is retained between physics calculations. This neccessitates a
second set of evolution equations for the atmospheric state variables on
the modified grid. If the equation for the evolution of :math:`U` on
:math:`p^*` can be expressed as:

.. math::

   \left . \frac{\partial U}{\partial t} \right |_{p^*}^{total} =
   \left . \frac{\partial U}{\partial t} \right |_{p^*}^{dynamics} +
   \left . \frac{\partial U}{\partial t} \right |_{p^*}^{physics}

where the physics forcing terms on :math:`p^*` have been mapped from the
modified grid, then an additional equation to govern the evolution of
:math:`U` (for example) on the modified grid is written:

.. math::

   \left . \frac{\partial U}{\partial t} \right |_{p^{*m}}^{total} =
   \left . \frac{\partial U}{\partial t} \right |_{p^{*m}}^{dynamics} +
   \left . \frac{\partial U}{\partial t} \right |_{p^{*m}}^{physics} +
   \gamma ({\left . U \right |_{p^*}} - {\left . U \right |_{p^{*m}}})

where :math:`p^{*m}` refers to the modified higher resolution grid, and
the dynamics forcing terms have been mapped from :math:`p^*` space. The
last term on the RHS is a relaxation term, meant to constrain the state
variables on the modified vertical grid to 'track' the state variables
on the :math:`p^*` grid on some time scale, governed by :math:`\gamma`.
In the present implementation, :math:`\gamma = 1`, requiring an
immediate agreement between the two 'states'.

Time stepping Sequence
++++++++++++++++++++++

If we write :math:`T_{phys}` as the temperature (or any other state
variable) on the high resolution physics grid, and :math:`T_{dyn}` as
the temperature on the coarse vertical resolution dynamics grid, then:

#. Compute the tendency due to physics processes.

#. Advance the physics state: :math:`{{T^{n+1}}^{**}}_{phys}(l) = {T^n}_{phys}(l) + \delta T_{phys}`.

#. Interpolate the physics tendency to the dynamics grid, and advance the dynamics state by physics and dynamics tendencies: :math:`{T^{n+1}}_{dyn}(L) = {T^n}_{dyn}(L) + \delta T_{dyn}(L) + [\delta T _{phys}(l)](L)`.

#. Interpolate the dynamics tendency to the physics grid, and update the physics grid due to dynamics tendencies: :math:`{{T^{n+1}}^*}_{phys}(l)` = :math:`{{T^{n+1}}^{**}}_{phys}(l) + {\delta T_{dyn}(L)}(l)`.

#. Apply correction term to physics state to account for divergence from dynamics state: :math:`{T^{n+1}}_{phys}(l)` = :math:`{{T^{n+1}}^*}_{phys}(l) + \gamma \{  T_{dyn}(L) - [T_{phys}(l)](L) \}(l)`. Where :math:`\gamma=1` here.

Interpolation
+++++++++++++

In order to minimize the correction terms for the state variables on
the alternative, higher resolution grid, the vertical interpolation
scheme must be constructed so that a dynamics-to-physics interpolation
can be exactly reversed with a physics-to-dynamics mapping. The simple
scheme employed to achieve this is:

Coarse to fine:For all physics layers l in dynamics layer L, :math:`T_{phys}(l) = \{T_{dyn}(L)\} = T_{dyn}(L)`.

| Fine to coarse:For all physics layers l in dynamics layer L, :math:`T_{dyn}(L) = [T_{phys}(l)] = \int{T_{phys} dp }`.

Where :math:`\{\}` is defined as the dynamics-to-physics operator and
:math:`[ ]` is the physics-to-dynamics operator, :math:`T` stands for
any state variable, and the subscripts :math:`phys` and :math:`dyn`
stand for variables on the physics and dynamics grids, respectively.

Key subroutines, parameters and files
++++++++++++++++++++++++++++++++++++++

One of the central elements of the gridalt package is the routine which
is called from subroutine gridalt\_initialise to define the grid to be
used for the high end physics calculations. Routine make\_phys\_grid
passes back the parameters which define the grid, ultimately stored in
the common block gridalt\_mapping.

::

           subroutine make_phys_grid(drF,hfacC,im1,im2,jm1,jm2,Nr,
         . Nsx,Nsy,i1,i2,j1,j2,bi,bj,Nrphys,Lbot,dpphys,numlevphys,nlperdyn)
    c***********************************************************************
    c Purpose: Define the grid that the will be used to run the high-end
    c          atmospheric physics.
    c
    c Algorithm: Fit additional levels of some (~) known thickness in
    c          between existing levels of the grid used for the dynamics
    c
    c Need:    Information about the dynamics grid vertical spacing
    c
    c Input:   drF         - delta r (p*) edge-to-edge
    c          hfacC       - fraction of grid box above topography
    c          im1, im2    - beginning and ending i - dimensions
    c          jm1, jm2    - beginning and ending j - dimensions
    c          Nr          - number of levels in dynamics grid
    c          Nsx,Nsy     - number of processes in x and y direction
    c          i1, i2      - beginning and ending i - index to fill
    c          j1, j2      - beginning and ending j - index to fill
    c          bi, bj      - x-dir and y-dir index of process
    c          Nrphys      - number of levels in physics grid
    c
    c Output:  dpphys      - delta r (p*) edge-to-edge of physics grid
    c          numlevphys  - number of levels used in the physics
    c          nlperdyn    - physics level number atop each dynamics layer
    c
    c NOTES: 1) Pressure levs are built up from bottom, using p0, ps and dp:
    c              p(i,j,k)=p(i,j,k-1) + dp(k)*ps(i,j)/p0(i,j)
    c        2) Output dp's are aligned to fit EXACTLY between existing
    c           levels of the dynamics vertical grid
    c        3) IMPORTANT! This routine assumes the levels are numbered
    c           from the bottom up, ie, level 1 is the surface.
    c           IT WILL NOT WORK OTHERWISE!!!
    c        4) This routine does NOT work for surface pressures less
    c           (ie, above in the atmosphere) than about 350 mb
    c***********************************************************************

In the case of the grid used to compute the atmospheric physical forcing
(fizhi package), the locations of the grid points move in time with the
MITgcm :math:`p^*` coordinate, and subroutine gridalt\_update is called
during the run to update the locations of the grid points:

::

           subroutine gridalt_update(myThid)
    c***********************************************************************
    c Purpose: Update the pressure thicknesses of the layers of the
    c          alternative vertical grid (used now for atmospheric physics).
    c
    c Calculate: dpphys    - new delta r (p*) edge-to-edge of physics grid
    c                        using dpphys0 (initial value) and rstarfacC
    c***********************************************************************

The gridalt package also supplies utility routines which perform the
mappings from one grid to the other. These routines are called from the
code which computes the fields on the alternative (fizhi) grid.

::

          subroutine dyn2phys(qdyn,pedyn,im1,im2,jm1,jm2,lmdyn,Nsx,Nsy,
         . idim1,idim2,jdim1,jdim2,bi,bj,windphy,pephy,Lbot,lmphy,nlperdyn,
         . flg,qphy)
    C***********************************************************************
    C Purpose:
    C   To interpolate an arbitrary quantity from the 'dynamics' eta (pstar)
    C               grid to the higher resolution physics grid
    C Algorithm:
    C   Routine works one layer (edge to edge pressure) at a time.
    C   Dynamics -> Physics retains the dynamics layer mean value,
    C   weights the field either with the profile of the physics grid
    C   wind speed (for U and V fields), or uniformly (T and Q)
    C
    C Input:
    C   qdyn..... [im,jm,lmdyn] Arbitrary Quantity on Input Grid
    C   pedyn.... [im,jm,lmdyn+1] Pressures at bottom edges of input levels
    C   im1,2 ... Limits for Longitude Dimension of Input
    C   jm1,2 ... Limits for Latitude  Dimension of Input
    C   lmdyn.... Vertical  Dimension of Input
    C   Nsx...... Number of processes in x-direction
    C   Nsy...... Number of processes in y-direction
    C   idim1,2.. Beginning and ending i-values to calculate
    C   jdim1,2.. Beginning and ending j-values to calculate
    C   bi....... Index of process number in x-direction
    C   bj....... Index of process number in x-direction
    C   windphy.. [im,jm,lmphy] Magnitude of the wind on the output levels
    C   pephy.... [im,jm,lmphy+1] Pressures at bottom edges of output levels
    C   lmphy.... Vertical  Dimension of Output
    C   nlperdyn. [im,jm,lmdyn] Highest Physics level in each dynamics level
    C   flg...... Flag to indicate field type (0 for T or Q, 1 for U or V)
    C
    C Output:
    C   qphy..... [im,jm,lmphy] Quantity at output grid (physics grid)
    C
    C Notes:
    C   1) This algorithm assumes that the output (physics) grid levels
    C      fit exactly into the input (dynamics) grid levels
    C***********************************************************************

And similarly, gridalt contains subroutine phys2dyn.

Gridalt Diagnostics
+++++++++++++++++++

::

    ------------------------------------------------------------------------
    <-Name->|Levs|<-parsing code->|<--  Units   -->|<- Tile (max=80c)
    ------------------------------------------------------------------------
    DPPHYS  | 20 |SM      ML      |Pascal          |Pressure Thickness of Layers on Fizhi Grid

Dos and donts
+++++++++++++

Gridalt Reference
+++++++++++++++++

Experiments and tutorials that use gridalt
++++++++++++++++++++++++++++++++++++++++++

-  Fizhi experiment, in fizhi-cs-32x32x10 verification directory


text:
using System;
using System.Linq.Expressions;
using System.Reflection;
using System.Web.Http.Controllers;
using System.Web.Http.Routing;

namespace Strathweb.TypedRouting
{
    public class TypedRoute : IDirectRouteFactory
    {
        public TypedRoute(string template)
        {
            Template = template;
        }

        public Type ControllerType { get; private set; }

        public string RouteName { get; private set; }

        public string Template { get; private set; }

        public string ControllerName
        {
            get { return ControllerType != null ? ControllerType.FullName : string.Empty; }
        }

        public string ActionName { get; private set; }

        public MethodInfo ActionMember { get; private set; }

        RouteEntry IDirectRouteFactory.CreateRoute(DirectRouteFactoryContext context)
        {
            IDirectRouteBuilder builder = context.CreateBuilder(Template);

            builder.Name = RouteName;
            return builder.Build();
        }

        public TypedRoute Controller<TController>() where TController : IHttpController
        {
            ControllerType = typeof(TController);
            return this;
        }

        public TypedRoute Action<T, U>(Expression<Func<T, U>> expression)
        {
            ActionMember = GetMethodInfoInternal(expression);
            ControllerType = ActionMember.DeclaringType;
            ActionName = ActionMember.Name;
            return this;
        }

        public TypedRoute Action<T>(Expression<Action<T>> expression)
        {
            ActionMember = GetMethodInfoInternal(expression);
            ControllerType = ActionMember.DeclaringType;
            ActionName = ActionMember.Name;
            return this;
        }

        private static MethodInfo GetMethodInfoInternal(dynamic expression)
        {
            var method = expression.Body as MethodCallExpression;
            if (method != null)
                return method.Method;

            throw new ArgumentException("Expression is incorrect!");
        }

        public TypedRoute Name(string name)
        {
            RouteName = name;
            return this;
        }

        public TypedRoute Action(string actionName)
        {
            ActionName = actionName;
            return this;
        }
    }
}


text:
            Key
            Default
            Type
            Description

state.backend.rocksdb.metrics.actual-delayed-write-rate

            false
            Boolean
            Monitor the current actual delayed write rate. 0 means no delay.

state.backend.rocksdb.metrics.background-errors

            false
            Boolean
            Monitor the number of background errors in RocksDB.

state.backend.rocksdb.metrics.block-cache-capacity

            false
            Boolean
            Monitor block cache capacity.

state.backend.rocksdb.metrics.block-cache-pinned-usage

            false
            Boolean
            Monitor the memory size for the entries being pinned in block cache.

state.backend.rocksdb.metrics.block-cache-usage

            false
            Boolean
            Monitor the memory size for the entries residing in block cache.

state.backend.rocksdb.metrics.column-family-as-variable

            false
            Boolean
            Whether to expose the column family as a variable.

state.backend.rocksdb.metrics.compaction-pending

            false
            Boolean
            Track pending compactions in RocksDB. Returns 1 if a compaction is pending, 0 otherwise.

state.backend.rocksdb.metrics.cur-size-active-mem-table

            false
            Boolean
            Monitor the approximate size of the active memtable in bytes.

state.backend.rocksdb.metrics.cur-size-all-mem-tables

            false
            Boolean
            Monitor the approximate size of the active and unflushed immutable memtables in bytes.

state.backend.rocksdb.metrics.estimate-live-data-size

            false
            Boolean
            Estimate of the amount of live data in bytes (usually smaller than sst files size due to space amplification).

state.backend.rocksdb.metrics.estimate-num-keys

            false
            Boolean
            Estimate the number of keys in RocksDB.

state.backend.rocksdb.metrics.estimate-pending-compaction-bytes

            false
            Boolean
            Estimated total number of bytes compaction needs to rewrite to get all levels down to under target size. Not valid for other compactions than level-based.

state.backend.rocksdb.metrics.estimate-table-readers-mem

            false
            Boolean
            Estimate the memory used for reading SST tables, excluding memory used in block cache (e.g.,filter and index blocks) in bytes.

state.backend.rocksdb.metrics.is-write-stopped

            false
            Boolean
            Track whether write has been stopped in RocksDB. Returns 1 if write has been stopped, 0 otherwise.

state.backend.rocksdb.metrics.live-sst-files-size

            false
            Boolean
            Monitor the total size (bytes) of all SST files belonging to the latest version.WARNING: may slow down online queries if there are too many files.

state.backend.rocksdb.metrics.mem-table-flush-pending

            false
            Boolean
            Monitor the number of pending memtable flushes in RocksDB.

state.backend.rocksdb.metrics.num-deletes-active-mem-table

            false
            Boolean
            Monitor the total number of delete entries in the active memtable.

state.backend.rocksdb.metrics.num-deletes-imm-mem-tables

            false
            Boolean
            Monitor the total number of delete entries in the unflushed immutable memtables.

state.backend.rocksdb.metrics.num-entries-active-mem-table

            false
            Boolean
            Monitor the total number of entries in the active memtable.

state.backend.rocksdb.metrics.num-entries-imm-mem-tables

            false
            Boolean
            Monitor the total number of entries in the unflushed immutable memtables.

state.backend.rocksdb.metrics.num-immutable-mem-table

            false
            Boolean
            Monitor the number of immutable memtables in RocksDB.

state.backend.rocksdb.metrics.num-live-versions

            false
            Boolean
            Monitor number of live versions. Version is an internal data structure. See RocksDB file version_set.h for details. More live versions often mean more SST files are held from being deleted, by iterators or unfinished compactions.

state.backend.rocksdb.metrics.num-running-compactions

            false
            Boolean
            Monitor the number of currently running compactions.

state.backend.rocksdb.metrics.num-running-flushes

            false
            Boolean
            Monitor the number of currently running flushes.

state.backend.rocksdb.metrics.num-snapshots

            false
            Boolean
            Monitor the number of unreleased snapshots of the database.

state.backend.rocksdb.metrics.size-all-mem-tables

            false
            Boolean
            Monitor the approximate size of the active, unflushed immutable, and pinned immutable memtables in bytes.

state.backend.rocksdb.metrics.total-sst-files-size

            false
            Boolean
            Monitor the total size (bytes) of all SST files of all versions.WARNING: may slow down online queries if there are too many files.


text:
<?php

namespace DCarbone\PHPFHIRGenerated\R4\PHPFHIRTests\FHIRElement\FHIRBackboneElement\FHIRRelatedPerson;

use PHPUnit\Framework\TestCase;
use DCarbone\PHPFHIRGenerated\R4\FHIRElement\FHIRBackboneElement\FHIRRelatedPerson\FHIRRelatedPersonCommunication;

/**
 * Class FHIRRelatedPersonCommunicationTest
 * @package \DCarbone\PHPFHIRGenerated\R4\PHPFHIRTests\FHIRElement\FHIRBackboneElement\FHIRRelatedPerson
 */
class FHIRRelatedPersonCommunicationTest extends TestCase
{
    public function testCanConstructTypeNoArgs()
    {
        $type = new FHIRRelatedPersonCommunication();
        $this->assertInstanceOf('\DCarbone\PHPFHIRGenerated\R4\FHIRElement\FHIRBackboneElement\FHIRRelatedPerson\FHIRRelatedPersonCommunication', $type);
    }
}