Commit e7b4976f authored by Adam P. Goucher's avatar Adam P. Goucher

Since we can essentially get LifeHistory for free

parent fac85f30
......@@ -813,8 +813,6 @@ namespace apg {
* 3 = andn
*/
auto it = memmap->find(std::make_pair(std::make_pair(lnode.index, rnode.index), lnode.depth));
if (lnode.index == 0) {
if (operation == 0 || operation == 3) {
return lnode;
......@@ -827,47 +825,56 @@ namespace apg {
} else {
return lnode;
}
} else if (it != memmap->end()) {
return hypernode<I>(it->second, lnode.depth);
} else if (lnode.depth >= 1){
kiventry<nicearray<I, 4>, I, J >* lptr = ind2ptr_nonleaf(lnode.depth, lnode.index);
kiventry<nicearray<I, 4>, I, J >* rptr = ind2ptr_nonleaf(rnode.depth, rnode.index);
hypernode<I> ytl = boolean_recurse(hypernode<I>(lptr->key.x[0], lnode.depth-1), hypernode<I>(rptr->key.x[0], rnode.depth-1),
operation, memmap);
hypernode<I> ytr = boolean_recurse(hypernode<I>(lptr->key.x[1], lnode.depth-1), hypernode<I>(rptr->key.x[1], rnode.depth-1),
operation, memmap);
hypernode<I> ybl = boolean_recurse(hypernode<I>(lptr->key.x[2], lnode.depth-1), hypernode<I>(rptr->key.x[2], rnode.depth-1),
operation, memmap);
hypernode<I> ybr = boolean_recurse(hypernode<I>(lptr->key.x[3], lnode.depth-1), hypernode<I>(rptr->key.x[3], rnode.depth-1),
operation, memmap);
nicearray<I, 4> cc = {ytl.index, ytr.index, ybl.index, ybr.index};
hypernode<I> xcc = make_nonleaf_hn(lnode.depth, cc);
memmap->emplace(std::make_pair(std::make_pair(lnode.index, rnode.index), lnode.depth), xcc.index);
return xcc;
} else {
kiventry<nicearray<uint64_t, 4*N>, I, J >* lptr = ind2ptr_leaf(lnode.index);
kiventry<nicearray<uint64_t, 4*N>, I, J >* rptr = ind2ptr_leaf(rnode.index);
nicearray<uint64_t, 4*N> outleaf = {0ull};
if (operation == 0) {
for (int i = 0; i < 4*N; i++) {
outleaf.x[i] = lptr->key.x[i] & rptr->key.x[i];
}
} else if (operation == 1) {
for (int i = 0; i < 4*N; i++) {
outleaf.x[i] = lptr->key.x[i] | rptr->key.x[i];
}
} else if (operation == 2) {
for (int i = 0; i < 4*N; i++) {
outleaf.x[i] = lptr->key.x[i] ^ rptr->key.x[i];
}
// Both operands are nonzero, so we need to actually compute
// the result recursively. Firstly, we check to see whether
// the result has already been computed and cached:
auto it = memmap->find(std::make_pair(std::make_pair(lnode.index, rnode.index), lnode.depth));
if (it != memmap->end()) {
return hypernode<I>(it->second, lnode.depth);
} else if (lnode.depth >= 1){
// Nonleaf node:
kiventry<nicearray<I, 4>, I, J >* lptr = ind2ptr_nonleaf(lnode.depth, lnode.index);
kiventry<nicearray<I, 4>, I, J >* rptr = ind2ptr_nonleaf(rnode.depth, rnode.index);
hypernode<I> ytl = boolean_recurse(hypernode<I>(lptr->key.x[0], lnode.depth-1), hypernode<I>(rptr->key.x[0], rnode.depth-1),
operation, memmap);
hypernode<I> ytr = boolean_recurse(hypernode<I>(lptr->key.x[1], lnode.depth-1), hypernode<I>(rptr->key.x[1], rnode.depth-1),
operation, memmap);
hypernode<I> ybl = boolean_recurse(hypernode<I>(lptr->key.x[2], lnode.depth-1), hypernode<I>(rptr->key.x[2], rnode.depth-1),
operation, memmap);
hypernode<I> ybr = boolean_recurse(hypernode<I>(lptr->key.x[3], lnode.depth-1), hypernode<I>(rptr->key.x[3], rnode.depth-1),
operation, memmap);
nicearray<I, 4> cc = {ytl.index, ytr.index, ybl.index, ybr.index};
hypernode<I> xcc = make_nonleaf_hn(lnode.depth, cc);
memmap->emplace(std::make_pair(std::make_pair(lnode.index, rnode.index), lnode.depth), xcc.index);
return xcc;
} else {
for (int i = 0; i < 4*N; i++) {
outleaf.x[i] = lptr->key.x[i] & ~(rptr->key.x[i]);
// Leaf node:
kiventry<nicearray<uint64_t, 4*N>, I, J >* lptr = ind2ptr_leaf(lnode.index);
kiventry<nicearray<uint64_t, 4*N>, I, J >* rptr = ind2ptr_leaf(rnode.index);
nicearray<uint64_t, 4*N> outleaf = {0ull};
if (operation == 0) {
for (int i = 0; i < 4*N; i++) {
outleaf.x[i] = lptr->key.x[i] & rptr->key.x[i];
}
} else if (operation == 1) {
for (int i = 0; i < 4*N; i++) {
outleaf.x[i] = lptr->key.x[i] | rptr->key.x[i];
}
} else if (operation == 2) {
for (int i = 0; i < 4*N; i++) {
outleaf.x[i] = lptr->key.x[i] ^ rptr->key.x[i];
}
} else {
for (int i = 0; i < 4*N; i++) {
outleaf.x[i] = lptr->key.x[i] & ~(rptr->key.x[i]);
}
}
I res = make_leaf(outleaf);
memmap->emplace(std::make_pair(std::make_pair(lnode.index, rnode.index), 0), res);
return hypernode<I>(res, 0);
}
I res = make_leaf(outleaf);
memmap->emplace(std::make_pair(std::make_pair(lnode.index, rnode.index), 0), res);
return hypernode<I>(res, 0);
}
}
......
......@@ -14,18 +14,18 @@ namespace apg {
};
template<typename I>
class streamtree : public lifetree_generic<I, 1, streammeta<I> > {
template<typename I, int N>
class streamtree : public lifetree_generic<I, N, streammeta<I> > {
public:
using lifetree_generic<I, 1, streammeta<I> >::htree;
using lifetree_generic<I, 1, streammeta<I> >::iterate_recurse;
using lifetree_generic<I, 1, streammeta<I> >::iterate_recurse1;
using lifetree_generic<I, 1, streammeta<I> >::ind2ptr_leaf;
using lifetree_generic<I, 1, streammeta<I> >::ind2ptr_nonleaf;
using lifetree_generic<I, 1, streammeta<I> >::ninechildren;
using lifetree_generic<I, 1, streammeta<I> >::fourchildren;
using lifetree_generic<I, 1, streammeta<I> >::make_nonleaf;
using lifetree_generic<I, N, streammeta<I> >::htree;
using lifetree_generic<I, N, streammeta<I> >::iterate_recurse;
using lifetree_generic<I, N, streammeta<I> >::iterate_recurse1;
using lifetree_generic<I, N, streammeta<I> >::ind2ptr_leaf;
using lifetree_generic<I, N, streammeta<I> >::ind2ptr_nonleaf;
using lifetree_generic<I, N, streammeta<I> >::ninechildren;
using lifetree_generic<I, N, streammeta<I> >::fourchildren;
using lifetree_generic<I, N, streammeta<I> >::make_nonleaf;
using lifetree_abstract<I>::boolean_recurse;
streamtree(uint64_t maxmem) {
......@@ -72,15 +72,28 @@ namespace apg {
if (adml == 0) { pptr->value.lanes = ((rule + 1) << 16); return 0; }
if (depth == 1) {
auto pptr_tl = ind2ptr_leaf(pptr->key.x[0]);
auto pptr_tr = ind2ptr_leaf(pptr->key.x[1]);
auto pptr_bl = ind2ptr_leaf(pptr->key.x[2]);
auto pptr_br = ind2ptr_leaf(pptr->key.x[3]);
nicearray<uint64_t, 4> cc = {pptr_tl->key.x[3], pptr_tr->key.x[2], pptr_bl->key.x[1], pptr_br->key.x[0]};
nicearray<uint64_t, 4> tc = {pptr_tl->key.x[1], pptr_tr->key.x[0], pptr_tl->key.x[3], pptr_tr->key.x[2]};
nicearray<uint64_t, 4> bc = {pptr_bl->key.x[1], pptr_br->key.x[0], pptr_bl->key.x[3], pptr_br->key.x[2]};
nicearray<uint64_t, 4> cl = {pptr_tl->key.x[2], pptr_tl->key.x[3], pptr_bl->key.x[0], pptr_bl->key.x[1]};
nicearray<uint64_t, 4> cr = {pptr_tr->key.x[2], pptr_tr->key.x[3], pptr_br->key.x[0], pptr_br->key.x[1]};
uint64_t* tlx = ind2ptr_leaf(pptr->key.x[0])->key.x;
uint64_t* trx = ind2ptr_leaf(pptr->key.x[1])->key.x;
uint64_t* blx = ind2ptr_leaf(pptr->key.x[2])->key.x;
uint64_t* brx = ind2ptr_leaf(pptr->key.x[3])->key.x;
nicearray<uint64_t, 4*N> cc, tc, bc, cl, cr;
for (uint64_t i = 0; i < N; i++) {
uint64_t arr[20] = {tlx[3], trx[2], blx[1], brx[0],
tlx[1], trx[0], tlx[3], trx[2],
blx[1], brx[0], blx[3], brx[2],
tlx[2], tlx[3], blx[0], blx[1],
trx[2], trx[3], brx[0], brx[1]};
std::memcpy(cc.x + 4*i, arr, 16);
std::memcpy(tc.x + 4*i, arr + 4, 16);
std::memcpy(bc.x + 4*i, arr + 8, 16);
std::memcpy(cl.x + 4*i, arr + 12, 16);
std::memcpy(cr.x + 4*i, arr + 16, 16);
tlx += 4; trx += 4; blx += 4; brx += 4;
}
childlanes[1] = node2lanes(rule, depth - 1, this->make_leaf(tc));
childlanes[3] = node2lanes(rule, depth - 1, this->make_leaf(cl));
childlanes[4] = node2lanes(rule, depth - 1, this->make_leaf(cc));
......
......@@ -5,7 +5,7 @@
int main() {
apg::lifetree<uint32_t, 4> lt(1500);
apg::streamtree<uint32_t> st(1500);
apg::streamtree<uint32_t, 2> st(1500);
/*
apg::pattern mkn(&lt, "16bo$15b2o$15bo3bo$14bo2bob2o$13b2o5bo$13bo2bo2bo$7bo5b2o4bo$7bobo5b2o"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment