<commit_before>// ======================================================================== //
// Copyright 2009-2017 Intel Corporation                                    //
//                                                                          //
// Licensed under the Apache License, Version 2.0 (the "License");          //
// you may not use this file except in compliance with the License.         //
// You may obtain a copy of the License at                                  //
//                                                                          //
//     http://www.apache.org/licenses/LICENSE-2.0                           //
//                                                                          //
// Unless required by applicable law or agreed to in writing, software      //
// distributed under the License is distributed on an "AS IS" BASIS,        //
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
// See the License for the specific language governing permissions and      //
// limitations under the License.                                           //
// ======================================================================== //

#pragma once

#include "priminfo.h"
#include "../geometry/bezier1v.h"

#include "../../common/algorithms/parallel_reduce.h"
#include "../../common/algorithms/parallel_partition.h"

namespace embree
{
  namespace isa
  { 
    /*! mapping into bins */
    template<size_t BINS>
      struct BinMapping
      {
      public:
        __forceinline BinMapping() {}
        
        /*! calculates the mapping */
        __forceinline BinMapping(size_t N, const BBox3fa& centBounds) 
        {
          num = min(BINS,size_t(4.0f + 0.05f*N));
          assert(num >= 1);
          const vfloat4 eps = 1E-34f;
          const vfloat4 diag = max(eps, (vfloat4) centBounds.size());
          scale = select(diag > eps,vfloat4(0.99f*num)/diag,vfloat4(0.0f));
          ofs  = (vfloat4) centBounds.lower;
        }

        /*! calculates the mapping */
        __forceinline BinMapping(const BBox3fa& centBounds) 
        {
          num = BINS; 
          const vfloat4 eps = 1E-34f;
          const vfloat4 diag = max(eps, (vfloat4) centBounds.size());
          scale = select(diag > eps,vfloat4(0.99f*num)/diag,vfloat4(0.0f));
          ofs  = (vfloat4) centBounds.lower;
        }

        /*! calculates the mapping */
        template<typename PrimInfo>
        __forceinline BinMapping(const PrimInfo& pinfo) 
        {
          const vfloat4 eps = 1E-34f;
          num = min(BINS,size_t(4.0f + 0.05f*pinfo.size()));
          const vfloat4 diag = max(eps,(vfloat4) pinfo.centBounds.size());
          scale = select(diag > eps,vfloat4(0.99f*num)/diag,vfloat4(0.0f));
          ofs  = (vfloat4) pinfo.centBounds.lower;
        }

        /*! returns number of bins */
        __forceinline size_t size() const { return num; }
        
        /*! slower but safe binning */
        __forceinline Vec3ia bin(const Vec3fa& p) const 
        {
          const vint4 i = floori((vfloat4(p)-ofs)*scale);
#if 1
          assert(i[0] >= 0 && (size_t)i[0] < num); 
          assert(i[1] >= 0 && (size_t)i[1] < num);
          assert(i[2] >= 0 && (size_t)i[2] < num);
          return Vec3ia(i);
#else
          return Vec3ia(clamp(i,vint4(0),vint4(num-1)));
#endif
        }

        /*! faster but unsafe binning */
        __forceinline Vec3ia bin_unsafe(const Vec3fa& p) const {
          return Vec3ia(floori((vfloat4(p)-ofs)*scale));
        }

        /*! faster but unsafe binning */
        template<typename PrimRef>
        __forceinline Vec3ia bin_unsafe(const PrimRef& p) const {
          return bin_unsafe(p.binCenter());
        }

        /*! faster but unsafe binning */
        template<typename PrimRef, typename BinBoundsAndCenter>
        __forceinline Vec3ia bin_unsafe(const PrimRef& p, const BinBoundsAndCenter& binBoundsAndCenter) const {
          return bin_unsafe(binBoundsAndCenter.binCenter(p));
        }

        template<typename PrimRef>
        __forceinline bool bin_unsafe(const PrimRef& ref,
                                      const vint4&   vSplitPos,
                                      const vbool4&  splitDimMask) const // FIXME: rename to isLeft
        {
          return any(((vint4)bin_unsafe(center2(ref.bounds())) < vSplitPos) & splitDimMask);
        }

        /*! calculates left spatial position of bin */
        __forceinline float pos(const size_t bin, const size_t dim) const {
          return madd(float(bin),1.0f / scale[dim],ofs[dim]);
        }

