Revision: 70074
          http://sourceforge.net/p/brlcad/code/70074
Author:   mdtwenty
Date:     2017-08-11 20:37:09 +0000 (Fri, 11 Aug 2017)
Log Message:
-----------
bool_eval() function using new boolean tree representation, where each tree 
node is encoded in 32 bits

Modified Paths:
--------------
    brlcad/branches/opencl/include/rt/region.h
    brlcad/branches/opencl/include/rt/rt_instance.h
    brlcad/branches/opencl/include/rt/tree.h
    brlcad/branches/opencl/src/librt/bool.c
    brlcad/branches/opencl/src/librt/pr.c
    brlcad/branches/opencl/src/librt/prep.c
    brlcad/branches/opencl/src/librt/primitives/bool.cl
    brlcad/branches/opencl/src/librt/primitives/common.cl
    brlcad/branches/opencl/src/librt/primitives/primitive_util.c
    brlcad/branches/opencl/src/librt/tree.c

Modified: brlcad/branches/opencl/include/rt/region.h
===================================================================
--- brlcad/branches/opencl/include/rt/region.h  2017-08-10 21:40:14 UTC (rev 
70073)
+++ brlcad/branches/opencl/include/rt/region.h  2017-08-11 20:37:09 UTC (rev 
70074)
@@ -45,8 +45,8 @@
     struct bu_list      l;              /**< @brief magic # and doubly linked 
list */
     const char *        reg_name;       /**< @brief Identifying string */
     union tree *        reg_treetop;    /**< @brief Pointer to boolean tree */
-    union tree_rpn *   reg_rtree;      /**< @brief Pointer to boolean tree in 
RPN */
-    size_t             reg_nrtree;     /**< @brief number of elements in rtree 
*/
+    struct bit_tree *   reg_btree;      /**< @brief Pointer to bit boolean 
tree */
+    size_t              reg_nbtree;     /**< @brief number of elements in 
btree */
     int                 reg_bit;        /**< @brief constant index into 
Regions[] */
     int                 reg_regionid;   /**< @brief Region ID code.  If <=0, 
use reg_aircode */
     int                 reg_aircode;    /**< @brief Region ID AIR code */
@@ -68,14 +68,12 @@
 #define RT_CK_REGION(_p) BU_CKMAG(_p, RT_REGION_MAGIC, "struct region")
 
 #ifdef USE_OPENCL
