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

Partially working

parent d9190c42
......@@ -45,6 +45,7 @@ namespace apg {
if (dmap & 85) {
lmask |= 7;
}
if (dmap) { std::cerr << centre << " " << dmap << std::endl; }
}
// Use a uint64 as an ordered pair of uint32s:
......
......@@ -12,6 +12,16 @@
return z;
}
void displaycentre(uint32_t *d) {
for (uint64_t i = 0; i < 16; i++) {
for (uint64_t j = 8; j < 24; j++) {
std::cerr << (((d[i] >> j) & 1) ? '*' : '.');
}
std::cerr << std::endl;
}
std::cerr << std::endl;
}
void iter4_var_leaf(uint64_t * inleaf, uint64_t * centres) {
/*
* Find the 8-by-8 centre after iterating a 16-by-16 leaf for a
......@@ -23,14 +33,19 @@
if (bis >= 9) {
apg::z64_to_r32_centre_avx(inleaf, d);
// displaycentre(d);
iterate_avx_16_12(d, e, 0, 0, 0, false);
iterate_avx_12_8(d+2, e+2, 0, 0, 0, false);
// displaycentre(d);
} else {
apg::z64_to_r32_centre_ssse3(inleaf, d);
iterate_sse2_16_12(d, e, 0, 0, 0, false);
iterate_sse2_12_8(d+2, e+2, 0, 0, 0, false);
}
centres[0] = r32_centre_to_u64(d, 0, 0);
// std::cerr << inleaf[0] << " " << inleaf[1] << " " << inleaf[2] << " " << inleaf[3] << ": " << centres[0] << std::endl;
}
bool iterate_var_leaf(int n, uint64_t * inleaves, uint64_t * outleaf) {
......
......@@ -12,6 +12,9 @@ namespace apg {
0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0,
1, 0, 0, 0, 5, 0, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0};
const static uint8_t __linvperm[] __attribute__((aligned(64))) = {0,
8, 4, 12, 1, 9, 5, 13, 2, 10, 6, 14, 3, 11, 7, 15,
0, 8, 4, 12, 1, 9, 5, 13, 2, 10, 6, 14, 3, 11, 7, 15};
void transpose_bytes_avx(uint64_t* a, uint64_t* b) {
......@@ -308,12 +311,12 @@ namespace apg {
// Dirty hack to perform << 8 and >> 8 during movups:
"movups %%xmm0, 1(%1) \n\t"
"movups %%xmm1, 15(%1) \n\t"
"movups %%xmm0, 15(%1) \n\t"
"movups %%xmm2, 33(%1) \n\t"
"movups %%xmm3, 47(%1) \n\t"
"movups %%xmm2, 47(%1) \n\t"
: /* no output operands -- implicitly volatile */
: "r" (c), "r" (b), "r" (__lifeperm)
: "r" (c), "r" (b), "r" (__linvperm)
: "xmm0", "xmm1", "xmm2", "xmm3", "memory" );
}
......@@ -335,12 +338,12 @@ namespace apg {
// Dirty hack to perform << 8 and >> 8 during movups:
"vmovups %%xmm0, 1(%1) \n\t"
"vmovups %%xmm1, 15(%1) \n\t"
"vmovups %%xmm0, 15(%1) \n\t"
"vmovups %%xmm2, 33(%1) \n\t"
"vmovups %%xmm3, 47(%1) \n\t"
"vmovups %%xmm2, 47(%1) \n\t"
: /* no output operands -- implicitly volatile */
: "r" (c), "r" (b), "r" (__lifeperm)
: "r" (c), "r" (b), "r" (__linvperm)
: "xmm0", "xmm1", "xmm2", "xmm3", "memory" );
}
......
#pragma once
#include <stdint.h>
#include <cstring>
#include <iostream>
#include "lifeperm.h"
#include "lifelogic/iterators_all.h"
......
......@@ -42,9 +42,22 @@ namespace apg {
*/
kivtable<nicearray<I, 4>, I, nicearray<I, 2> > biresults;
void printnode(hypernode<I> hnode) {
for (int y = 0; y < (16 << hnode.depth); y++) {
for (int x = 0; x < (16 << hnode.depth); x++) {
uint64_t c = this->getcell_recurse(hnode, x, y);
if (c > 1) {std::cout << "\033[3" << ((c >> 1) % 7) + 1 << ";1m"; }
if (c > 0) {std::cout << "_*.o"[c & 3]; } else { std::cout << "."; }
if (c > 1) {std::cout << "\033[0m"; }
}
std::cout << std::endl;
}
}
uint64_t node2lanes(uint64_t rule, I depth, I index) {
if (index == 0) {
// std::cerr << "index = 0" << std::endl;
return 0xffff;
}
......@@ -53,6 +66,13 @@ namespace apg {
if ((pptr->value.lanes & 0xffff0000ull) != ((rule + 1) << 16)) {
pptr->value.lanes = determine_direction(rule, pptr->key.x) | ((rule + 1) << 16);
}
/*
if (pptr->value.lanes & 255) {
std::cout << (pptr->value.lanes & 255) << std::endl;
printnode(hypernode<I>(index, depth));
}
*/
// std::cerr << pptr->value.lanes << std::endl;
return pptr->value.lanes & 0xffffffff0000ffffull;
} else {
auto pptr = this->ind2ptr_nonleaf(depth, index);
......@@ -86,11 +106,11 @@ namespace apg {
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);
std::memcpy(cc.x + 4*i, arr, 32);
std::memcpy(tc.x + 4*i, arr + 4, 32);
std::memcpy(bc.x + 4*i, arr + 8, 32);
std::memcpy(cl.x + 4*i, arr + 12, 32);
std::memcpy(cr.x + 4*i, arr + 16, 32);
tlx += 4; trx += 4; blx += 4; brx += 4;
}
......@@ -99,6 +119,7 @@ namespace apg {
childlanes[4] = node2lanes(rule, depth - 1, this->make_leaf(cc));
childlanes[5] = node2lanes(rule, depth - 1, this->make_leaf(cr));
childlanes[7] = node2lanes(rule, depth - 1, this->make_leaf(bc));
adml &= (childlanes[1] & childlanes[3] & childlanes[4] & childlanes[5] & childlanes[7]);
} else {
auto pptr_tl = ind2ptr_nonleaf(depth - 1, pptr->key.x[0]);
auto pptr_tr = ind2ptr_nonleaf(depth - 1, pptr->key.x[1]);
......@@ -114,9 +135,15 @@ namespace apg {
childlanes[4] = node2lanes(rule, depth - 1, make_nonleaf(depth - 1, cc));
childlanes[5] = node2lanes(rule, depth - 1, make_nonleaf(depth - 1, cr));
childlanes[7] = node2lanes(rule, depth - 1, make_nonleaf(depth - 1, bc));
adml &= (childlanes[1] & childlanes[3] & childlanes[4] & childlanes[5] & childlanes[7]);
}
/*
if ((adml == 4) && (depth <= 3)) {
std::cout << (adml) << std::endl;
printnode(hypernode<I>(index, depth));
}
*/
adml &= (childlanes[1] & childlanes[3] & childlanes[4] & childlanes[5] & childlanes[7]);
for (uint64_t i = 0; i < 9; i++) {
childlanes[i] >>= 32;
......@@ -173,7 +200,9 @@ namespace apg {
uint64_t is_solitonic(hypernode<I> hnode, int rule) {
uint64_t lanes1 = node2lanes(rule, hnode.depth, hnode.index);
if ((lanes1 & 255) == 0) { return 0; }
uint64_t lanes2 = node2lanes(rule, hnode.depth, hnode.index2);
if ((lanes2 & 255) == 0) { return 0; }
uint64_t commonlanes = (lanes1 & lanes2) >> 32;
if (commonlanes) { return 0; }
return ((((lanes1 >> 4) & lanes2) | ((lanes2 >> 4) & lanes1)) & 15);
......@@ -189,9 +218,22 @@ namespace apg {
if (is_solitonic(hnode, rule)) {
// BESZEL and ULQOMA tiles are provably non-interacting:
// std::cerr << "is solitonic" << std::endl;
I i1 = iterate_recurse1(part1, mantissa, exponent, rule, history).index;
I i2 = iterate_recurse1(part2, mantissa, exponent, rule, history).index;
return hypernode<I>(i1, i2, hnode.depth - 1);
if ((hnode.index == 0) || (hnode.index2 == 0)) {
I i3 = i1 | i2;
I ind3 = hnode.index | hnode.index2;
auto lanes = node2lanes(rule, hnode.depth, ind3);
if (lanes & 240) {
return hypernode<I>(0, i3, hnode.depth - 1);
} else {
return hypernode<I>(i3, 0, hnode.depth - 1);
}
} else {
return hypernode<I>(i1, i2, hnode.depth - 1);
}
} else {
......@@ -211,7 +253,9 @@ namespace apg {
if (i3 != 0) {
uint64_t lanes = node2lanes(rule, hnode2.depth, hnode2.index);
if (lanes & 255) { std::cerr << lanes << std::endl; }
if (lanes & 240) {
std::cerr << "lanes & 240" << std::endl;
res.index2 = i3;
} else {
res.index = i3;
......
......@@ -5,7 +5,7 @@
int main() {
apg::lifetree<uint32_t, 4> lt(1500);
apg::streamtree<uint32_t, 2> st(1500);
apg::streamtree<uint32_t, 1> st(1500);
/*
apg::pattern mkn(&lt, "16bo$15b2o$15bo3bo$14bo2bob2o$13b2o5bo$13bo2bo2bo$7bo5b2o4bo$7bobo5b2o"
......@@ -61,6 +61,7 @@ int main() {
std::ofstream out("rubbish3.mc");
ip46.write_macrocell(out);
/*
apg::pattern y(&lt, "4b2o9b2o$3bobo9bobo$3bobob2o3b2obobo$b2o2bob2o3b2obo2b2o$o4bo9bo4bo$6o"
"b2o3b2ob6o$7bobobobo$2b2ob2o2bobo2b2ob2o$2b2obo3bobo3bob2o$6b3o3b3o2$"
"6b3o3b3o$2b2obo3bobo3bob2o$2b2ob2o2bobo2b2ob2o$7bobobobo$6ob2o3b2ob6o$"
......@@ -69,16 +70,26 @@ int main() {
std::vector<std::string> parts = c.pbbosc(y, 2, 4);
for (int i = 0; i < parts.size(); i++) { std::cerr << parts[i] << std::endl; }
*/
apg::pattern x(&lt, "bo$obo$bo8$8bo$6bobo$5b2obo2$4b3o!", "b3s23");
std::cerr << "Population of Lidka: " << x.popcount((1 << 30) + 3) << std::endl;
x = x["b3s23"][32768];
std::cerr << "Population of Lidka: " << x.popcount((1 << 30) + 3) << std::endl;
x = apg::pattern(&lt, "bo$obo$bo8$8bo$6bobo$5b2obo2$4b3o!", "r1b3t3s3t4");
std::cerr << "Population of Lidka: " << x.popcount((1 << 30) + 3) << std::endl;
x = x["r1b3t3s3t4"][32768];
std::cerr << "Population of Lidka: " << x.popcount((1 << 30) + 3) << std::endl;
apg::pattern y(&st, "bo$obo$bo8$8bo$6bobo$5b2obo2$4b3o!", "b3s23");
std::cerr << "Population of Lidka: " << y.popcount((1 << 30) + 3) << std::endl;
for (int i = 0; i < 1000; i++) {
y = y["b3s23"][32];
}
std::cerr << "Population of Lidka: " << y.popcount((1 << 30) + 3) << std::endl;
std::cerr << y.gethnode().index << " " << y.gethnode().index2 << std::endl;
std::ofstream out2("lidka1.mc");
st.write_macrocell(out2, apg::hypernode<uint32_t>(y.gethnode().index, y.gethnode().depth), "b3s23");
std::ofstream out3("lidka2.mc");
st.write_macrocell(out3, apg::hypernode<uint32_t>(y.gethnode().index2, y.gethnode().depth), "b3s23");
return 0;
......
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