示例#1
0
SetId Approximator::function_rhs_val(const Function& fun, SetId rhs, SetId val,
                                     Parity parity) const {
    POMAGMA_ASSERT1(rhs, "rhs is undefined");
    POMAGMA_ASSERT1(val, "val is undefined");
    POMAGMA_ASSERT1(parity == NABOVE or parity == NBELOW, "invalid parity");
    const bool upward = (parity == NBELOW);
    const DenseSet& support = m_structure.carrier().support();
    const DenseSet rhs_set = m_sets.load(rhs);  // positive
    const DenseSet val_set = m_sets.load(val);  // negative
    DenseSet lhs_set(m_item_dim);               // negative

    for (auto iter = support.iter_diff(lhs_set); iter.ok(); iter.next()) {
        Ob lhs = *iter;
        if (unlikely(lhs_set.contains(lhs))) continue;  // iterator latency
        for (auto iter = fun.get_Lx_set(lhs).iter_insn(rhs_set); iter.ok();
             iter.next()) {
            Ob rhs = *iter;
            Ob val = fun.find(lhs, rhs);
            if (val_set.contains(val)) {
                convex_insert(lhs_set, lhs, upward);
                break;
            }
        }
    }

    return m_sets.store(std::move(lhs_set));
}
示例#2
0
文件: queue.cpp 项目: fritzo/pomagma
void FileBackedQueue::push(const void* message, uint8_t size) {
    POMAGMA_ASSERT1(size, "empty messages are not allowed");
    std::unique_lock<std::mutex> lock(m_mutex);
    POMAGMA_ASSERT_C(pwrite(m_fid, &size, 1, m_write_offset));
    m_write_offset += 1;
    POMAGMA_ASSERT_C(pwrite(m_fid, message, size, m_write_offset));
    m_write_offset += size;
}
示例#3
0
文件: queue.cpp 项目: fritzo/pomagma
void VectorQueue::push(const void* message, uint8_t size) {
    POMAGMA_ASSERT1(size, "empty messages are not allowed");
    std::unique_lock<std::mutex> lock(m_mutex);
    size_t offset = m_data.size();
    m_data.resize(offset + 1 + size);
    memcpy(m_data.data() + offset, &size, 1);
    memcpy(m_data.data() + offset + 1, message, size);
}
示例#4
0
SetId Approximator::function_lhs_rhs(const Function& fun, SetId lhs, SetId rhs,
                                     Parity parity) const {
    POMAGMA_ASSERT1(lhs, "lhs is undefined");
    POMAGMA_ASSERT1(rhs, "rhs is undefined");
    POMAGMA_ASSERT1(parity == ABOVE or parity == BELOW, "invalid parity");
    const bool upward = (parity == ABOVE);
    const DenseSet lhs_set = m_sets.load(lhs);  // positive
    const DenseSet rhs_set = m_sets.load(rhs);  // positive
    DenseSet val_set(m_item_dim);               // positive

    const Ob optimum = upward ? m_top : m_bot;
    POMAGMA_ASSERT1(lhs_set.contains(optimum), "invalid lhs set");
    POMAGMA_ASSERT1(rhs_set.contains(optimum), "invalid rhs set");
    val_set.insert(optimum);

    DenseSet temp_set(m_item_dim);
    for (auto iter = lhs_set.iter(); iter.ok(); iter.next()) {
        Ob lhs = *iter;

        // optimize for constant functions
        if (Ob lhs_top = fun.find(lhs, m_top)) {
            if (Ob lhs_bot = fun.find(lhs, m_bot)) {
                if (lhs_top == lhs_bot) {
                    convex_insert(val_set, lhs_top, upward);
                    continue;
                }
            }
        }

        temp_set.set_insn(rhs_set, fun.get_Lx_set(lhs));
        for (auto iter = temp_set.iter(); iter.ok(); iter.next()) {
            Ob rhs = *iter;
            Ob val = fun.find(lhs, rhs);
            convex_insert(val_set, val, upward);
        }
    }

    return m_sets.store(std::move(val_set));
}
示例#5
0
inline bool try_pop(CleanupTask &task) {
    const unsigned long type_count = g_type_count;
    POMAGMA_ASSERT1(type_count, "Cleanup::init has not been called");

    unsigned long done = 0;
    while (not g_done_count.compare_exchange_weak(done, done + 1,
                                                  std::memory_order_acq_rel)) {
        if (done == type_count) {
            return false;
        }
    }

    unsigned long type = 0;
    while (not g_type.compare_exchange_weak(type, (type + 1) % type_count,
                                            std::memory_order_acq_rel)) {
    }

    task.type = type;
    return true;
}
示例#6
0
 void lock_shared ()
 {
     int status = pthread_rwlock_rdlock(&m_rwlock);
     POMAGMA_ASSERT1(status == 0, "pthread_rwlock_rdlock failed");
 }
示例#7
0
 // glibc seems to be buggy; don't unlock more often than it has been locked
 // see http://sourceware.org/bugzilla/show_bug.cgi?id=4825
 void unlock ()
 {
     int status = pthread_rwlock_unlock(&m_rwlock);
     POMAGMA_ASSERT1(status == 0, "pthread_rwlock_unlock failed");
 }
示例#8
0
 ~SharedMutex ()
 {
     int status = pthread_rwlock_destroy(&m_rwlock);
     POMAGMA_ASSERT1(status == 0, "pthread_rwlock_destroy failed");
 }
示例#9
0
 SharedMutex ()
 {
     int status = pthread_rwlock_init(&m_rwlock, nullptr);
     POMAGMA_ASSERT1(status == 0, "pthread_rwlock_init failed");
 }