-union cl_tree_rpn {
-    long uop;
-    long st_bit;
+struct cl_tree_bit {
+    cl_uint val;
 };
 
 struct cl_bool_region {
-    cl_uint rtree_offset;           /**< @brief index to the start of the rpn 
tree */
-    cl_uint reg_nrtree;             /**< @brief number of elements in rtree */
+    cl_uint btree_offset;           /**< @brief index to the start of the bit 
tree */
     cl_int reg_aircode;             /**< @brief Region ID AIR code */
     cl_int reg_bit;                 /**< @brief constant index into Regions[] 
*/
     cl_short reg_all_unions;        /**< @brief 1=boolean tree is all unions */

Modified: brlcad/branches/opencl/include/rt/rt_instance.h
===================================================================
--- brlcad/branches/opencl/include/rt/rt_instance.h     2017-08-10 21:40:14 UTC 
(rev 70073)
+++ brlcad/branches/opencl/include/rt/rt_instance.h     2017-08-11 20:37:09 UTC 
(rev 70074)
@@ -360,7 +360,7 @@
 clt_db_store_bvh(size_t count, struct clt_linear_bvh_node *nodes);
 
 RT_EXPORT extern void
-clt_db_store_regions(size_t sz_tree_rpn, union tree_rpn *rtp, size_t nregions, 
struct cl_bool_region *regions, struct clt_region *mtls);
+clt_db_store_regions(size_t sz_btree_array, struct bit_tree *btp, size_t 
nregions, struct cl_bool_region *regions, struct clt_region *mtls);
 
 RT_EXPORT extern void
 clt_db_store_regions_table(cl_uint *regions_table, size_t regions_table_size);

Modified: brlcad/branches/opencl/include/rt/tree.h
===================================================================
--- brlcad/branches/opencl/include/rt/tree.h    2017-08-10 21:40:14 UTC (rev 
70073)
+++ brlcad/branches/opencl/include/rt/tree.h    2017-08-11 20:37:09 UTC (rev 
70074)
@@ -255,17 +255,31 @@
 #define TREE_LIST_NULL  ((struct tree_list *)0)
 
 /**
- * Flattened RPN version of the infix union tree.
+ * Flattened version of the infix union tree.
  */
-#define UOP_NOP                -1
-#define UOP_UNION      -2
-#define UOP_INTERSECT  -3
-#define UOP_SUBTRACT   -4
-#define UOP_XOR                -5
+#define UOP_UNION        1         /**< @brief  Binary: L union R */
+#define UOP_INTERSECT    2         /**< @brief  Binary: L intersect R */
+#define UOP_SUBTRACT     3         /**< @brief  Binary: L subtract R */
+#define UOP_XOR          4         /**< @brief  Binary: L xor R, not both*/
+#define UOP_NOT          5         /**< @brief  Unary:  not L */
+#define UOP_GUARD        6         /**< @brief  Unary:  not L, or else! */
+#define UOP_XNOP         7         /**< @brief  Unary:  L, mark region */
 
-union tree_rpn {                       /* UOPs are negative. SOLIDs are 
non-negative */
-    long uop;
-    long st_bit;
+#define UOP_SOLID        0         /**< @brief  Leaf:  tr_stp -> solid */
+
+/**
+ * bit expr tree representation
+ *
+ * node:
+ *      uint uop : 3
+ *      uint right_child : 29
+ *
+ * leaf:
+ *      uint uop : 3
+ *      uint st_bit : 29
+ */
+struct bit_tree {
+    uint val;
 };
 
 /* Print an expr tree */
@@ -280,9 +294,10 @@
                                      const struct partition *partp,
                                      int pr_name,
                                      int lvl);
-/* Print an RPN expr tree */
-RT_EXPORT extern void rt_pr_rtree(const union tree_rpn *rtp,
-                                 size_t rlen);
+/* Print a bit expr tree */
+RT_EXPORT extern void rt_pr_bit_tree(const struct bit_tree *btp,
+                                     int idx,
+                                     int lvl);
 
 /**
  * Duplicate the contents of a db_tree_state structure, including a
@@ -769,9 +784,9 @@
 RT_EXPORT extern void rt_optim_tree(union tree *tp,
                                    struct resource *resp);
 
-RT_EXPORT extern void rt_tree_rpn(union tree_rpn *rtp,
-                                 const union tree *tp,
-                                 size_t *len);
+RT_EXPORT extern void rt_bit_tree(struct bit_tree *btp,
+                                  const union tree *tp,
+                                  size_t *len);
 
 
 

Modified: brlcad/branches/opencl/src/librt/bool.c
===================================================================
--- brlcad/branches/opencl/src/librt/bool.c     2017-08-10 21:40:14 UTC (rev 
70073)
+++ brlcad/branches/opencl/src/librt/bool.c     2017-08-11 20:37:09 UTC (rev 
70074)
@@ -49,7 +49,7 @@
 #define BOOL_FALSE 0
 #define BOOL_TRUE 1
 
-#define BOOL_STACKSIZE 64
+#define BOOL_STACKSIZE 128
 
 
 /**
@@ -657,7 +657,7 @@
  * -1 If no rays are contributing segs for this region.
  */
 HIDDEN int
-bool_max_raynum(const union tree_rpn *rtp, size_t rtlen, const struct 
partition *pp)
+bool_max_raynum(struct bit_tree *btp, size_t btlen, register const struct 
partition *pp)
 {
     int max;
     size_t i;
@@ -665,9 +665,9 @@
     RT_CK_PARTITION(pp);
 
     max = -1;
-    for (i=0; i<rtlen; i++) {
-       if (rtp[i].uop >= 0) {
-           const long st_bit = rtp[i].st_bit;
+    for (i=0; i<btlen; i++) {
+       if ((btp[i].val & 7) == UOP_SOLID) {
+           const uint st_bit = btp[i].val >> 3;
            struct seg **segpp;
 
            /* Maybe it hasn't been shot yet, or ray missed */
@@ -984,8 +984,8 @@
             * retain that one.
             */
        } else {
-           int r1 = bool_max_raynum(lastregion->reg_rtree, 
lastregion->reg_nrtree, pp);
-           int r2 = bool_max_raynum(regp->reg_rtree, regp->reg_nrtree, pp);
+           int r1 = bool_max_raynum(lastregion->reg_btree, 
lastregion->reg_nbtree, pp);
+           int r2 = bool_max_raynum(regp->reg_btree, regp->reg_nbtree, pp);
 
            /* Only use this algorithm if one is not the main ray */
            if (r1 > 0 || r2 > 0) {
@@ -1155,24 +1155,47 @@
  *  0 Region is not ready
  */
 HIDDEN int
-bool_test_tree(const union tree_rpn *rtp, size_t rtlen, const struct bu_bitv 
*solidbits)
+bool_test_tree(const struct bit_tree *btp, int idx, register const struct 
bu_bitv *solidbits)
 {
-    int all;
-    size_t i;
+    uint uop;
+    BU_CK_BITV(solidbits);
 
-    all = 1;
-    for (i=0; i<rtlen; i++) {
-       if (rtp[i].uop >= 0) {
-           if (BU_BITTEST(solidbits, rtp[i].st_bit)) {
-               /* This solid's been shot, segs are valid. */
-               all &= 1;
-           } else {
-               /* This solid has not been shot yet. */
-               all &= 0;
+    uop = btp[idx].val & 7;
+    switch (uop) {
+        case UOP_SOLID:
+            {
+                uint st_bit = btp[idx].val >> 3;
+                if (BU_BITTEST(solidbits, st_bit)) {
+                    /* This solid's been shot, segs are valid. */
+                    return 1;
+                }
+
+                /*
+                * This solid has not been shot yet.
+                */
+               return 0;
            }
-       }
+
+       case UOP_NOT:
+           return !bool_test_tree(btp, idx+1, solidbits);
+
+       case UOP_UNION:
+       case UOP_INTERSECT:
+       case UOP_SUBTRACT:
+       case UOP_XOR:
+            {
+                uint rchild;
+               if (!bool_test_tree(btp, idx+1, solidbits))
+                   return 0;
+
+                rchild = btp[idx].val >> 3;
+               return bool_test_tree(btp, rchild, solidbits);
+            }
+
+       default:
+           bu_bomb("bool_test_tree: bad op\n");
     }
-    return all;
+    return 0;
 }
 
 
@@ -1200,7 +1223,7 @@
        RT_CK_REGION(regp);
 
        /* Check region prerequisites */
-       if (!bool_test_tree(regp->reg_rtree, regp->reg_nrtree, solidbits)) {
+       if (!bool_test_tree(regp->reg_btree, 0, solidbits)) {
            return 0;
        }
     }
@@ -1221,62 +1244,149 @@
  * -1 tree is in error (GUARD)
  */
 HIDDEN int
-bool_eval(const union tree_rpn *rtp, size_t rtlen, struct partition *partp)
+bool_eval(struct bit_tree *treep, struct partition *partp, struct resource 
*resp)
+/* Tree to evaluate */
+/* Partition to evaluate */
+/* XOR true (and overlap) return */
+/* resource pointer for this CPU */
 {
-    uint8_t stack[BOOL_STACKSIZE];     /* uh bits would be enough */
-    size_t stackend;
-    uint8_t a, b, ret;
-    size_t i;
+    static int stack[BOOL_STACKSIZE*MAX_PSW];
+    int *sp;
+    int ret;
+    uint uop;
+    int idx;
 
-    stack[0] = 0;
-    stackend = 0;
-    for (i=0; i<rtlen; i++) {
-       if (stackend >= BOOL_STACKSIZE)
-           return -1;
+    RT_CK_PT(partp);
 
-       switch (rtp[i].uop) {
-           case UOP_NOP:
-               stack[stackend++] = 0;
-               break;
+    sp = &stack[BOOL_STACKSIZE*resp->re_cpu];
+    *sp++ = INT_MAX;
+    idx = 0;
+    for (;;) {
+       for (;;) {
+            uop = treep[idx].val & 7;
 
-           case UOP_UNION:
-               b = stack[--stackend];
-               a = stack[--stackend];
-               stack[stackend++] = (a || b);
-               break;
-           case UOP_INTERSECT:
-               b = stack[--stackend];
-               a = stack[--stackend];
-               stack[stackend++] = (a && b);
-               break;
-           case UOP_SUBTRACT:
-               b = stack[--stackend];
-               a = stack[--stackend];
-               stack[stackend++] = (a && !b);
-               break;
-           case UOP_XOR:
-               b = stack[--stackend];
-               a = stack[--stackend];
-               stack[stackend++] = (a ^ b);
-               break;
+            switch (uop) {
+                case UOP_SOLID:
+                    {
+                        /* Tree Leaf */
+                        register const uint st_bit = treep[idx].val >> 3;
+                        register struct seg **segpp;
+                        ret = 0;
+                        for (BU_PTBL_FOR(segpp, (struct seg **), 
&partp->pt_seglist)) {
+                            if ((*segpp)->seg_stp->st_bit == st_bit) {
+                                ret = 1;
+                                break;
+                            }
+                       }
+                    }
+                    break;
+                case UOP_UNION:
+                case UOP_INTERSECT:
+                case UOP_SUBTRACT:
+                case UOP_XOR:
+                    *sp++ = idx;
+                    idx++;
+                    continue;
+                default:
+                    bu_log("bool_eval:  bad stack op [%d]\n", uop);
+                    return BOOL_TRUE;  /* screw up output */
+            }
+           break;
+       }
 
-           default:
-               {
-                   const long st_bit = rtp[i].st_bit;
-                   struct seg **segpp;
-                   ret = 0;
-                   for (BU_PTBL_FOR(segpp, (struct seg **), 
&partp->pt_seglist)) {
-                       if ((*segpp)->seg_stp->st_bit == st_bit) {
-                           ret = 1;
-                           break;
-                       }
+        for (;;) {
+            idx = *--sp;
+
+            switch (idx) {
+                case INT_MAX:
+                    return ret;                /* top of tree again */
+                case -1:
+                    /* Special operation for subtraction */
+                   ret = !ret;
+                   continue;
+                case -2:
+                    /*
+                    * Special operation for XOR.  lhs was true.  If rhs
+                    * subtree was true, an overlap condition exists (both
+                    * sides of the XOR are BOOL_TRUE).  Return error
+                    * condition.  If subtree is false, then return BOOL_TRUE
+                    * (from lhs).
+                    */
+                   if (ret) {
+                       /* stacked temp val: rhs */
+                       return -1;      /* GUARD error */
                    }
-                   stack[stackend++] = ret;
+                   ret = BOOL_TRUE;
+                   sp--;                       /* pop temp val */
+                   continue;
+                case -3:
+                    /*
+                    * Special NOP for XOR.  lhs was false.  If rhs is true,
+                    * take note of its regionp.
+                    */
+                   sp--;                       /* pop temp val */
+                   continue;
+                default:
+                    break;
+            }
+
+            uop = treep[idx].val & 7;
+
+           /*
+            * Here, each operation will look at the operation just completed
+            * (the left branch of the tree generally), and rewrite the top of
+            * the stack and/or branch accordingly.
+            */
+            switch (uop) {
+                case UOP_SOLID:
+                    bu_log("bool_eval:  pop SOLID?\n");
+                    return BOOL_TRUE;      /* screw up output */
+                case UOP_UNION:
+                    if (ret) continue;     /* BOOL_TRUE, we are done */
+                    /* lhs was false, rewrite as rhs tree */
+                    idx = treep[idx].val >> 3;
+                    break;
+               case UOP_INTERSECT:
+                   if (!ret) {
+                       ret = BOOL_FALSE;
+                       continue;
+                   }
+                   /* lhs was true, rewrite as rhs tree */
+                    idx = treep[idx].val >> 3;
                    break;
-               }
+                case UOP_SUBTRACT:
+                   if (!ret) continue; /* BOOL_FALSE, we are done */
+                   /* lhs was true, rewrite as NOT of rhs tree */
+                   /* We introduce the special NOT operator here */
+                    *sp++ = -1;
+                    idx = treep[idx].val >> 3;
+                   break;
+               case UOP_XOR:
+                   if (ret) {
+                       /* lhs was true, rhs better not be, or we have an
+                        * overlap condition.  Rewrite as guard node followed
+                        * by rhs.
+                        */
+                        idx = treep[idx].val >> 3;
+                       *sp++ = idx;            /* temp val for guard node */
+                       *sp++ = -2;
+                   } else {
+                       /* lhs was false, rewrite as xnop node and result of
+                        * rhs.
+                        */
+                        idx = treep[idx].val >> 3;
+                       *sp++ = idx;            /* temp val for xnop */
+                       *sp++ = -3;
+                   }
+                   break;
+               default:
+                   bu_log("bool_eval:  bad pop op [%d]\n", uop);
+                   return BOOL_TRUE;       /* screw up output */
+            }
+           break;
        }
     }
-    return stack[0];
+    /* NOTREACHED */
 }
 
 
@@ -1542,7 +1652,7 @@
                    lastregion = regp;
                    continue;
                }
-               if (bool_eval(regp->reg_rtree, regp->reg_nrtree, pp) == 
BOOL_FALSE) {
+               if (bool_eval(regp->reg_btree, pp, ap->a_resource) == 
BOOL_FALSE) {
                    if (RT_G_DEBUG&DEBUG_PARTITION)
                        bu_log("BOOL_FALSE\n");
                    /* Null out non-claiming region's pointer */

Modified: brlcad/branches/opencl/src/librt/pr.c
===================================================================
--- brlcad/branches/opencl/src/librt/pr.c       2017-08-10 21:40:14 UTC (rev 
70073)
+++ brlcad/branches/opencl/src/librt/pr.c       2017-08-11 20:37:09 UTC (rev 
70074)
@@ -626,41 +626,74 @@
 
 
 /**
- * Produce representations of this postfix bool tree.
+ * Produce representations of this bit bool tree
  */
 void
-rt_pr_rtree(const union tree_rpn *rtp, size_t rtlen)
+rt_pr_bit_tree(const struct bit_tree *btp, int idx, int lvl)
+/* Tree to print */
+/* Offset in tree */
+/* Recursion level */
 {
-    size_t i;
+    uint uop, val;
 
-    bu_log("\npostfix: ");
-    for (i=0; i<rtlen; i++) {
-       switch (rtp[i].uop) {
-           case UOP_NOP:
-               bu_log("NOP");
-               break;
+    uop = btp[idx].val & 7;
+    val = btp[idx].val >> 3;
 
-           case UOP_UNION:
-               bu_log("%c", DB_OP_UNION);
-               break;
-           case UOP_INTERSECT:
-               bu_log("%c", DB_OP_INTERSECT);
-               break;
-           case UOP_SUBTRACT:
-               bu_log("%c", DB_OP_SUBTRACT);
-               break;
-           case UOP_XOR:
-               bu_log("XOR");
-               break;
+    if (lvl == 0) bu_log("bit tree: ");
 
-           default:
-               bu_log("%ld", rtp[i].st_bit);
-               break;
-       }
-       if (i != rtlen-1)
-           bu_log(" ");
+    switch (uop) {
+        case UOP_SOLID:
+            /* Tree leaf */
+            bu_log("%ld", val);
+            if (lvl == 0) bu_log("\n");
+            return;
+        case UOP_SUBTRACT:
+            bu_log("(");
+            rt_pr_bit_tree(btp, idx+1, lvl+1);
+            bu_log(" %c ", DB_OP_SUBTRACT);
+            rt_pr_bit_tree(btp, val, lvl+1);
+            bu_log(")");
+            break;
+        case UOP_UNION:
+            bu_log("(");
+            rt_pr_bit_tree(btp, idx+1, lvl+1);
+            bu_log(" %c ", DB_OP_UNION);
+            rt_pr_bit_tree(btp, val, lvl+1);
+            bu_log(")");
+            break;
+        case UOP_INTERSECT:
+            bu_log("(");
+            rt_pr_bit_tree(btp, idx+1, lvl+1);
+            bu_log(" %c ", DB_OP_INTERSECT);
+            rt_pr_bit_tree(btp, val, lvl+1);
+            bu_log(")");
+            break;
+        case UOP_XOR:
+            bu_log("(");
+            rt_pr_bit_tree(btp, idx+1, lvl+1);
+            bu_log(" XOR ");
+            rt_pr_bit_tree(btp, val, lvl+1);
+            bu_log(")");
+            break;
+
+        case UOP_NOT:
+            bu_log(" !");
+            rt_pr_bit_tree(btp, idx+1, lvl+1);
+            break;
+        case UOP_GUARD:
+            bu_log(" GUARD ");
+            /* TODO */
+            break;
+        case UOP_XNOP:
+            bu_log(" XNOP ");
+            /* TODO */
+            break;
+        default:
+            bu_log("rt_bit_tree: bad op[%d]\n", uop);
+            exit(1);
+            break;
     }
-    bu_log("\n");
+    if (lvl == 0) bu_log("\n");
 }
 
 

Modified: brlcad/branches/opencl/src/librt/prep.c
===================================================================
--- brlcad/branches/opencl/src/librt/prep.c     2017-08-10 21:40:14 UTC (rev 
70073)
+++ brlcad/branches/opencl/src/librt/prep.c     2017-08-11 20:37:09 UTC (rev 
70074)
@@ -47,7 +47,7 @@
 
 extern void rt_ck(struct rt_i *rtip);
 
-HIDDEN void rt_solid_bitfinder(const union tree_rpn *rtp, size_t rtlen, struct 
soltab **solids, size_t nsolids, struct region *regp);
+HIDDEN void rt_solid_bitfinder(const struct bit_tree *btp, size_t btlen, 
struct soltab **solids, size_t nsolids, struct region *regp);
 
 
 /* XXX Need rt_init_rtg(), rt_clean_rtg() */
@@ -321,17 +321,17 @@
        rt_optim_tree(regp->reg_treetop, resp);
 
        len = 0;
-       rt_tree_rpn(NULL, regp->reg_treetop, &len);
-       regp->reg_rtree = (union tree_rpn *)bu_calloc(len, sizeof(union 
tree_rpn),"region rtree");
-       regp->reg_nrtree = 0;
-       rt_tree_rpn(regp->reg_rtree, regp->reg_treetop, &regp->reg_nrtree);
+       rt_bit_tree(NULL, regp->reg_treetop, &len);
+        regp->reg_btree = (struct bit_tree *)bu_calloc(len, sizeof(struct 
bit_tree), "region btree");
+        regp->reg_nbtree = 0;
+        rt_bit_tree(regp->reg_btree, regp->reg_treetop, &regp->reg_nbtree);
 
        if (RT_G_DEBUG&DEBUG_REGIONS) {
-           rt_pr_rtree(regp->reg_rtree, regp->reg_nrtree);
+           rt_pr_bit_tree(regp->reg_btree, 0, 0);
            rt_pr_tree_val(regp->reg_treetop, NULL, 2, 0);
        }
 
-       rt_solid_bitfinder(regp->reg_rtree, regp->reg_nrtree, rtip->rti_Solids, 
rtip->nsolids, regp);
+       rt_solid_bitfinder(regp->reg_btree, regp->reg_nbtree, rtip->rti_Solids, 
rtip->nsolids, regp);
        if (RT_G_DEBUG&DEBUG_REGIONS) {
            db_ck_tree(regp->reg_treetop);
            rt_pr_region(regp);
@@ -463,19 +463,21 @@
 
 #ifdef USE_OPENCL
 static void
-rt_rtree_translate(struct rt_i *rtip, struct soltab **primitives, union 
tree_rpn *rtp, size_t start, size_t end, const long n_primitives)
+rt_btree_translate(struct rt_i *rtip, struct soltab **primitives, struct 
bit_tree *btp, size_t start, size_t end, const long n_primitives)
 {
     size_t i;
     long j;
+    uint uop, st_bit;
 
     RT_CK_RTI(rtip);
 
-    for (i=start; i<start+end; i++) {
-       if (rtp[i].uop >= 0) {
-           const long st_bit = rtp[i].st_bit;
+    for (i=start; i<end; i++) {
+        uop = btp[i].val & 7;
+       if (uop == UOP_SOLID) {
+           st_bit = btp[i].val >> 3;
            for (j = 0; j < n_primitives; j++) {
                if (st_bit == primitives[j]->st_bit) {
-                   rtp[i].st_bit = rtip->rti_Solids[j]->st_bit;
+                   btp[i].val = (rtip->rti_Solids[j]->st_bit << 3) | UOP_SOLID;
                    break;
                }
            }
@@ -484,18 +486,21 @@
 }
 
 static void
-build_regions_table(cl_uint *regions_table, union tree_rpn *rtp, size_t start, 
size_t end, const long n_primitives, const size_t n_regions, const long reg_id)
+build_regions_table(cl_uint *regions_table, struct bit_tree *btp, size_t 
start, size_t end, const long n_primitives, const size_t n_regions, const long 
reg_id)
 {
     size_t i;
-    long st_bit;
+    uint uop, st_bit;
     uint rt_index;
 
     rt_index = n_regions/32 + 1;
-    for (i=start; i<start+end; i++) {
-       st_bit = rtp[i].st_bit;
-       if (st_bit >= 0L && st_bit < n_primitives) {
-           regions_table[st_bit * rt_index + (reg_id >> 5)] |= 1 << (reg_id & 
31);
-       }
+    for (i=start; i<end; i++) {
+        uop = btp[i].val & 7;
+       if (uop == UOP_SOLID) {
+            st_bit = btp[i].val >> 3;
+           if (st_bit < n_primitives) {
+               regions_table[st_bit * rt_index + (reg_id >> 5)] |= 1 << 
(reg_id & 31);
+           }
+        }
     }
 }
 
@@ -581,10 +586,10 @@
            struct region *regp;
            struct cl_bool_region *regions;
            struct clt_region *mtls;
-           union tree_rpn *rtree;
+           struct bit_tree *btree;
            cl_uint *regions_table;
            size_t sz_regions_table;
-           size_t sz_rtree_array;
+           size_t sz_btree_array;
            size_t len;
 
            regions = (struct cl_bool_region*)bu_calloc(n_regions, 
sizeof(*regions), "regions");
@@ -591,9 +596,9 @@
            mtls = (struct clt_region*)bu_calloc(n_regions, sizeof(*mtls), 
"mtls");
 
            /* Determine the size of all trees to build one array containing
-            * the rpn trees from all regions.
+            * the bit trees from all regions.
             */
-           sz_rtree_array = 0;
+           sz_btree_array = 0;
 
            i = 0;
            for (BU_LIST_FOR(regp, region, &(rtip->HeadRegion))) {
@@ -603,8 +608,8 @@
                RT_CK_REGION(regp);
 
                len = 0;
-               rt_tree_rpn(NULL, regp->reg_treetop, &len);
-               sz_rtree_array += len;
+               rt_bit_tree(NULL, regp->reg_treetop, &len);
+               sz_btree_array += len;
 
 
                VMOVE(mtls[i].color, unset);
@@ -641,7 +646,7 @@
            }
 
            sz_regions_table = n_primitives * ((n_regions/32) + 1);
-           rtree = (union tree_rpn *)bu_calloc(sz_rtree_array, sizeof(union 
tree_rpn), "region rtree array");
+           btree = (struct bit_tree *)bu_calloc(sz_btree_array, sizeof(struct 
bit_tree), "region btree array");
            regions_table = (cl_uint*)bu_calloc(sz_regions_table, 
sizeof(cl_uint), "regions_table");
 
            len = 0;
@@ -650,27 +655,26 @@
                RT_CK_REGION(regp);
 
                if (i == 0) {
-                   regions[i].rtree_offset = 0;
+                   regions[i].btree_offset = 0;
                } else {
-                   regions[i].rtree_offset = regions[i-1].rtree_offset + 
regions[i-1].reg_nrtree;
+                   regions[i].btree_offset = len;
                }
 
-               regions[i].reg_nrtree = regp->reg_nrtree;
                regions[i].reg_aircode = regp->reg_aircode;
                regions[i].reg_bit = regp->reg_bit;
                regions[i].reg_all_unions = regp->reg_all_unions;
 
-               rt_tree_rpn(rtree, regp->reg_treetop, &len);
-               rt_rtree_translate(rtip, primitives, rtree, 
regions[i].rtree_offset, regions[i].reg_nrtree, n_primitives);
-               build_regions_table(regions_table, rtree, 
regions[i].rtree_offset, regions[i].reg_nrtree, n_primitives, n_regions, i);
+               rt_bit_tree(btree, regp->reg_treetop, &len);
+               rt_btree_translate(rtip, primitives, btree, 
regions[i].btree_offset, len, n_primitives);
+               build_regions_table(regions_table, btree, 
regions[i].btree_offset, len, n_primitives, n_regions, i);
                i++;
            }
 
-           clt_db_store_regions(sz_rtree_array, rtree, n_regions, regions, 
mtls);
+           clt_db_store_regions(sz_btree_array, btree, n_regions, regions, 
mtls);
            clt_db_store_regions_table(regions_table, sz_regions_table);
            bu_free(mtls, "mtls");
            bu_free(regions, "regions");
-           bu_free(rtree, "region rtree array");
+           bu_free(btree, "region btree array");
            bu_free(regions_table, "regions_table");
        }
 
@@ -1124,8 +1128,8 @@
        RT_CK_REGION(regp);
        BU_LIST_DEQUEUE(&(regp->l));
        db_free_tree(regp->reg_treetop, &rt_uniresource);
-       bu_free(regp->reg_rtree, "region rtree");
-       regp->reg_nrtree = 0;
+       bu_free(regp->reg_btree, "region btree");
+        regp->reg_nbtree = 0;
        bu_free((void *)regp->reg_name, "region name str");
        regp->reg_name = (char *)0;
        if (regp->reg_mater.ma_shader) {
@@ -1301,20 +1305,22 @@
  * region bits have been assigned.
  */
 HIDDEN void
-rt_solid_bitfinder(const union tree_rpn *rtp, size_t rtlen, struct soltab 
**solids, size_t nsolids, struct region *regp)
+rt_solid_bitfinder(const struct bit_tree *btp, size_t btlen, struct soltab 
**solids, size_t nsolids, struct region *regp)
 {
     struct soltab *stp;
-    long st_bit;
+    uint st_bit;
     size_t i;
 
     RT_CK_REGION(regp);
-    for (i=0; i<rtlen; i++) {
-       st_bit = rtp[i].st_bit;
-       if (st_bit >= 0L && st_bit < (long)nsolids) {
-           stp = solids[st_bit];
-           RT_CK_SOLTAB(stp);
-           bu_ptbl_ins(&stp->st_regions, (long *)regp);
-       }
+    for (i=0; i<btlen; i++) {
+        if ((btp[i].val & 7) == UOP_SOLID) {
+            st_bit = btp[i].val >> 3;
+           if (st_bit < nsolids) {
+               stp = solids[st_bit];
+               RT_CK_SOLTAB(stp);
+               bu_ptbl_ins(&stp->st_regions, (long *)regp);
+           }
+        }
     }
 }
 
@@ -1959,7 +1965,7 @@
                VMINMAX(rtip->mdl_min, rtip->mdl_max, region_min);
                VMINMAX(rtip->mdl_min, rtip->mdl_max, region_max);
            }
-           rt_solid_bitfinder(rp->reg_rtree, rp->reg_nrtree, rtip->rti_Solids, 
rtip->nsolids, rp);
+           rt_solid_bitfinder(rp->reg_btree, rp->reg_nbtree, rtip->rti_Solids, 
rtip->nsolids, rp);
        }
        bitno++;
     }

Modified: brlcad/branches/opencl/src/librt/primitives/bool.cl
===================================================================
--- brlcad/branches/opencl/src/librt/primitives/bool.cl 2017-08-10 21:40:14 UTC 
(rev 70073)
+++ brlcad/branches/opencl/src/librt/primitives/bool.cl 2017-08-11 20:37:09 UTC 
(rev 70074)
@@ -2,17 +2,21 @@
 
 #if !RT_SINGLE_HIT
 
-#define BOOL_STACKSIZE 64
+#define BOOL_STACKSIZE 128
 
 /**
- * Flattened RPN version of the infix union tree.
+ * Flattened version of the infix union tree.
  */
-#define UOP_NOP                -1
-#define UOP_UNION      -2
-#define UOP_INTERSECT  -3
-#define UOP_SUBTRACT   -4
-#define UOP_XOR                -5
+#define UOP_UNION        1         /* Binary: L union R */
+#define UOP_INTERSECT    2         /* Binary: L intersect R */
+#define UOP_SUBTRACT     3         /* Binary: L subtract R */
+#define UOP_XOR          4         /* Binary: L xor R, not both*/
+#define UOP_NOT          5         /* Unary:  not L */
+#define UOP_GUARD        6         /* Unary:  not L, or else! */
+#define UOP_XNOP         7         /* Unary:  L, mark region */
 
+#define UOP_SOLID        0         /* Leaf:  tr_stp -> solid */
+
 /* Boolean values.  Not easy to change, but defined symbolically */
 #define BOOL_FALSE     0
 #define BOOL_TRUE      1
@@ -529,123 +533,163 @@
     }
 }
 
-/**
- * Produce representations of all postfix bool trees in the regions.
- * Debug function - use when running opencl on the CPU
- */
-void
-pr_all_rtrees(const int total_regions, global struct bool_region *bregions, 
global union tree_rpn *rtree)
-{
-    for (uint j = 0; j < total_regions; j++) {
-        printf("\npostfix: ");
-        for (uint i=bregions[j].rtree_offset; i< bregions[j].rtree_offset + 
bregions[j].reg_nrtree; i++) {
-           switch (rtree[i].uop) {
-               case UOP_NOP:
-               printf("NOP");
-               break;
-
-               case UOP_UNION:
-               printf("U");
-               break;
-               case UOP_INTERSECT:
-               printf("+");
-               break;
-               case UOP_SUBTRACT:
-               printf("-");
-               break;
-               case UOP_XOR:
-               printf("XOR");
-               break;
-
-               default:
-               printf("%ld", rtree[i].st_bit);
-               break;
-           }
-           if (i != bregions[j].rtree_offset + bregions[j].reg_nrtree-1)
-               printf(" ");
-        }
-        printf("\n");
-    }
-    printf("\n\n");
-}
-
 int
 bool_eval(global struct partition *partitions, global uint *ipartition, 
RESULT_TYPE segs,
         global uint *h, global uint *segs_bv, const uint bv_index, uint 
offset, size_t id,
-        global struct bool_region *bregions, global union tree_rpn *rtree, 
const uint region_index)
+        global struct bool_region *bregions, global struct tree_bit *btree, 
const uint region_index)
 {
-    uchar stack[BOOL_STACKSIZE];
+    int sp[BOOL_STACKSIZE];
+    int ret;
+    int stackend;
+    uint uop;
+    int idx;
 
-    size_t stackend;
-    uchar a, b, ret;
-
-    stack[0] = 0;
     stackend = 0;
+    sp[stackend++] = INT_MAX;
+    idx = bregions[region_index].btree_offset;
+    for(;;) {
+        for (;;) {
+            uop = btree[idx].val & 7;
 
-    for (uint i = bregions[region_index].rtree_offset; i < 
bregions[region_index].rtree_offset + bregions[region_index].reg_nrtree; i++) {
-       if (stackend >= BOOL_STACKSIZE)
-           return -1;
+            switch (uop) {
+                case UOP_SOLID:
+                    {
+                        /* Tree Leaf */
+                        const uint st_bit = btree[idx].val >> 3;
+                        global struct partition *pp;
+                        RESULT_TYPE segp;
+                        ret = 0;
 
-        switch (rtree[i].uop) {
-            case UOP_NOP:
-            stack[stackend++] = 0;
-            break;
+                        pp = &partitions[offset];
+                        /* Iterate over segments of partition */
+                        for (uint i = 0; i < bv_index; i++) {
+                            uint mask = segs_bv[offset * bv_index + i];
+                            while (mask != 0) {
+                                uint lz = clz(mask);
+                                uint k = h[id] + (31 - lz);
+                                if (isset(segs_bv, offset * bv_index, k - 
h[id]) != 0) {
+                                    segp = segs+k;
 
-            case UOP_UNION:
-            b = stack[--stackend];
-            a = stack[--stackend];
-            stack[stackend++] = (a || b);
+                                    if (segp->seg_sti == st_bit) {
+                                        ret = 1;
+                                        break;
+                                    }
+                                }
+                                // clear bit in mask
+                                mask &= ~(1 << (31-lz));
+                            }
+                            if (ret) break;
+                        }
+                    }
+                    break;
+
+                case UOP_UNION:
+                case UOP_INTERSECT:
+                case UOP_SUBTRACT:
+                case UOP_XOR:
+                    sp[stackend++] = idx;
+                    idx++;
+                    continue;
+                default:
+                    /* bad sp op */
+                    return BOOL_TRUE;       /* Screw up output */
+            }
             break;
-            case UOP_INTERSECT:
-            b = stack[--stackend];
-            a = stack[--stackend];
-            stack[stackend++] = (a && b);
-            break;
-            case UOP_SUBTRACT:
-            b = stack[--stackend];
-            a = stack[--stackend];
-            stack[stackend++] = (a && !b);
-            break;
-            case UOP_XOR:
-            b = stack[--stackend];
-            a = stack[--stackend];
-            stack[stackend++] = (a ^ b);
-            break;
+        }
 
-            default:
-           {
-               const long st_bit = rtree[i].st_bit;
-               global struct partition *pp;
-               RESULT_TYPE segp;
-               ret = 0;
+        for (;;) {
+            idx = sp[--stackend];
 
-               pp = &partitions[offset];
-               //iterate over segments of partition
-               for (uint i = 0; i < bv_index; i++) {
-                   uint mask = segs_bv[offset * bv_index + i];
-                   while (mask != 0) {
-                       uint lz = clz(mask);
-                       uint k = h[id] + (31 - lz);
-                       if (isset(segs_bv, offset * bv_index, k - h[id]) != 0) {
-                           RESULT_TYPE segp = segs+k;
+            switch (idx) {
+                case INT_MAX:
+                    return ret;                /* top of tree again */
+                case -1:
+                    /* Special operation for subtraction */
+                   ret = !ret;
+                   continue;
+                case -2:
+                    /*
+                    * Special operation for XOR.  lhs was true.  If rhs
+                    * subtree was true, an overlap condition exists (both
+                    * sides of the XOR are BOOL_TRUE).  Return error
+                    * condition.  If subtree is false, then return BOOL_TRUE
+                    * (from lhs).
+                    */
+                   if (ret) {
+                       /* stacked temp val: rhs */
+                       return -1;      /* GUARD error */
+                   }
+                   ret = BOOL_TRUE;
+                   stackend--;                 /* pop temp val */
+                   continue;
+                case -3:
+                    /*
+                    * Special NOP for XOR.  lhs was false.  If rhs is true,
+                    * take note of its regionp.
+                    */
+                   stackend--;                 /* pop temp val */
+                   continue;
+                default:
+                    break;
+            }
 
-                           if (segp->seg_sti == st_bit) {
-                               ret = 1;
-                               break;
-                           }
-                       }
-                       // clear bit in mask
-                       mask &= ~(1 << (31 - lz));
+            uop = btree[idx].val & 7;
+
+           /*
+            * Here, each operation will look at the operation just completed
+            * (the left branch of the tree generally), and rewrite the top of
+            * the stack and/or branch accordingly.
+            */
+            switch (uop) {
+                case UOP_SOLID:
+                    /* bool_eval:  pop SOLID? */
+                    return BOOL_TRUE;      /* screw up output */
+                case UOP_UNION:
+                    if (ret) continue;     /* BOOL_TRUE, we are done */
+                    /* lhs was false, rewrite as rhs tree */
+                    idx = btree[idx].val >> 3;
+                    break;
+               case UOP_INTERSECT:
+                   if (!ret) {
+                       ret = BOOL_FALSE;
+                       continue;
                    }
-                    if (ret) break;
-               }
-               stack[stackend++] = ret;
-               break;
+                   /* lhs was true, rewrite as rhs tree */
+                    idx = btree[idx].val >> 3;
+                   break;
+                case UOP_SUBTRACT:
+                   if (!ret) continue; /* BOOL_FALSE, we are done */
+                   /* lhs was true, rewrite as NOT of rhs tree */
+                   /* We introduce the special NOT operator here */
+                    sp[stackend++] = -1;
+                    idx = btree[idx].val >> 3;
+                   break;
+               case UOP_XOR:
+                   if (ret) {
+                       /* lhs was true, rhs better not be, or we have an
+                        * overlap condition.  Rewrite as guard node followed
+                        * by rhs.
+                        */
+                        idx = btree[idx].val >> 3;
+                       sp[stackend++] = idx;           /* temp val for guard 
node */
+                       sp[stackend++] = -2;
+                   } else {
+                       /* lhs was false, rewrite as xnop node and result of
+                        * rhs.
+                        */
+                        idx = btree[idx].val >> 3;
+                       sp[stackend++] = idx;           /* temp val for xnop */
+                       sp[stackend++] = -3;
+                   }
+                   break;
+               default:
+                   /* bool_eval:  bad pop op */
+                   return BOOL_TRUE;       /* screw up output */
             }
-        }
+           break;
+       }
     }
-
-    return stack[0];
+    /* NOTREACHED */
 }
 
 /**
@@ -812,7 +856,7 @@
 __kernel void
 rt_boolfinal(global struct partition *partitions, global uint *ipartition, 
RESULT_TYPE segs,
         global uint *h, global uint *segs_bv, const int max_depth,
-        global struct bool_region *bregions, const uint total_regions, global 
union tree_rpn *rtree,
+        global struct bool_region *bregions, const uint total_regions, global 
struct tree_bit *rtree,
         global uint *regiontable, const int cur_pixel, const int last_pixel,
         global uint *regions_table, const uint regions_table_size, global uint 
*head_partition)
 {

Modified: brlcad/branches/opencl/src/librt/primitives/common.cl
===================================================================
--- brlcad/branches/opencl/src/librt/primitives/common.cl       2017-08-10 
21:40:14 UTC (rev 70073)
+++ brlcad/branches/opencl/src/librt/primitives/common.cl       2017-08-11 
20:37:09 UTC (rev 70074)
@@ -74,14 +74,23 @@
     char outflip;              /* flip outhit->hit_normal */
 };
 
-union tree_rpn {
-    long uop;
-    long st_bit;
+/**
+ * bit expr tree representation
+ *
+ * node:
+ *      uint uop : 3
+ *      uint right_child : 29
+ *
+ * leaf:
+ *      uint uop : 3
+ *      uint st_bit : 29
+ */
+struct tree_bit {
+    uint val;
 };
 
 struct bool_region {
-    uint rtree_offset;          /* index to the start of the rpn tree */
-    uint reg_nrtree;            /* number of elements in rtree */
+    uint btree_offset;          /* index to the start of the bit tree */
     int reg_aircode;            /* Region ID AIR code */
     int reg_bit;                /* constant index into Regions[] */
     short reg_all_unions;       /* 1=boolean tree is all unions */

Modified: brlcad/branches/opencl/src/librt/primitives/primitive_util.c
===================================================================
--- brlcad/branches/opencl/src/librt/primitives/primitive_util.c        
2017-08-10 21:40:14 UTC (rev 70073)
+++ brlcad/branches/opencl/src/librt/primitives/primitive_util.c        
2017-08-11 20:37:09 UTC (rev 70074)
@@ -767,7 +767,7 @@
 }
 
 void
-clt_db_store_regions(size_t sz_tree_rpn, union tree_rpn *rtp, size_t nregions, 
struct cl_bool_region *regions, struct clt_region *mtls)
+clt_db_store_regions(size_t sz_btree_array, struct bit_tree *btp, size_t 
nregions, struct cl_bool_region *regions, struct clt_region *mtls)
 {
     cl_int error;
 
@@ -776,7 +776,7 @@
        clt_db_bool_regions = clCreateBuffer(clt_context, 
CL_MEM_READ_ONLY|CL_MEM_HOST_WRITE_ONLY|CL_MEM_COPY_HOST_PTR, sizeof(struct 
cl_bool_region)*nregions, regions, &error);
        if (error != CL_SUCCESS) bu_bomb("failed to create OpenCL boolean 
regions buffer");
 
-       clt_db_rtree = clCreateBuffer(clt_context, 
CL_MEM_READ_ONLY|CL_MEM_HOST_WRITE_ONLY|CL_MEM_COPY_HOST_PTR, sizeof(union 
cl_tree_rpn)*sz_tree_rpn, rtp, &error);
+       clt_db_rtree = clCreateBuffer(clt_context, 
CL_MEM_READ_ONLY|CL_MEM_HOST_WRITE_ONLY|CL_MEM_COPY_HOST_PTR, sizeof(struct 
cl_tree_bit)*sz_btree_array, btp, &error);
        if (error != CL_SUCCESS) bu_bomb("failed to create OpenCL boolean trees 
buffer");
 
        clt_db_regions = clCreateBuffer(clt_context, 
CL_MEM_READ_ONLY|CL_MEM_HOST_WRITE_ONLY|CL_MEM_COPY_HOST_PTR, sizeof(struct 
clt_region)*nregions, mtls, &error);

Modified: brlcad/branches/opencl/src/librt/tree.c
===================================================================
--- brlcad/branches/opencl/src/librt/tree.c     2017-08-10 21:40:14 UTC (rev 
70073)
+++ brlcad/branches/opencl/src/librt/tree.c     2017-08-11 20:37:09 UTC (rev 
70074)
@@ -1106,49 +1106,45 @@
 
 
 void
-rt_tree_rpn(union tree_rpn *rtp, const union tree *tp, size_t *len)
+rt_bit_tree(struct bit_tree *btp, const union tree *tp, size_t *len)
 {
+    int idx;
+    uint st_bit, uop, rchild;
+
     if (tp == TREE_NULL)
-       return;
+        return;
 
+    idx = (*len)++;
     switch (tp->tr_op) {
-       case OP_NOP:
-           rtp[*len].uop = UOP_NOP;
-           ++*len;
-           break;
-       case OP_SOLID:
-           if (rtp) rtp[*len].st_bit = tp->tr_a.tu_stp->st_bit;
-           ++*len;
-           break;
-       case OP_SUBTRACT:
-           rt_tree_rpn(rtp, tp->tr_b.tb_left, len);
-           rt_tree_rpn(rtp, tp->tr_b.tb_right, len);
-           if (rtp) rtp[*len].uop = UOP_SUBTRACT;
-           ++*len;
-           break;
-       case OP_UNION:
-           rt_tree_rpn(rtp, tp->tr_b.tb_left, len);
-           rt_tree_rpn(rtp, tp->tr_b.tb_right, len);
-           if (rtp) rtp[*len].uop = UOP_UNION;
-           ++*len;
-           break;
-       case OP_INTERSECT:
-           rt_tree_rpn(rtp, tp->tr_b.tb_left, len);
-           rt_tree_rpn(rtp, tp->tr_b.tb_right, len);
-           if (rtp) rtp[*len].uop = UOP_INTERSECT;
-           ++*len;
-           break;
-       case OP_XOR:
-           rt_tree_rpn(rtp, tp->tr_b.tb_left, len);
-           rt_tree_rpn(rtp, tp->tr_b.tb_right, len);
-           if (rtp) rtp[*len].uop = UOP_XOR;
-           ++*len;
-           break;
-       default:
-           bu_log("rt_tree_rpn:  bad op [%d]\n", tp->tr_op);
-           exit(1);
-           break;
+        case OP_SOLID:
+            /* Tree Leaf */
+            st_bit = tp->tr_a.tu_stp->st_bit;
+            if (btp) btp[idx].val = (st_bit << 3) | UOP_SOLID;
+            return;
+        case OP_SUBTRACT:
+            uop = UOP_SUBTRACT;
+            break;
+        case OP_UNION:
+            uop = UOP_UNION;
+            break;
+        case OP_INTERSECT:
+            uop = UOP_INTERSECT;
+            break;
+        case OP_XOR:
+            uop = UOP_XOR;
+            break;
+        default:
+            bu_log("rt_bit_tree: bad op[%d]\n", tp->tr_op);
+            exit(1);
+            break;
     }
+
+    rt_bit_tree(btp, tp->tr_b.tb_left, len);
+
+    rchild = *len;
+    if (btp) btp[idx].val = (rchild << 3) | uop;
+
+    rt_bit_tree(btp, tp->tr_b.tb_right, len);
 }
 
 

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
BRL-CAD Source Commits mailing list
brlcad-commits@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/brlcad-commits

Reply via email to