        /*! returns true if the mapping is invalid in some dimension */
        __forceinline bool invalid(const size_t dim) const {
          return scale[dim] == 0.0f;
        }
        
        /*! stream output */
        friend std::ostream& operator<<(std::ostream& cout, const BinMapping& mapping) {
          return cout << "BinMapping { num = " << mapping.num << ", ofs = " << mapping.ofs << ", scale = " << mapping.scale << "}";
        }
        
      public:
        size_t num;
        vfloat4 ofs,scale;        //!< linear function that maps to bin ID
      };
    
    /*! stores all information to perform some split */
    template<size_t BINS>
      struct BinSplit
      {
        enum
        {
          SPLIT_OBJECT   =  0,
          SPLIT_TEMPORAL = -1,
          SPLIT_FALLBACK = -2,
        };

        /*! construct an invalid split by default */
        __forceinline BinSplit()
          : sah(inf), dim(-1), pos(0), data(0) {}

        __forceinline BinSplit(float sah, unsigned data, int dim = 0, float fpos = 0)
          : sah(sah), dim(dim), fpos(fpos), data(data) {}
        
        /*! constructs specified split */
        __forceinline BinSplit(float sah, int dim, int pos, const BinMapping<BINS>& mapping)
          : sah(sah), dim(dim), pos(pos), data(0), mapping(mapping) {}
        
        /*! tests if this split is valid */
        __forceinline bool valid() const { return dim != -1; }
        
        /*! calculates surface area heuristic for performing the split */
        __forceinline float splitSAH() const { return sah; }
        
        /*! stream output */
        friend std::ostream& operator<<(std::ostream& cout, const BinSplit& split) {
          return cout << "BinSplit { sah = " << split.sah << ", dim = " << split.dim << ", pos = " << split.pos << "}";
        }
        
      public:
        float sah;                //!< SAH cost of the split
        int dim;                  //!< split dimension
        union { int pos; float fpos; };                  //!< bin index for splitting
        unsigned int data;        //!< extra optional split data
        BinMapping<BINS> mapping; //!< mapping into bins
      };<commit_msg>cleanups to heuristic_binning.h<commit_after>// ======================================================================== //
// Copyright 2009-2017 Intel Corporation                                    //
//                                                                          //
// Licensed under the Apache License, Version 2.0 (the "License");          //
// you may not use this file except in compliance with the License.         //
// You may obtain a copy of the License at                                  //
//                                                                          //
//     http://www.apache.org/licenses/LICENSE-2.0                           //
//                                                                          //
// Unless required by applicable law or agreed to in writing, software      //
// distributed under the License is distributed on an "AS IS" BASIS,        //
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
// See the License for the specific language governing permissions and      //
// limitations under the License.                                           //
// ======================================================================== //

#pragma once

#include "priminfo.h"
#include "../geometry/bezier1v.h"

#include "../../common/algorithms/parallel_reduce.h"
#include "../../common/algorithms/parallel_partition.h"

namespace embree
{
  namespace isa
  { 
    /*! mapping into bins */
    template<size_t BINS>
      struct BinMapping
      {
      public:
        __forceinline BinMapping() {}
        
        /*! calculates the mapping */
        __forceinline BinMapping(size_t N, const BBox3fa& centBounds) 
        {
          num = min(BINS,size_t(4.0f + 0.05f*N));
          assert(num >= 1);
          const vfloat4 eps = 1E-34f;
          const vfloat4 diag = max(eps, (vfloat4) centBounds.size());
          scale = select(diag > eps,vfloat4(0.99f*num)/diag,vfloat4(0.0f));
          ofs  = (vfloat4) centBounds.lower;
        }

        /*! calculates the mapping */
        __forceinline BinMapping(const BBox3fa& centBounds) 
        {
          num = BINS; 
          const vfloat4 eps = 1E-34f;
          const vfloat4 diag = max(eps, (vfloat4) centBounds.size());
          scale = select(diag > eps,vfloat4(0.99f*num)/diag,vfloat4(0.0f));
          ofs  = (vfloat4) centBounds.lower;
        }

        /*! calculates the mapping */
        template<typename PrimInfo>
        __forceinline BinMapping(const PrimInfo& pinfo) 
        {
          const vfloat4 eps = 1E-34f;
          num = min(BINS,size_t(4.0f + 0.05f*pinfo.size()));
          const vfloat4 diag = max(eps,(vfloat4) pinfo.centBounds.size());
          scale = select(diag > eps,vfloat4(0.99f*num)/diag,vfloat4(0.0f));
          ofs  = (vfloat4) pinfo.centBounds.lower;
        }