示例#10
0
 Word *find(SetId id) const {
     SharedMutex::SharedLock lock(m_mutex);
     auto i = m_index.find(id);
     POMAGMA_ASSERT1(i != m_index.end(), "missing id " << id);
     return i->second;
 }
示例#11
0
inline SetId Approximator::lazy_find(const std::string& name, Target target,
                                     Parity parity, SetId arg0, SetId arg1) {
    auto i = m_binary_cache.find(CacheKey{hash_name(name), target, parity});
    POMAGMA_ASSERT1(i != m_binary_cache.end(), "programmer error");
    return i->second->try_find({arg0, arg1});
}
示例#12
0
Approximator::Approximator(Structure& structure, DenseSetStore& sets,
                           WorkerPool& worker_pool)
    :  // structure
      m_structure(structure),
      m_item_dim(structure.carrier().item_dim()),
      m_top(structure.nullary_function("TOP").find()),
      m_bot(structure.nullary_function("BOT").find()),
      m_less(structure.binary_relation("LESS")),
      m_nless(structure.binary_relation("NLESS")),
      // dense set stores
      m_sets(sets),
      m_empty_set(sets.store(std::move(DenseSet(m_item_dim)))),
      m_known(1 + m_item_dim),
      m_unknown(),
      // lazy map caches
      m_disjoint_cache(worker_pool,
                       [this](const std::pair<SetId, SetId>& pair) {
          return m_sets.load(pair.first).disjoint(m_sets.load(pair.second))
                     ? Trool::TRUE
                     : Trool::FALSE;
      }),
      m_union_cache(worker_pool, [this](const std::vector<SetId>& sets) {
          const size_t count = sets.size();
          POMAGMA_ASSERT1(count >= 2, "too few sets: " << count);
          DenseSet val(m_item_dim);
          val.set_union(m_sets.load(sets[0]), m_sets.load(sets[1]));
          for (size_t i = 2; i < count; ++i) {
              val += m_sets.load(sets[i]);
          }
          return m_sets.store(std::move(val));
      }),
      m_nullary_cache(),
      m_binary_cache() {
    POMAGMA_ASSERT(m_top, "TOP is not defined");
    POMAGMA_ASSERT(m_bot, "BOT is not defined");

    POMAGMA_INFO("Inserting LESS and NLESS in DenseSetStore");
    for (auto iter = m_structure.carrier().iter(); iter.ok(); iter.next()) {
        const Ob ob = *iter;
        m_known[ob][ABOVE] = m_sets.store(m_less.get_Lx_set(ob));
        m_known[ob][BELOW] = m_sets.store(m_less.get_Rx_set(ob));
        m_known[ob][NABOVE] = m_sets.store(m_nless.get_Lx_set(ob));
        m_known[ob][NBELOW] = m_sets.store(m_nless.get_Rx_set(ob));
    }
    m_unknown[ABOVE] = m_known[m_top][ABOVE];
    m_unknown[BELOW] = m_known[m_bot][BELOW];
    m_unknown[NABOVE] = m_empty_set;
    m_unknown[NBELOW] = m_empty_set;

    POMAGMA_INFO("Initializing nullary_function cache");
    for (const auto& i : signature().nullary_functions()) {
        const std::string& name = i.first;
        Ob ob = i.second->find();
        Approximation approx = ob ? known(ob) : unknown();
        POMAGMA_INSERT(m_nullary_cache, name, approx);
    }

    POMAGMA_INFO("Initializing binary_function cache");
    for (const auto& i : signature().binary_functions()) {
        const auto& fun = *i.second;
        const uint64_t hash = hash_name(i.first);
        typedef SetPairToSetCache Cache;
        for (Parity p : {ABOVE, BELOW}) {
            POMAGMA_INSERT(
                m_binary_cache, CacheKey(hash, VAL, p),
                new Cache(worker_pool,
                          [this, &fun, p](const std::pair<SetId, SetId>& x) {
                    return function_lhs_rhs(fun, x.first, x.second, p);
                }));
        }
        for (Parity p : {NABOVE, NBELOW}) {
            POMAGMA_INSERT(
                m_binary_cache, CacheKey(hash, RHS, p),
                new Cache(worker_pool,
                          [this, &fun, p](const std::pair<SetId, SetId>& x) {
                    return function_lhs_val(fun, x.first, x.second, p);
                }));
            POMAGMA_INSERT(
                m_binary_cache, CacheKey(hash, LHS, p),
                new Cache(worker_pool,
                          [this, &fun, p](const std::pair<SetId, SetId>& x) {
                    return function_rhs_val(fun, x.first, x.second, p);
                }));
        }
    }

    POMAGMA_INFO("Initializing symmetric_function cache");
    for (const auto& i : signature().symmetric_functions()) {
        const auto& fun = *i.second;
        const uint64_t hash = hash_name(i.first);
        typedef SetPairToSetCache Cache;
        for (Parity p : {ABOVE, BELOW}) {
            POMAGMA_INSERT(
                m_binary_cache, CacheKey(hash, VAL, p),
                new Cache(worker_pool,
                          [this, &fun, p](const std::pair<SetId, SetId>& x) {
                    return function_lhs_rhs(fun, x.first, x.second, p);
                }));
        }
        for (Parity p : {NABOVE, NBELOW}) {
            auto* cache = new Cache(
                worker_pool, [this, &fun, p](const std::pair<SetId, SetId>& x) {
                    return function_lhs_val(fun, x.first, x.second, p);
                });
            POMAGMA_INSERT(m_binary_cache, CacheKey(hash, RHS, p), cache);
            POMAGMA_INSERT(m_binary_cache, CacheKey(hash, LHS, p), cache);
        }
    }
}