        /*! returns number of bins */
        __forceinline size_t size() const { return num; }
        
        /*! slower but safe binning */
        __forceinline Vec3ia bin(const Vec3fa& p) const 
        {
          const vint4 i = floori((vfloat4(p)-ofs)*scale);
#if 1
          assert(i[0] >= 0 && (size_t)i[0] < num); 
          assert(i[1] >= 0 && (size_t)i[1] < num);
          assert(i[2] >= 0 && (size_t)i[2] < num);
          return Vec3ia(i);
#else
          return Vec3ia(clamp(i,vint4(0),vint4(num-1)));
#endif
        }

        /*! faster but unsafe binning */
        __forceinline Vec3ia bin_unsafe(const Vec3fa& p) const {
          return Vec3ia(floori((vfloat4(p)-ofs)*scale));
        }

        /*! faster but unsafe binning */
        template<typename PrimRef>
        __forceinline Vec3ia bin_unsafe(const PrimRef& p) const {
          return bin_unsafe(p.binCenter());
        }

        /*! faster but unsafe binning */
        template<typename PrimRef, typename BinBoundsAndCenter>
        __forceinline Vec3ia bin_unsafe(const PrimRef& p, const BinBoundsAndCenter& binBoundsAndCenter) const {
          return bin_unsafe(binBoundsAndCenter.binCenter(p));
        }

        template<typename PrimRef>
        __forceinline bool bin_unsafe(const PrimRef& ref,
                                      const vint4&   vSplitPos,
                                      const vbool4&  splitDimMask) const // FIXME: rename to isLeft
        {
          return any(((vint4)bin_unsafe(center2(ref.bounds())) < vSplitPos) & splitDimMask);
        }

        /*! calculates left spatial position of bin */
        __forceinline float pos(const size_t bin, const size_t dim) const {
          return madd(float(bin),1.0f / scale[dim],ofs[dim]);
        }

        /*! returns true if the mapping is invalid in some dimension */
        __forceinline bool invalid(const size_t dim) const {
          return scale[dim] == 0.0f;
        }
        
        /*! stream output */
        friend std::ostream& operator<<(std::ostream& cout, const BinMapping& mapping) {
          return cout << "BinMapping { num = " << mapping.num << ", ofs = " << mapping.ofs << ", scale = " << mapping.scale << "}";
        }
        
      public:
        size_t num;
        vfloat4 ofs,scale;        //!< linear function that maps to bin ID
      };
    
    /*! stores all information to perform some split */
    template<size_t BINS>
      struct BinSplit
      {
        enum
        {
          SPLIT_OBJECT   = 0,
          SPLIT_TEMPORAL = 1,
          SPLIT_FALLBACK = 2,
        };

        /*! construct an invalid split by default */
        __forceinline BinSplit()
          : sah(inf), dim(-1), pos(0), data(0) {}

        __forceinline BinSplit(float sah, unsigned data, int dim = 0, float fpos = 0)
          : sah(sah), dim(dim), fpos(fpos), data(data) {}
        
        /*! constructs specified split */
        __forceinline BinSplit(float sah, int dim, int pos, const BinMapping<BINS>& mapping)
          : sah(sah), dim(dim), pos(pos), data(0), mapping(mapping) {}
        
        /*! tests if this split is valid */
        __forceinline bool valid() const { return dim != -1; }
        
        /*! calculates surface area heuristic for performing the split */
        __forceinline float splitSAH() const { return sah; }
        
        /*! stream output */
        friend std::ostream& operator<<(std::ostream& cout, const BinSplit& split) {
          return cout << "BinSplit { sah = " << split.sah << ", dim = " << split.dim << ", pos = " << split.pos << "}";
        }
        
      public:
        float sah;                //!< SAH cost of the split
        int dim;                  //!< split dimension
        union { int pos; float fpos; };                  //!< bin index for splitting
        unsigned int data;        //!< extra optional split data
        BinMapping<BINS> mapping; //!< mapping into bins
      };
{'fraction_non_alphanumeric': 0.1366272667205051, 'fraction_numerical': 0.01659202701710594, 'mean_word_length': 1.7184194771502694, 'pattern_counts': {'":': 0, '<': 103, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 30, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1349259', 'n_tokens_mistral': 3887, 'n_tokens_neox': 3705, 'n_words': 1018}