<commit_before>#ifdef NG_PYTHON

#include <../general/ngpython.hpp>
#include <csg.hpp>

using namespace netgen;

namespace netgen
{
  extern shared_ptr<NetgenGeometry> ng_geometry;
}

inline void NOOP_Deleter(void *) { ; }

// a shadow solid tree using shared pointers.

class SPSolid
{
  shared_ptr<SPSolid> s1, s2;
  Solid * solid;
  int bc = -1;
  string bcname = "";
  double maxh = -1;
  string material;
  bool owner;
  double red, green, blue;
  bool transp = false;
public:
  enum optyp { TERM, SECTION, UNION, SUB };

  SPSolid (Solid * as) : solid(as), owner(true), op(TERM) { ; }
  ~SPSolid ()
  {
    ; // if (owner) delete solid;
  }
  SPSolid (optyp aop, shared_ptr<SPSolid> as1, shared_ptr<SPSolid> as2)
    : s1(as1), s2(as2), owner(true), op(aop)
  {
    if (aop == UNION)
      solid = new Solid (Solid::UNION, s1->GetSolid(), s2->GetSolid());
    else if (aop == SECTION)
      solid = new Solid (Solid::SECTION, s1->GetSolid(), s2->GetSolid());
    else if (aop == SUB)
      solid = new Solid (Solid::SUB, s1->GetSolid()); // , s2->GetSolid());
  }

  Solid * GetSolid() { return solid; }
  const Solid * GetSolid() const { return solid; }

  void GiveUpOwner()
  {
    owner = false;
    if (s1) s1 -> GiveUpOwner();
    if (s2) s2 -> GiveUpOwner();
  }

  void AddSurfaces(CSGeometry & geom)
  {
    if (op == TERM)
      geom.AddSurfaces (solid->GetPrimitive());
    if (s1) s1 -> AddSurfaces (geom);
    if (s2) s2 -> AddSurfaces (geom);
  }

  void SetMaterial (string mat)  { material = mat; }

  string GetMaterial ()
  {
    if (!material.empty()) return material;
    if (s1)
      {
        string s1mat = s1->GetMaterial();
        if (!s1mat.empty()) return s1mat;
      }
    if (s2)
      {
        string s2mat = s2->GetMaterial();
        if (!s2mat.empty()) return s2mat;
      }
    return material;
  }

  void SetBC(int abc)
  {
    if (bc == -1)
      {
        bc = abc;
        if (s1) s1 -> SetBC(bc);
        if (s2) s2 -> SetBC(bc);
        if (op == TERM)
          {
            Primitive * prim = solid -> GetPrimitive();
            for (int i = 0; i < prim->GetNSurfaces(); i++)
              prim->GetSurface(i).SetBCProperty (abc);
            // cout << "set " << prim->GetNSurfaces() << " surfaces to bc " << bc << endl;
          }
      }
  }

  void SetBCName(string name)
  {
    if (bcname == "")
      {
        bcname = name;
        if (s1) s1 -> SetBCName(name);
        if (s2) s2 -> SetBCName(name);
        if (op == TERM)
          {
            Primitive * prim = solid -> GetPrimitive();
            for (int i = 0; i < prim->GetNSurfaces(); i++)
              prim->GetSurface(i).SetBCName (name);
            // cout << "set " << prim->GetNSurfaces() << " surfaces to bc " << bc << endl;
          }
      }
  }

  void SetMaxH(double amaxh)
  {
    if (maxh == -1)
      {
        maxh = amaxh;
        if (s1) s1 -> SetMaxH(maxh);
        if (s2) s2 -> SetMaxH(maxh);
        if (op == TERM)
          {
            Primitive * prim = solid -> GetPrimitive();
            for (int i = 0; i < prim->GetNSurfaces(); i++)
              prim->GetSurface(i).SetMaxH (maxh);
          }
      }
  }

  void SetColor(double ared, double agreen, double ablue)
  {
    red = ared;
    green = agreen;
    blue = ablue;
  }

  double GetRed() const { return red; }
  double GetGreen() const { return green; }
  double GetBlue() const { return blue; }

  void SetTransparent() { transp = true; }
  bool IsTransparent() { return transp; }

private:
  optyp op;
};

inline ostream & operator<< (ostream & ost, const SPSolid & sol)
{
  ost << *sol.GetSolid();
  return ost;
}

namespace netgen
{
  extern CSGeometry * ParseCSG (istream & istr);
}

DLL_HEADER void ExportCSG()
{
  ModuleScope module("csg");

  bp::class_<Point<2>> ("Point2d", bp::init<double,double>())
    .def ("__str__", &ToString<Point<2>>)
    .def(bp::self-bp::self)
    .def(bp::self+Vec<2>())
    .def(bp::self-Vec<2>())
    ;

  bp::class_<Point<3>> ("Point3d", bp::init<double,double,double>())
    .def ("__str__", &ToString<Point<3>>)
    .def(bp::self-bp::self)
    .def(bp::self+Vec<3>())
    .def(bp::self-Vec<3>())
    ;

  bp::def ("Pnt", FunctionPointer
           ([](double x, double y, double z) { return Point<3>(x,y,z); }));
  bp::def ("Pnt", FunctionPointer
           ([](double x, double y) { return Point<2>(x,y); }));

  bp::class_<Vec<2>> ("Vec2d", bp::init<double,double>())
    .def ("__str__", &ToString<Vec<3>>)
    .def(bp::self+bp::self)
    .def(bp::self-bp::self)
    .def(-bp::self)
    .def(double()*bp::self)
    .def("Norm", &Vec<2>::Length)
    ;

  bp::class_<Vec<3>> ("Vec3d", bp::init<double,double,double>())
    .def ("__str__", &ToString<Vec<3>>)
    .def(bp::self+bp::self)
    .def(bp::self-bp::self)
    .def(-bp::self)
    .def(double()*bp::self)
    .def("Norm", &Vec<3>::Length)
    ;

  bp::def ("Vec", FunctionPointer
           ([] (double x, double y, double z) { return Vec<3>(x,y,z); }));
  bp::def ("Vec", FunctionPointer
           ([] (double x, double y) { return Vec<2>(x,y); }));

  bp::class_<SPSolid, shared_ptr<SPSolid>, boost::noncopyable> ("Solid", bp::no_init)
    .def ("__str__", &ToString<SPSolid>)
    .def ("__add__", FunctionPointer( [] ( shared_ptr<SPSolid> self, shared_ptr<SPSolid> other) { return make_shared<SPSolid> (SPSolid::UNION, self, other); }))
    .def ("__mul__", FunctionPointer( [] ( shared_ptr<SPSolid> self, shared_ptr<SPSolid> other) { return make_shared<SPSolid> (SPSolid::SECTION, self, other); }))
    .def ("__sub__", FunctionPointer
          ([] ( shared_ptr<SPSolid> self, shared_ptr<SPSolid> other)
           { return make_shared<SPSolid> (SPSolid::SECTION, self,
                                          make_shared<SPSolid> (SPSolid::SUB, other, nullptr)); }))

    .def ("bc", FunctionPointer([](shared_ptr<SPSolid> & self, int nr) -> shared_ptr<SPSolid>
                                { self->SetBC(nr); return self; }))
    .def ("bc", FunctionPointer([](shared_ptr<SPSolid> & self, string name) -> shared_ptr<SPSolid>
                                { self->SetBCName(name); return self; }))
    .def ("maxh", FunctionPointer([](shared_ptr<SPSolid> & self, double maxh) -> shared_ptr<SPSolid>
                                { self->SetMaxH(maxh); return self; }))
    .def ("mat", FunctionPointer([](shared_ptr<SPSolid> & self, string mat) -> shared_ptr<SPSolid>
                                 { self->SetMaterial(mat); return self; }))
    .def ("mat", &SPSolid::GetMaterial)
    .def("col", FunctionPointer([](shared_ptr<SPSolid> & self, bp::list rgb) -> shared_ptr<SPSolid>
                                {
                                  bp::extract<double> red(rgb[0]);
                                  bp::extract<double> green(rgb[1]);
                                  bp::extract<double> blue(rgb[2]);
                                  self->SetColor(red(),green(),blue());
                                  return self;
                                }))
    .def("transp", FunctionPointer([](shared_ptr<SPSolid> & self)->shared_ptr < SPSolid > { self->SetTransparent(); return self; }))
    ;

  bp::def ("Sphere", FunctionPointer([](Point<3> c, double r)
                                     {
                                       Sphere * sp = new Sphere (c, r);
                                       Solid * sol = new Solid (sp);
                                       return make_shared<SPSolid> (sol);
                                     }));
  bp::def ("Plane", FunctionPointer([](Point<3> p, Vec<3> n)
                                    {
                                      Plane * sp = new Plane (p,n);
                                      Solid * sol = new Solid (sp);
                                      return make_shared<SPSolid> (sol);
                                    }));
  bp::def ("Cylinder", FunctionPointer([](Point<3> a, Point<3> b, double r)
                                       {
                                         Cylinder * cyl = new Cylinder (a, b, r);
                                         Solid * sol = new Solid (cyl);
                                         return make_shared<SPSolid> (sol);
                                       }));
  bp::def ("OrthoBrick", FunctionPointer([](Point<3> p1, Point<3> p2)
                                         {
                                           OrthoBrick * brick = new OrthoBrick (p1,p2);
                                           Solid * sol = new Solid (brick);
                                           return make_shared<SPSolid> (sol);
                                         }));

  bp::def ("Or", FunctionPointer([](shared_ptr<SPSolid> s1, shared_ptr<SPSolid> s2)
                                 {
                                   return make_shared<SPSolid> (SPSolid::UNION, s1, s2);
                                 }));
  bp::def ("And", FunctionPointer([](shared_ptr<SPSolid> s1, shared_ptr<SPSolid> s2)
                                  {
                                    return make_shared<SPSolid> (SPSolid::SECTION, s1, s2);
                                  }));

  bp::class_<CSGeometry,shared_ptr<CSGeometry>, boost::noncopyable> ("CSGeometry")
    .def("__init__", bp::make_constructor (FunctionPointer
                                           ([](const string & filename)
                                            {
                                              cout << "load geometry";
                                              ifstream ist(filename);
                                              shared_ptr<CSGeometry> geom(ParseCSG(ist));
                                              geom -> FindIdenticSurfaces(1e-8 * geom->MaxSize());
                                              return geom;
                                            })))

    .def("__init__", bp::make_constructor (FunctionPointer
                                           ([](const bp::list & solidlist)
                                            {
                                              cout << "csg from list";
                                              auto geom = make_shared<CSGeometry>();
                                              for (int i = 0; i < len(solidlist); i++)
                                                {
                                                  bp::object obj = solidlist[i];
                                                  cout << "obj " << i << endl;

                                                  bp::extract<shared_ptr<SPSolid>> solid(solidlist[i]);
                                                  if(solid.check())
                                                    {
                                                      cout << "its a solid" << endl;
                                                      solid()->AddSurfaces (*geom);
                                                      solid()->GiveUpOwner();
                                                      int tlonr = geom->SetTopLevelObject (solid()->GetSolid());
                                                      geom->GetTopLevelObject(tlonr) -> SetMaterial(solid()->GetMaterial());
                                                    }
                                                }
                                              geom -> FindIdenticSurfaces(1e-8 * geom->MaxSize());
                                              return geom;
                                            })))

    .def("Save", FunctionPointer([] (CSGeometry & self, string filename)
                                 {
                                   cout << "save geometry to file " << filename << endl;
                                   self.Save (filename);
                                 }))
    .def("Add", FunctionPointer
         ([] (CSGeometry & self, shared_ptr<SPSolid> solid, bp::list bcmod)
          {
            solid->AddSurfaces (self);
            solid->GiveUpOwner();
            int tlonr = self.SetTopLevelObject (solid->GetSolid());
            self.GetTopLevelObject(tlonr) -> SetMaterial(solid->GetMaterial());
            self.GetTopLevelObject(tlonr) -> SetRGB(solid->GetRed(),solid->GetGreen(),solid->GetBlue());
            self.GetTopLevelObject(tlonr)->SetTransparent(solid->IsTransparent());

            // bcmod is list of tuples ( solid, bcnr )
            for (int i = 0; i < bp::len(bcmod); i++)
              {
                bp::tuple tup = bp::extract<bp::tuple> (bcmod[i]) ();
                auto mod_solid = bp::extract<shared_ptr<SPSolid>> (tup[0]) ();
                auto mod_nr = bp::extract<int> (tup[1])();
                Array<int> si;
                mod_solid -> GetSolid() -> GetSurfaceIndices (si);
                // cout << "change bc on surfaces: " << si << " to " << mod_nr << endl;

                for (int j = 0; j < si.Size(); j++)
                  {
                    CSGeometry::BCModification bcm;
                    bcm.bcname = NULL;
                    bcm.tlonr = tlonr;
                    bcm.si = si[j];
		    bcm.bcnr = mod_nr;
		    self.bcmodifications.Append (bcm);
                  }
              }

          }),
         (bp::arg("self"), bp::arg("solid"), bp::arg("bcmod")=bp::list())
         )

    .def("CloseSurfaces", FunctionPointer
         ([] (CSGeometry & self, shared_ptr<SPSolid> s1, shared_ptr<SPSolid> s2, int reflevels)
          {
            Array<int> si1, si2;
            s1->GetSolid()->GetSurfaceIndices (si1);
            s2->GetSolid()->GetSurfaceIndices (si2);
            cout << "surface ids1 = " << si1 << endl;
            cout << "surface ids2 = " << si2 << endl;

            Flags flags;
            const TopLevelObject * domain = nullptr;
            self.AddIdentification
              (new CloseSurfaceIdentification
               (self.GetNIdentifications()+1, self,
                self.GetSurface (si1[0]), self.GetSurface (si2[0]),
                domain,
                flags));
          }),
         (bp::arg("self"), bp::arg("solid1"), bp::arg("solid2"), bp::arg("reflevels")=2)
         )

    .add_property ("ntlo", &CSGeometry::GetNTopLevelObjects)
    ;

  bp::def("GenerateMesh", FunctionPointer
          ([](shared_ptr<CSGeometry> geo, MeshingParameters & param)
           {
             auto dummy = make_shared<Mesh>();
             dummy->SetGeometry(geo);
	     ng_geometry = geo;
             geo->FindIdenticSurfaces(1e-8 * geo->MaxSize());
             geo->GenerateMesh (dummy, param, 0, 6);
             return dummy;
           }))
    ;

  bp::def("Save", FunctionPointer
          ([](const Mesh & self, const string & filename, const CSGeometry & geom)
           {
             ostream * outfile;
             if (filename.substr (filename.length()-3, 3) == ".gz")
               outfile = new ogzstream (filename.c_str());
             else
               outfile = new ofstream (filename.c_str());

             self.Save (*outfile);
             *outfile << endl << endl << "endmesh" << endl << endl;
             geom.SaveToMeshFile (*outfile);
             delete outfile;
           }))
    ;

  bp::def("ZRefinement", FunctionPointer
          ([](Mesh & mesh, CSGeometry & geom)
          {
            ZRefinementOptions opt;
            opt.minref = 5;
            ZRefinement (mesh, &geom, opt);
          }))
    ;
}

BOOST_PYTHON_MODULE(libcsg) {
  ExportCSG();
}

#endif

<commit_msg>bcm modification for names<commit_after>#ifdef NG_PYTHON

#include <../general/ngpython.hpp>
#include <csg.hpp>

using namespace netgen;

namespace netgen
{
  extern shared_ptr<NetgenGeometry> ng_geometry;
}

inline void NOOP_Deleter(void *) { ; }

// a shadow solid tree using shared pointers.

class SPSolid
{
  shared_ptr<SPSolid> s1, s2;
  Solid * solid;
  int bc = -1;
  string bcname = "";
  double maxh = -1;
  string material;
  bool owner;
  double red, green, blue;
  bool transp = false;
public:
  enum optyp { TERM, SECTION, UNION, SUB };

  SPSolid (Solid * as) : solid(as), owner(true), op(TERM) { ; }
  ~SPSolid ()
  {
    ; // if (owner) delete solid;
  }
  SPSolid (optyp aop, shared_ptr<SPSolid> as1, shared_ptr<SPSolid> as2)
    : s1(as1), s2(as2), owner(true), op(aop)
  {
    if (aop == UNION)
      solid = new Solid (Solid::UNION, s1->GetSolid(), s2->GetSolid());
    else if (aop == SECTION)
      solid = new Solid (Solid::SECTION, s1->GetSolid(), s2->GetSolid());
    else if (aop == SUB)
      solid = new Solid (Solid::SUB, s1->GetSolid()); // , s2->GetSolid());
  }

  Solid * GetSolid() { return solid; }
  const Solid * GetSolid() const { return solid; }

  void GiveUpOwner()
  {
    owner = false;
    if (s1) s1 -> GiveUpOwner();
    if (s2) s2 -> GiveUpOwner();
  }

  void AddSurfaces(CSGeometry & geom)
  {
    if (op == TERM)
      geom.AddSurfaces (solid->GetPrimitive());
    if (s1) s1 -> AddSurfaces (geom);
    if (s2) s2 -> AddSurfaces (geom);
  }

  void SetMaterial (string mat)  { material = mat; }

  string GetMaterial ()
  {
    if (!material.empty()) return material;
    if (s1)
      {
        string s1mat = s1->GetMaterial();
        if (!s1mat.empty()) return s1mat;
      }
    if (s2)
      {
        string s2mat = s2->GetMaterial();
        if (!s2mat.empty()) return s2mat;
      }
    return material;
  }

  void SetBC(int abc)
  {
    if (bc == -1)
      {
        bc = abc;
        if (s1) s1 -> SetBC(bc);
        if (s2) s2 -> SetBC(bc);
        if (op == TERM)
          {
            Primitive * prim = solid -> GetPrimitive();
            for (int i = 0; i < prim->GetNSurfaces(); i++)
              prim->GetSurface(i).SetBCProperty (abc);
            // cout << "set " << prim->GetNSurfaces() << " surfaces to bc " << bc << endl;
          }
      }
  }

  void SetBCName(string name)
  {
    if (bcname == "")
      {
        bcname = name;
        if (s1) s1 -> SetBCName(name);
        if (s2) s2 -> SetBCName(name);
        if (op == TERM)
          {
            Primitive * prim = solid -> GetPrimitive();
            for (int i = 0; i < prim->GetNSurfaces(); i++)
              prim->GetSurface(i).SetBCName (name);
            // cout << "set " << prim->GetNSurfaces() << " surfaces to bc " << bc << endl;
          }
      }
  }

  void SetMaxH(double amaxh)
  {
    if (maxh == -1)
      {
        maxh = amaxh;
        if (s1) s1 -> SetMaxH(maxh);
        if (s2) s2 -> SetMaxH(maxh);
        if (op == TERM)
          {
            Primitive * prim = solid -> GetPrimitive();
            for (int i = 0; i < prim->GetNSurfaces(); i++)
              prim->GetSurface(i).SetMaxH (maxh);
          }
      }
  }

  void SetColor(double ared, double agreen, double ablue)
  {
    red = ared;
    green = agreen;
    blue = ablue;
  }

  double GetRed() const { return red; }
  double GetGreen() const { return green; }
  double GetBlue() const { return blue; }

  void SetTransparent() { transp = true; }
  bool IsTransparent() { return transp; }

private:
  optyp op;
};

inline ostream & operator<< (ostream & ost, const SPSolid & sol)
{
  ost << *sol.GetSolid();
  return ost;
}

namespace netgen
{
  extern CSGeometry * ParseCSG (istream & istr);
}

DLL_HEADER void ExportCSG()
{
  ModuleScope module("csg");

  bp::class_<Point<2>> ("Point2d", bp::init<double,double>())
    .def ("__str__", &ToString<Point<2>>)
    .def(bp::self-bp::self)
    .def(bp::self+Vec<2>())
    .def(bp::self-Vec<2>())
    ;

  bp::class_<Point<3>> ("Point3d", bp::init<double,double,double>())
    .def ("__str__", &ToString<Point<3>>)
    .def(bp::self-bp::self)
    .def(bp::self+Vec<3>())
    .def(bp::self-Vec<3>())
    ;

  bp::def ("Pnt", FunctionPointer
           ([](double x, double y, double z) { return Point<3>(x,y,z); }));
  bp::def ("Pnt", FunctionPointer
           ([](double x, double y) { return Point<2>(x,y); }));

  bp::class_<Vec<2>> ("Vec2d", bp::init<double,double>())
    .def ("__str__", &ToString<Vec<3>>)
    .def(bp::self+bp::self)
    .def(bp::self-bp::self)
    .def(-bp::self)
    .def(double()*bp::self)
    .def("Norm", &Vec<2>::Length)
    ;

  bp::class_<Vec<3>> ("Vec3d", bp::init<double,double,double>())
    .def ("__str__", &ToString<Vec<3>>)
    .def(bp::self+bp::self)
    .def(bp::self-bp::self)
    .def(-bp::self)
    .def(double()*bp::self)
    .def("Norm", &Vec<3>::Length)
    ;

  bp::def ("Vec", FunctionPointer
           ([] (double x, double y, double z) { return Vec<3>(x,y,z); }));
  bp::def ("Vec", FunctionPointer
           ([] (double x, double y) { return Vec<2>(x,y); }));

  bp::class_<SPSolid, shared_ptr<SPSolid>, boost::noncopyable> ("Solid", bp::no_init)
    .def ("__str__", &ToString<SPSolid>)
    .def ("__add__", FunctionPointer( [] ( shared_ptr<SPSolid> self, shared_ptr<SPSolid> other) { return make_shared<SPSolid> (SPSolid::UNION, self, other); }))
    .def ("__mul__", FunctionPointer( [] ( shared_ptr<SPSolid> self, shared_ptr<SPSolid> other) { return make_shared<SPSolid> (SPSolid::SECTION, self, other); }))
    .def ("__sub__", FunctionPointer
          ([] ( shared_ptr<SPSolid> self, shared_ptr<SPSolid> other)
           { return make_shared<SPSolid> (SPSolid::SECTION, self,
                                          make_shared<SPSolid> (SPSolid::SUB, other, nullptr)); }))

    .def ("bc", FunctionPointer([](shared_ptr<SPSolid> & self, int nr) -> shared_ptr<SPSolid>
                                { self->SetBC(nr); return self; }))
    .def ("bc", FunctionPointer([](shared_ptr<SPSolid> & self, string name) -> shared_ptr<SPSolid>
                                { self->SetBCName(name); return self; }))
    .def ("maxh", FunctionPointer([](shared_ptr<SPSolid> & self, double maxh) -> shared_ptr<SPSolid>
                                { self->SetMaxH(maxh); return self; }))
    .def ("mat", FunctionPointer([](shared_ptr<SPSolid> & self, string mat) -> shared_ptr<SPSolid>
                                 { self->SetMaterial(mat); return self; }))
    .def ("mat", &SPSolid::GetMaterial)
    .def("col", FunctionPointer([](shared_ptr<SPSolid> & self, bp::list rgb) -> shared_ptr<SPSolid>
                                {
                                  bp::extract<double> red(rgb[0]);
                                  bp::extract<double> green(rgb[1]);
                                  bp::extract<double> blue(rgb[2]);
                                  self->SetColor(red(),green(),blue());
                                  return self;
                                }))
    .def("transp", FunctionPointer([](shared_ptr<SPSolid> & self)->shared_ptr < SPSolid > { self->SetTransparent(); return self; }))
    ;

  bp::def ("Sphere", FunctionPointer([](Point<3> c, double r)
                                     {
                                       Sphere * sp = new Sphere (c, r);
                                       Solid * sol = new Solid (sp);
                                       return make_shared<SPSolid> (sol);
                                     }));
  bp::def ("Plane", FunctionPointer([](Point<3> p, Vec<3> n)
                                    {
                                      Plane * sp = new Plane (p,n);
                                      Solid * sol = new Solid (sp);
                                      return make_shared<SPSolid> (sol);
                                    }));
  bp::def ("Cylinder", FunctionPointer([](Point<3> a, Point<3> b, double r)
                                       {
                                         Cylinder * cyl = new Cylinder (a, b, r);
                                         Solid * sol = new Solid (cyl);
                                         return make_shared<SPSolid> (sol);
                                       }));
  bp::def ("OrthoBrick", FunctionPointer([](Point<3> p1, Point<3> p2)
                                         {
                                           OrthoBrick * brick = new OrthoBrick (p1,p2);
                                           Solid * sol = new Solid (brick);
                                           return make_shared<SPSolid> (sol);
                                         }));

  bp::def ("Or", FunctionPointer([](shared_ptr<SPSolid> s1, shared_ptr<SPSolid> s2)
                                 {
                                   return make_shared<SPSolid> (SPSolid::UNION, s1, s2);
                                 }));
  bp::def ("And", FunctionPointer([](shared_ptr<SPSolid> s1, shared_ptr<SPSolid> s2)
                                  {
                                    return make_shared<SPSolid> (SPSolid::SECTION, s1, s2);
                                  }));

  bp::class_<CSGeometry,shared_ptr<CSGeometry>, boost::noncopyable> ("CSGeometry")
    .def("__init__", bp::make_constructor (FunctionPointer
                                           ([](const string & filename)
                                            {
                                              cout << "load geometry";
                                              ifstream ist(filename);
                                              shared_ptr<CSGeometry> geom(ParseCSG(ist));
                                              geom -> FindIdenticSurfaces(1e-8 * geom->MaxSize());
                                              return geom;
                                            })))

    .def("__init__", bp::make_constructor (FunctionPointer
                                           ([](const bp::list & solidlist)
                                            {
                                              cout << "csg from list";
                                              auto geom = make_shared<CSGeometry>();
                                              for (int i = 0; i < len(solidlist); i++)
                                                {
                                                  bp::object obj = solidlist[i];
                                                  cout << "obj " << i << endl;

                                                  bp::extract<shared_ptr<SPSolid>> solid(solidlist[i]);
                                                  if(solid.check())
                                                    {
                                                      cout << "its a solid" << endl;
                                                      solid()->AddSurfaces (*geom);
                                                      solid()->GiveUpOwner();
                                                      int tlonr = geom->SetTopLevelObject (solid()->GetSolid());
                                                      geom->GetTopLevelObject(tlonr) -> SetMaterial(solid()->GetMaterial());
                                                    }
                                                }
                                              geom -> FindIdenticSurfaces(1e-8 * geom->MaxSize());
                                              return geom;
                                            })))

    .def("Save", FunctionPointer([] (CSGeometry & self, string filename)
                                 {
                                   cout << "save geometry to file " << filename << endl;
                                   self.Save (filename);
                                 }))
    .def("Add", FunctionPointer
         ([] (CSGeometry & self, shared_ptr<SPSolid> solid, bp::list bcmod)
          {
            solid->AddSurfaces (self);
            solid->GiveUpOwner();
            int tlonr = self.SetTopLevelObject (solid->GetSolid());
            self.GetTopLevelObject(tlonr) -> SetMaterial(solid->GetMaterial());
            self.GetTopLevelObject(tlonr) -> SetRGB(solid->GetRed(),solid->GetGreen(),solid->GetBlue());
            self.GetTopLevelObject(tlonr)->SetTransparent(solid->IsTransparent());

            // bcmod is list of tuples ( solid, bcnr )
            for (int i = 0; i < bp::len(bcmod); i++)
              {
                bp::tuple tup = bp::extract<bp::tuple> (bcmod[i]) ();
                auto mod_solid = bp::extract<shared_ptr<SPSolid>> (tup[0]) ();
                int mod_nr = -1;
                string * bcname = nullptr;
                bp::object val = tup[1];
                if (bp::extract<int>(val).check()) mod_nr = bp::extract<int> (val)();
                if (bp::extract<string>(val).check()) bcname = new string ( bp::extract<string> (val)());

                Array<int> si;
                mod_solid -> GetSolid() -> GetSurfaceIndices (si);
                // cout << "change bc on surfaces: " << si << " to " << mod_nr << endl;

                for (int j = 0; j < si.Size(); j++)
                  {
                    CSGeometry::BCModification bcm;
                    bcm.bcname = bcname ? new string (*bcname) : nullptr;
                    bcm.tlonr = tlonr;
                    bcm.si = si[j];
		    bcm.bcnr = mod_nr;
		    self.bcmodifications.Append (bcm);
                  }
                delete bcname;
              }

          }),
         (bp::arg("self"), bp::arg("solid"), bp::arg("bcmod")=bp::list())
         )

    .def("CloseSurfaces", FunctionPointer
         ([] (CSGeometry & self, shared_ptr<SPSolid> s1, shared_ptr<SPSolid> s2, int reflevels)
          {
            Array<int> si1, si2;
            s1->GetSolid()->GetSurfaceIndices (si1);
            s2->GetSolid()->GetSurfaceIndices (si2);
            cout << "surface ids1 = " << si1 << endl;
            cout << "surface ids2 = " << si2 << endl;

            Flags flags;
            const TopLevelObject * domain = nullptr;
            self.AddIdentification
              (new CloseSurfaceIdentification
               (self.GetNIdentifications()+1, self,
                self.GetSurface (si1[0]), self.GetSurface (si2[0]),
                domain,
                flags));
          }),
         (bp::arg("self"), bp::arg("solid1"), bp::arg("solid2"), bp::arg("reflevels")=2)
         )

    .add_property ("ntlo", &CSGeometry::GetNTopLevelObjects)
    ;

  bp::def("GenerateMesh", FunctionPointer
          ([](shared_ptr<CSGeometry> geo, MeshingParameters & param)
           {
             auto dummy = make_shared<Mesh>();
             dummy->SetGeometry(geo);
	     ng_geometry = geo;
             geo->FindIdenticSurfaces(1e-8 * geo->MaxSize());
             geo->GenerateMesh (dummy, param, 0, 6);
             return dummy;
           }))
    ;

  bp::def("Save", FunctionPointer
          ([](const Mesh & self, const string & filename, const CSGeometry & geom)
           {
             ostream * outfile;
             if (filename.substr (filename.length()-3, 3) == ".gz")
               outfile = new ogzstream (filename.c_str());
             else
               outfile = new ofstream (filename.c_str());

             self.Save (*outfile);
             *outfile << endl << endl << "endmesh" << endl << endl;
             geom.SaveToMeshFile (*outfile);
             delete outfile;
           }))
    ;

  bp::def("ZRefinement", FunctionPointer
          ([](Mesh & mesh, CSGeometry & geom)
          {
            ZRefinementOptions opt;
            opt.minref = 5;
            ZRefinement (mesh, &geom, opt);
          }))
    ;
}

BOOST_PYTHON_MODULE(libcsg) {
  ExportCSG();
}

#endif

<|endoftext|>


<commit_before>#include "LION.H"

#include "DRAW.H"
#include "BOX.H"
#include "LARA.H"
#include "OBJECTS.H"
#include "SETUP.H"
#include "CONTROL.H"
#include "TOMB4FX.H"
#include "STYPES.H"
#if PC_VERSION
#include "GAME.H"
#endif

#if PSX_VERSION || PSXPC_VERSION || SAT_VERSION
#include "MISC.H"
#endif

struct BITE_INFO LION_BITE_1 = { 0x0FFFFFFFE, 0x0FFFFFFF6, 0x0FA, 0x15 };
struct BITE_INFO LION_BITE_2 = { 0x0FFFFFFFE, 0x0FFFFFFF6, 0x84, 0x15 };

void InitialiseLion(short item_num)
{
	struct ITEM_INFO* item = &items[item_num];

	InitialiseCreature(item_num);
	item->anim_number = objects[LION].anim_index;
	item->frame_number = anims[objects[LION].anim_index].frame_base;
	item->goal_anim_state = 1;
	item->current_anim_state = 1;
}

void LionControl(short item_num)
{
	short angle;
	short required;
	char *data;
	struct ITEM_INFO* item;
	short Lion_Object;
	short Lion_DefaultAnim;
	short Creature_Turn;
	short Creature_Angle;
	short requiredAngle;
	short requiredAnimState;
	int v9;
	int v10;
	struct AI_info info;

	data = (char*)items[item_num].data;
	item = &items[item_num];
	if (CreatureActive(item_num))
	{
		requiredAngle = 0;
		Creature_Angle = 0;
		angle = 0;
		required = 0;
		data = (char *)items[item_num].data;
		item = &items[item_num];
		if (items[item_num].hit_points <= 0)
		{
			item->hit_points = 0;
			if (item->current_anim_state != 5)
			{
				Lion_Object = objects[57].anim_index + (GetRandomControl() & 1) + 7;
				item->anim_number = Lion_Object;
				Lion_DefaultAnim = anims[Lion_Object].frame_base;
				item->current_anim_state = 5;
				item->frame_number = Lion_DefaultAnim;
			}
			CreatureTilt(item, angle);
			CreatureJoint(item, 0, requiredAngle);
			CreatureJoint(item, 1, required);
			CreatureAnimation(item_num, Creature_Angle, 0);
			return;
		}
		CreatureAIInfo(item, &info);
		if (info.ahead)
			required = info.angle;
		GetCreatureMood(item, &info, 1);
		CreatureMood(item, &info, 1);
		Creature_Turn = CreatureTurn(item, *((unsigned short *)data + 4));
		Creature_Angle = Creature_Turn;
		requiredAngle = -16 * Creature_Turn;
		switch (item->current_anim_state)
		{
		case 1:
			*((unsigned short *)data + 4) = 0;
			requiredAnimState = item->required_anim_state;
			if (requiredAnimState)
			{
				item->goal_anim_state = requiredAnimState;
				CreatureTilt(item, angle);
				CreatureJoint(item, 0, requiredAngle);
				CreatureJoint(item, 1, required);
				CreatureAnimation(item_num, Creature_Angle, 0);
				return;
			}
			if (!*(unsigned long *)(data + 14))
			{
				if (!(GetRandomControl() & 0x3F))
					item->goal_anim_state = 2;
				CreatureTilt(item, angle);
				CreatureJoint(item, 0, requiredAngle);
				CreatureJoint(item, 1, required);
				CreatureAnimation(item_num, Creature_Angle, 0);
				return;
			}
			if (info.ahead)
			{
				if (item->touch_bits & 0x200048)
				{
					item->goal_anim_state = 7;
					CreatureTilt(item, angle);
					CreatureJoint(item, 0, requiredAngle);
					CreatureJoint(item, 1, required);
					CreatureAnimation(item_num, Creature_Angle, 0);
					return;
				}
				if (info.distance < 0x100000)
				{
					item->goal_anim_state = 4;
					CreatureTilt(item, angle);
					CreatureJoint(item, 0, requiredAngle);
					CreatureJoint(item, 1, required);
					CreatureAnimation(item_num, Creature_Angle, 0);
					return;
				}
			}
			item->goal_anim_state = 3;
			CreatureTilt(item, angle);
			CreatureJoint(item, 0, requiredAngle);
			CreatureJoint(item, 1, required);
			CreatureAnimation(item_num, Creature_Angle, 0);
			return;
		case 2:
			v9 = *(unsigned long *)(data + 14);
			*((unsigned short *)data + 4) = 364;
			if (!v9)
				if (GetRandomControl() < 128)
				{
					item->required_anim_state = 6;
					item->goal_anim_state = 1;
				}
			item->goal_anim_state = 1;
			CreatureTilt(item, angle);
			CreatureJoint(item, 0, requiredAngle);
			CreatureJoint(item, 1, required);
			CreatureAnimation(item_num, Creature_Angle, 0);
			return;
		case 3:
			*((unsigned short *)data + 4) = 910;
			v10 = *(unsigned long *)(data + 14);
			angle = Creature_Turn;
			if (v10)
			{
				if (info.ahead && info.distance < 0x100000)
				{
					item->goal_anim_state = 1;
				}
				else if (item->touch_bits & 0x200048 && info.ahead)
				{
					item->goal_anim_state = 1;
				}
				else if (v10 != 2)
				{
					if (GetRandomControl() < 128)
					{
						item->required_anim_state = 6;
						item->goal_anim_state = 1;
					}
				}
			}
			else
			{
				item->goal_anim_state = 1;
			}
			CreatureTilt(item, angle);
			CreatureJoint(item, 0, requiredAngle);
			CreatureJoint(item, 1, required);
			CreatureAnimation(item_num, Creature_Angle, 0);
			return;
		case 4:
			if (!item->required_anim_state && item->touch_bits & 0x200048)
			{
				lara_item->hit_points -= 200;
				//*((unsigned long *)&lara_item->pointer2 + 1) |= 0x10u;
				//CreatureEffectT(item,&LION_BITE_1,10,item->pos.y_rot,(__int16(__cdecl *)(int, int, int, __int16, __int16, __int16))DoBloodSplat);
				item->required_anim_state = 1;
			}
			CreatureTilt(item, angle);
			CreatureJoint(item, 0, requiredAngle);
			CreatureJoint(item, 1, required);
			CreatureAnimation(item_num, Creature_Angle, 0);
			return;
		case 7:
			*((unsigned short *)data + 4) = 182;
			if (!item->required_anim_state && item->touch_bits & 0x200048)
			{
				//CreatureEffectT(item,&LION_BITE_2,10,item->pos.y_rot,(__int16(__cdecl *)(int, int, int, __int16, __int16, __int16))DoBloodSplat);
				lara_item->hit_points -= 60;
				//*((unsigned long *)&lara_item->pointer2 + 1) |= 0x10u;
				item->required_anim_state= 1;
			}
			CreatureTilt(item, angle);
			CreatureJoint(item, 0, requiredAngle);
			CreatureJoint(item, 1, required);
			CreatureAnimation(item_num, Creature_Angle, 0);
			return;
		default:
			CreatureTilt(item, angle);
			CreatureJoint(item, 0, requiredAngle);
			CreatureJoint(item, 1, required);
			CreatureAnimation(item_num, Creature_Angle, 0);
			return;
		}
	}
}<commit_msg>enhance InitialiseLion<commit_after>#include "LION.H"

#include "DRAW.H"
#include "BOX.H"
#include "LARA.H"
#include "OBJECTS.H"
#include "SETUP.H"
#include "CONTROL.H"
#include "TOMB4FX.H"
#include "STYPES.H"
#include "FXTRIG.H"
#include "EFFECTS.H"
#if PC_VERSION
#include "GAME.H"
#endif

#if PSX_VERSION || PSXPC_VERSION || SAT_VERSION
#include "MISC.H"
#endif

struct BITE_INFO LION_BITE_1 = { -2, -10, 0x0FA, 0x15 };
struct BITE_INFO LION_BITE_2 = { -2, -10, 0x84, 0x15 };

void InitialiseLion(short item_num)
{
	struct ITEM_INFO* item = &items[item_num];

	InitialiseCreature(item_num);
	item->anim_number = objects[LION].anim_index;
	item->frame_number = anims[objects[LION].anim_index].frame_base;
	item->goal_anim_state = 1;
	item->current_anim_state = 1;
}

void LionControl(short item_num)
{
	short angle;
	short required;
	char *data;
	struct ITEM_INFO* item;
	short Lion_Object;
	short Lion_DefaultAnim;
	short Creature_Turn;
	short Creature_Angle;
	short requiredAngle;
	short requiredAnimState;
	int v9;
	int v10;
	struct AI_info info;

	if (CreatureActive(item_num))
	{
		requiredAngle = 0;
		Creature_Angle = 0;
		angle = 0;
		required = 0;
		struct creature_info* crinfo = (struct creature_info*)items[item_num].data;
		item = &items[item_num];
		if (items[item_num].hit_points <= 0)
		{
			item->hit_points = 0;
			if (item->current_anim_state != 5)
			{
				Lion_Object = objects[LION].anim_index + (GetRandomControl() & 1) + 7;
				item->anim_number = Lion_Object;
				Lion_DefaultAnim = anims[Lion_Object].frame_base;
				item->current_anim_state = 5;
				item->frame_number = Lion_DefaultAnim;
			}
			CreatureTilt(item, angle);
			CreatureJoint(item, 0, requiredAngle);
			CreatureJoint(item, 1, required);
			CreatureAnimation(item_num, Creature_Angle, 0);
			return;
		}
		CreatureAIInfo(item, &info);
		if (info.ahead)
			required = info.angle;
		GetCreatureMood(item, &info, 1);
		CreatureMood(item, &info, 1);
		Creature_Turn = CreatureTurn(item, crinfo->maximum_turn);
		Creature_Angle = Creature_Turn;
		requiredAngle = -16 * Creature_Turn;
		switch (item->current_anim_state)
		{
		case 1:
			crinfo->maximum_turn = 0;
			requiredAnimState = item->required_anim_state;
			if (requiredAnimState)
			{
				item->goal_anim_state = requiredAnimState;
				CreatureTilt(item, angle);
				CreatureJoint(item, 0, requiredAngle);
				CreatureJoint(item, 1, required);
				CreatureAnimation(item_num, Creature_Angle, 0);
				return;
			}
			if (crinfo->mood == BORED_MOOD)
			{
				if (!(GetRandomControl() & 0x3F))
					item->goal_anim_state = 2;
				CreatureTilt(item, angle);
				CreatureJoint(item, 0, requiredAngle);
				CreatureJoint(item, 1, required);
				CreatureAnimation(item_num, Creature_Angle, 0);
				return;
			}
			if (info.ahead)
			{
				if (item->touch_bits & 0x200048)
				{
					item->goal_anim_state = 7;
					CreatureTilt(item, angle);
					CreatureJoint(item, 0, requiredAngle);
					CreatureJoint(item, 1, required);
					CreatureAnimation(item_num, Creature_Angle, 0);
					return;
				}
				if (info.distance < 0x100000)
				{
					item->goal_anim_state = 4;
					CreatureTilt(item, angle);
					CreatureJoint(item, 0, requiredAngle);
					CreatureJoint(item, 1, required);
					CreatureAnimation(item_num, Creature_Angle, 0);
					return;
				}
			}
			item->goal_anim_state = 3;
			CreatureTilt(item, angle);
			CreatureJoint(item, 0, requiredAngle);
			CreatureJoint(item, 1, required);
			CreatureAnimation(item_num, Creature_Angle, 0);
			return;
		case 2:
			crinfo->maximum_turn = ANGLE(2);
			if (crinfo->mood == BORED_MOOD)
				if (GetRandomControl() < 128)
				{
					item->required_anim_state = 6;
					item->goal_anim_state = 1;
				}
			item->goal_anim_state = 1;
			CreatureTilt(item, angle);
			CreatureJoint(item, 0, requiredAngle);
			CreatureJoint(item, 1, required);
			CreatureAnimation(item_num, Creature_Angle, 0);
			return;
		case 3:
			crinfo->maximum_turn = ANGLE(5);
			angle = Creature_Turn;
			if (crinfo->mood == BORED_MOOD)
			{
				if (info.ahead && info.distance < 0x100000)
				{
					item->goal_anim_state = 1;
				}
				else if (item->touch_bits & 0x200048 && info.ahead)
				{
					item->goal_anim_state = 1;
				}
				else if (crinfo->mood != ESCAPE_MOOD)
				{
					if (GetRandomControl() < 128)
					{
						item->required_anim_state = 6;
						item->goal_anim_state = 1;
					}
				}
			}
			else
			{
				item->goal_anim_state = 1;
			}
			CreatureTilt(item, angle);
			CreatureJoint(item, 0, requiredAngle);
			CreatureJoint(item, 1, required);
			CreatureAnimation(item_num, Creature_Angle, 0);
			return;
		case 4:
			if (!item->required_anim_state && item->touch_bits & 0x200048)
			{
				lara_item->hit_points -= 200;
				lara_item->hit_status = TRUE;
				CreatureEffectT(item, &LION_BITE_1, 10, item->pos.y_rot, DoBloodSplat);
				item->required_anim_state = 1;
			}
			CreatureTilt(item, angle);
			CreatureJoint(item, 0, requiredAngle);
			CreatureJoint(item, 1, required);
			CreatureAnimation(item_num, Creature_Angle, 0);
			return;
		case 7:
			crinfo->maximum_turn = ANGLE(1);
			if (!item->required_anim_state && item->touch_bits & 0x200048)
			{
				CreatureEffectT(item,&LION_BITE_2,10,item->pos.y_rot, DoBloodSplat);
				lara_item->hit_points -= 60;
				lara_item->hit_status = TRUE;
				item->required_anim_state= 1;
			}
			CreatureTilt(item, angle);
			CreatureJoint(item, 0, requiredAngle);
			CreatureJoint(item, 1, required);
			CreatureAnimation(item_num, Creature_Angle, 0);
			return;
		default:
			CreatureTilt(item, angle);
			CreatureJoint(item, 0, requiredAngle);
			CreatureJoint(item, 1, required);
			CreatureAnimation(item_num, Creature_Angle, 0);
			return;
		}
	}
}<|endoftext|>


<commit_before>// g++ -O3 -DNDEBUG -I.. -L /usr/lib64/atlas/ benchBlasGemm.cpp -o benchBlasGemm -lrt -lcblas
// possible options:
//    -DEIGEN_DONT_VECTORIZE
//    -msse2

// #define EIGEN_DEFAULT_TO_ROW_MAJOR
#define _FLOAT

#include <iostream>

#include <Eigen/Core>
#include "BenchTimer.h"

// include the BLAS headers
extern "C" {
#include <cblas.h>
}
#include <string>

#ifdef _FLOAT
typedef float Scalar;
#define CBLAS_GEMM cblas_sgemm
#else
typedef double Scalar;
#define CBLAS_GEMM cblas_dgemm
#endif

typedef Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic> MyMatrix;
void bench_eigengemm(MyMatrix& mc, const MyMatrix& ma, const MyMatrix& mb, int nbloops);
void check_product(int M, int N, int K);
void check_product(void);

int main(int argc, char *argv[])
{
  // disable SSE exceptions
  #ifdef __GNUC__
  {
    int aux;
    asm(
    "stmxcsr   %[aux]           \n\t"
    "orl       $32832, %[aux]   \n\t"
    "ldmxcsr   %[aux]           \n\t"
    : : [aux] "m" (aux));
  }
  #endif

  Eigen::setCpuCacheSizes(262144, 6000000);

  int nbtries=1, nbloops=1, M, N, K;

  if (argc==2)
  {
    if (std::string(argv[1])=="check")
      check_product();
    else
      M = N = K = atoi(argv[1]);
  }
  else if ((argc==3) && (std::string(argv[1])=="auto"))
  {
    M = N = K = atoi(argv[2]);
    nbloops = 1000000000/(M*M*M);
    if (nbloops<1)
      nbloops = 1;
    nbtries = 6;
  }
  else if (argc==4)
  {
    M = N = K = atoi(argv[1]);
    nbloops = atoi(argv[2]);
    nbtries = atoi(argv[3]);
  }
  else if (argc==6)
  {
    M = atoi(argv[1]);
    N = atoi(argv[2]);
    K = atoi(argv[3]);
    nbloops = atoi(argv[4]);
    nbtries = atoi(argv[5]);
  }
  else
  {
    std::cout << "Usage: " << argv[0] << " size  \n";
    std::cout << "Usage: " << argv[0] << " auto size\n";
    std::cout << "Usage: " << argv[0] << " size nbloops nbtries\n";
    std::cout << "Usage: " << argv[0] << " M N K nbloops nbtries\n";
    std::cout << "Usage: " << argv[0] << " check\n";
    std::cout << "Options:\n";
    std::cout << "    size       unique size of the 2 matrices (integer)\n";
    std::cout << "    auto       automatically set the number of repetitions and tries\n";
    std::cout << "    nbloops    number of times the GEMM routines is executed\n";
    std::cout << "    nbtries    number of times the loop is benched (return the best try)\n";
    std::cout << "    M N K      sizes of the matrices: MxN  =  MxK * KxN (integers)\n";
    std::cout << "    check      check eigen product using cblas as a reference\n";
    exit(1);
  }

  double nbmad = double(M) * double(N) * double(K) * double(nbloops);

  if (!(std::string(argv[1])=="auto"))
    std::cout << M << " x " << N << " x " << K << "\n";

  Scalar alpha, beta;
  MyMatrix ma(M,K), mb(K,N), mc(M,N);
  ma = MyMatrix::Random(M,K);
  mb = MyMatrix::Random(K,N);
  mc = MyMatrix::Random(M,N);

  Eigen::BenchTimer timer;

  // we simply compute c += a*b, so:
  alpha = 1;
  beta = 1;

  // bench cblas
  // ROWS_A, COLS_B, COLS_A, 1.0,  A, COLS_A, B, COLS_B, 0.0, C, COLS_B);
  if (!(std::string(argv[1])=="auto"))
  {
    timer.reset();
    for (uint k=0 ; k<nbtries ; ++k)
    {
        timer.start();
        for (uint j=0 ; j<nbloops ; ++j)
              #ifdef EIGEN_DEFAULT_TO_ROW_MAJOR
              CBLAS_GEMM(CblasRowMajor, CblasNoTrans, CblasNoTrans, M, N, K, alpha, ma.data(), K, mb.data(), N, beta, mc.data(), N);
              #else
              CBLAS_GEMM(CblasColMajor, CblasNoTrans, CblasNoTrans, M, N, K, alpha, ma.data(), M, mb.data(), K, beta, mc.data(), M);
              #endif
        timer.stop();
    }
    if (!(std::string(argv[1])=="auto"))
      std::cout << "cblas: " << timer.value() << " (" << 1e-3*floor(1e-6*nbmad/timer.value()) << " GFlops/s)\n";
    else
        std::cout << M << " : " << timer.value() << " ; " << 1e-3*floor(1e-6*nbmad/timer.value()) << "\n";
  }

  // clear
  ma = MyMatrix::Random(M,K);
  mb = MyMatrix::Random(K,N);
  mc = MyMatrix::Random(M,N);

  // eigen
//   if (!(std::string(argv[1])=="auto"))
  {
      timer.reset();
      for (uint k=0 ; k<nbtries ; ++k)
      {
          timer.start();
          bench_eigengemm(mc, ma, mb, nbloops);
          timer.stop();
      }
      if (!(std::string(argv[1])=="auto"))
        std::cout << "eigen : " << timer.value() << " (" << 1e-3*floor(1e-6*nbmad/timer.value()) << " GFlops/s)\n";
      else
        std::cout << M << " : " << timer.value() << " ; " << 1e-3*floor(1e-6*nbmad/timer.value()) << "\n";
  }

  std::cout << "l1: " << Eigen::l1CacheSize() << std::endl;
  std::cout << "l2: " << Eigen::l2CacheSize() << std::endl;

  return 0;
}

using namespace Eigen;

void bench_eigengemm(MyMatrix& mc, const MyMatrix& ma, const MyMatrix& mb, int nbloops)
{
  for (uint j=0 ; j<nbloops ; ++j)
      mc.noalias() += ma * mb;
}

#define MYVERIFY(A,M) if (!(A)) { \
    std::cout << "FAIL: " << M << "\n"; \
  }
void check_product(int M, int N, int K)
{
  MyMatrix ma(M,K), mb(K,N), mc(M,N), maT(K,M), mbT(N,K), meigen(M,N), mref(M,N);
  ma = MyMatrix::Random(M,K);
  mb = MyMatrix::Random(K,N);
  maT = ma.transpose();
  mbT = mb.transpose();
  mc = MyMatrix::Random(M,N);

  MyMatrix::Scalar eps = 1e-4;

  meigen = mref = mc;
  CBLAS_GEMM(CblasColMajor, CblasNoTrans, CblasNoTrans, M, N, K, 1, ma.data(), M, mb.data(), K, 1, mref.data(), M);
  meigen += ma * mb;
  MYVERIFY(meigen.isApprox(mref, eps),". * .");

  meigen = mref = mc;
  CBLAS_GEMM(CblasColMajor, CblasTrans, CblasNoTrans, M, N, K, 1, maT.data(), K, mb.data(), K, 1, mref.data(), M);
  meigen += maT.transpose() * mb;
  MYVERIFY(meigen.isApprox(mref, eps),"T * .");

  meigen = mref = mc;
  CBLAS_GEMM(CblasColMajor, CblasTrans, CblasTrans, M, N, K, 1, maT.data(), K, mbT.data(), N, 1, mref.data(), M);
  meigen += (maT.transpose()) * (mbT.transpose());
  MYVERIFY(meigen.isApprox(mref, eps),"T * T");

  meigen = mref = mc;
  CBLAS_GEMM(CblasColMajor, CblasNoTrans, CblasTrans, M, N, K, 1, ma.data(), M, mbT.data(), N, 1, mref.data(), M);
  meigen += ma * mbT.transpose();
  MYVERIFY(meigen.isApprox(mref, eps),". * T");
}

void check_product(void)
{
  int M, N, K;
  for (uint i=0; i<1000; ++i)
  {
    M = ei_random<int>(1,64);
    N = ei_random<int>(1,768);
    K = ei_random<int>(1,768);
    M = (0 + M) * 1;
    std::cout << M << " x " << N << " x " << K << "\n";
    check_product(M, N, K);
  }
}

<commit_msg>didn't want to commit that bench change.<commit_after>// g++ -O3 -DNDEBUG -I.. -L /usr/lib64/atlas/ benchBlasGemm.cpp -o benchBlasGemm -lrt -lcblas
// possible options:
//    -DEIGEN_DONT_VECTORIZE
//    -msse2

// #define EIGEN_DEFAULT_TO_ROW_MAJOR
#define _FLOAT

#include <iostream>

#include <Eigen/Core>
#include "BenchTimer.h"

// include the BLAS headers
extern "C" {
#include <cblas.h>
}
#include <string>

#ifdef _FLOAT
typedef float Scalar;
#define CBLAS_GEMM cblas_sgemm
#else
typedef double Scalar;
#define CBLAS_GEMM cblas_dgemm
#endif

typedef Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic> MyMatrix;
void bench_eigengemm(MyMatrix& mc, const MyMatrix& ma, const MyMatrix& mb, int nbloops);
void check_product(int M, int N, int K);
void check_product(void);

int main(int argc, char *argv[])
{
  // disable SSE exceptions
  #ifdef __GNUC__
  {
    int aux;
    asm(
    "stmxcsr   %[aux]           \n\t"
    "orl       $32832, %[aux]   \n\t"
    "ldmxcsr   %[aux]           \n\t"
    : : [aux] "m" (aux));
  }
  #endif

  int nbtries=1, nbloops=1, M, N, K;

  if (argc==2)
  {
    if (std::string(argv[1])=="check")
      check_product();
    else
      M = N = K = atoi(argv[1]);
  }
  else if ((argc==3) && (std::string(argv[1])=="auto"))
  {
    M = N = K = atoi(argv[2]);
    nbloops = 1000000000/(M*M*M);
    if (nbloops<1)
      nbloops = 1;
    nbtries = 6;
  }
  else if (argc==4)
  {
    M = N = K = atoi(argv[1]);
    nbloops = atoi(argv[2]);
    nbtries = atoi(argv[3]);
  }
  else if (argc==6)
  {
    M = atoi(argv[1]);
    N = atoi(argv[2]);
    K = atoi(argv[3]);
    nbloops = atoi(argv[4]);
    nbtries = atoi(argv[5]);
  }
  else
  {
    std::cout << "Usage: " << argv[0] << " size  \n";
    std::cout << "Usage: " << argv[0] << " auto size\n";
    std::cout << "Usage: " << argv[0] << " size nbloops nbtries\n";
    std::cout << "Usage: " << argv[0] << " M N K nbloops nbtries\n";
    std::cout << "Usage: " << argv[0] << " check\n";
    std::cout << "Options:\n";
    std::cout << "    size       unique size of the 2 matrices (integer)\n";
    std::cout << "    auto       automatically set the number of repetitions and tries\n";
    std::cout << "    nbloops    number of times the GEMM routines is executed\n";
    std::cout << "    nbtries    number of times the loop is benched (return the best try)\n";
    std::cout << "    M N K      sizes of the matrices: MxN  =  MxK * KxN (integers)\n";
    std::cout << "    check      check eigen product using cblas as a reference\n";
    exit(1);
  }

  double nbmad = double(M) * double(N) * double(K) * double(nbloops);

  if (!(std::string(argv[1])=="auto"))
    std::cout << M << " x " << N << " x " << K << "\n";

  Scalar alpha, beta;
  MyMatrix ma(M,K), mb(K,N), mc(M,N);
  ma = MyMatrix::Random(M,K);
  mb = MyMatrix::Random(K,N);
  mc = MyMatrix::Random(M,N);

  Eigen::BenchTimer timer;

  // we simply compute c += a*b, so:
  alpha = 1;
  beta = 1;

  // bench cblas
  // ROWS_A, COLS_B, COLS_A, 1.0,  A, COLS_A, B, COLS_B, 0.0, C, COLS_B);
  if (!(std::string(argv[1])=="auto"))
  {
    timer.reset();
    for (uint k=0 ; k<nbtries ; ++k)
    {
        timer.start();
        for (uint j=0 ; j<nbloops ; ++j)
              #ifdef EIGEN_DEFAULT_TO_ROW_MAJOR
              CBLAS_GEMM(CblasRowMajor, CblasNoTrans, CblasNoTrans, M, N, K, alpha, ma.data(), K, mb.data(), N, beta, mc.data(), N);
              #else
              CBLAS_GEMM(CblasColMajor, CblasNoTrans, CblasNoTrans, M, N, K, alpha, ma.data(), M, mb.data(), K, beta, mc.data(), M);
              #endif
        timer.stop();
    }
    if (!(std::string(argv[1])=="auto"))
      std::cout << "cblas: " << timer.value() << " (" << 1e-3*floor(1e-6*nbmad/timer.value()) << " GFlops/s)\n";
    else
        std::cout << M << " : " << timer.value() << " ; " << 1e-3*floor(1e-6*nbmad/timer.value()) << "\n";
  }

  // clear
  ma = MyMatrix::Random(M,K);
  mb = MyMatrix::Random(K,N);
  mc = MyMatrix::Random(M,N);

  // eigen
//   if (!(std::string(argv[1])=="auto"))
  {
      timer.reset();
      for (uint k=0 ; k<nbtries ; ++k)
      {
          timer.start();
          bench_eigengemm(mc, ma, mb, nbloops);
          timer.stop();
      }
      if (!(std::string(argv[1])=="auto"))
        std::cout << "eigen : " << timer.value() << " (" << 1e-3*floor(1e-6*nbmad/timer.value()) << " GFlops/s)\n";
      else
        std::cout << M << " : " << timer.value() << " ; " << 1e-3*floor(1e-6*nbmad/timer.value()) << "\n";
  }

  std::cout << "l1: " << Eigen::l1CacheSize() << std::endl;
  std::cout << "l2: " << Eigen::l2CacheSize() << std::endl;

  return 0;
}

using namespace Eigen;

void bench_eigengemm(MyMatrix& mc, const MyMatrix& ma, const MyMatrix& mb, int nbloops)
{
  for (uint j=0 ; j<nbloops ; ++j)
      mc.noalias() += ma * mb;
}

#define MYVERIFY(A,M) if (!(A)) { \
    std::cout << "FAIL: " << M << "\n"; \
  }
void check_product(int M, int N, int K)
{
  MyMatrix ma(M,K), mb(K,N), mc(M,N), maT(K,M), mbT(N,K), meigen(M,N), mref(M,N);
  ma = MyMatrix::Random(M,K);
  mb = MyMatrix::Random(K,N);
  maT = ma.transpose();
  mbT = mb.transpose();
  mc = MyMatrix::Random(M,N);

  MyMatrix::Scalar eps = 1e-4;

  meigen = mref = mc;
  CBLAS_GEMM(CblasColMajor, CblasNoTrans, CblasNoTrans, M, N, K, 1, ma.data(), M, mb.data(), K, 1, mref.data(), M);
  meigen += ma * mb;
  MYVERIFY(meigen.isApprox(mref, eps),". * .");

  meigen = mref = mc;
  CBLAS_GEMM(CblasColMajor, CblasTrans, CblasNoTrans, M, N, K, 1, maT.data(), K, mb.data(), K, 1, mref.data(), M);
  meigen += maT.transpose() * mb;
  MYVERIFY(meigen.isApprox(mref, eps),"T * .");

  meigen = mref = mc;
  CBLAS_GEMM(CblasColMajor, CblasTrans, CblasTrans, M, N, K, 1, maT.data(), K, mbT.data(), N, 1, mref.data(), M);
  meigen += (maT.transpose()) * (mbT.transpose());
  MYVERIFY(meigen.isApprox(mref, eps),"T * T");

  meigen = mref = mc;
  CBLAS_GEMM(CblasColMajor, CblasNoTrans, CblasTrans, M, N, K, 1, ma.data(), M, mbT.data(), N, 1, mref.data(), M);
  meigen += ma * mbT.transpose();
  MYVERIFY(meigen.isApprox(mref, eps),". * T");
}

void check_product(void)
{
  int M, N, K;
  for (uint i=0; i<1000; ++i)
  {
    M = ei_random<int>(1,64);
    N = ei_random<int>(1,768);
    K = ei_random<int>(1,768);
    M = (0 + M) * 1;
    std::cout << M << " x " << N << " x " << K << "\n";
    check_product(M, N, K);
  }
}

<|endoftext|>


<commit_before>#include <chrono>
#include <cstdio>
#include <vector>

#include <bulk/bulk.hpp>

#include "../examples/set_backend.hpp"
#include "fit.hpp"

using namespace std::chrono;

double flop_rate(bulk::world& world) {
    using clock = high_resolution_clock;

    unsigned int r_size = 10000000;
    std::vector<int> xs(r_size);
    std::iota(xs.begin(), xs.end(), 0);
    std::vector<int> ys = xs;
    std::vector<int> zs = xs;

    auto begin_time = clock::now();

    auto alpha = 1.0 / 3.0;
    auto beta = 4.0 / 9.0;
    for (auto i = 0u; i < r_size; ++i) {
        zs[i] = zs[i] + alpha * xs[i] - beta * ys[i];
    }

    auto end_time = clock::now();

    auto total_ms = duration<double, std::milli>(end_time - begin_time).count();
    auto flops = r_size * 4;

    auto flops_per_s = bulk::gather_all(world, 1000.0 * flops / total_ms);
    return bulk::average(flops_per_s.begin(), flops_per_s.end());
}

int main() {
    environment env;

    env.spawn(env.available_processors(), [](bulk::world& world, int s, int p) {
        assert(p > 0);

        using clock = high_resolution_clock;

        // about 4 MB
        unsigned int size = 1'000'000u;

        std::vector<int> dummy_data(size);
        std::iota(dummy_data.begin(), dummy_data.end(), 0);

        auto r = flop_rate(world);

        bulk::coarray<int> target(world, size);

        std::vector<size_t> test_sizes = {
            1'000u,   2'000u,   4'000u,    8'000u,   16'000u,
            32'000u,  64'000u,  100'000u,  128'000u, 200'000u,
            256'000u, 512'000u, 1'000'000u};
        std::vector<double> test_results;

        for (auto test_size : test_sizes) {
            double total = 0.0f;
            int sample_size = p > 8 ? 8 : p;
            for (auto k = 0; k < sample_size; ++k) {
                auto t = (world.next_processor() + p / sample_size) % p;

                auto begin_time = clock::now();

                target.put(t, dummy_data.begin(),
                           dummy_data.begin() + test_size);
                world.sync();

                auto end_time = clock::now();

                auto total_ms =
                    duration<double, std::milli>(end_time - begin_time).count();

                total += total_ms;
            }

            test_results.push_back(total / sample_size);
        }

        auto parameters = bulk::fit(test_sizes, test_results);
        if (parameters) {
            auto g = parameters.value().first * (r / 1000.0);
            auto l = parameters.value().second * (r / 1000.0);
            auto rs = bulk::gather_all(world, r / 1e9);
            auto gs = bulk::gather_all(world, g);
            auto ls = bulk::gather_all(world, l);

            if (s == 0) {
                world.log("> p = %i\n> r = %f GLOPS\n> l = %f FLOPs\n> g = %f "
                          "FLOPs",
                          p, bulk::average(rs.begin(), rs.end()),
                          bulk::average(gs.begin(), gs.end()),
                          bulk::average(ls.begin(), ls.end()));
            }
        }
    });

    return 0;
}
<commit_msg>Add more output to benchmark<commit_after>#include <chrono>
#include <cstdio>
#include <vector>

#include <bulk/bulk.hpp>

#include "../examples/set_backend.hpp"
#include "fit.hpp"

using namespace std::chrono;

double flop_rate(bulk::world& world) {
    using clock = high_resolution_clock;

    unsigned int r_size = 1 << 23;
    std::vector<int> xs(r_size);
    std::iota(xs.begin(), xs.end(), 0);
    std::vector<int> ys = xs;
    std::vector<int> zs = xs;

    auto begin_time = clock::now();

    auto alpha = 1.0 / 3.0;
    auto beta = 4.0 / 9.0;
    for (auto i = 0u; i < r_size; ++i) {
        zs[i] = zs[i] + alpha * xs[i] - beta * ys[i];
    }

    auto end_time = clock::now();

    auto total_ms = duration<double, std::milli>(end_time - begin_time).count();
    auto flops = r_size * 4;

    auto flops_per_s = bulk::gather_all(world, 1000.0 * flops / total_ms);
    return bulk::average(flops_per_s.begin(), flops_per_s.end());
}

int main() {
    environment env;

    env.spawn(env.available_processors(), [](bulk::world& world, int s, int p) {
        assert(p > 0);

        using clock = high_resolution_clock;

        // about 4 MB
        unsigned int size = 1'000'000u;

        std::vector<int> dummy_data(size);
        std::iota(dummy_data.begin(), dummy_data.end(), 0);

        auto r = flop_rate(world);

        bulk::coarray<int> target(world, size);

        std::vector<size_t> test_sizes = {
            1'000u,   2'000u,   4'000u,    8'000u,   16'000u,
            32'000u,  64'000u,  100'000u,  128'000u, 200'000u,
            256'000u, 512'000u, 1'000'000u};
        std::vector<double> test_results;

        for (auto test_size : test_sizes) {
            double total = 0.0f;
            int sample_size = p > 8 ? 8 : p;
            for (auto k = 0; k < sample_size; ++k) {
                auto t = (world.next_processor() + p / sample_size) % p;

                auto begin_time = clock::now();

                target.put(t, dummy_data.begin(),
                           dummy_data.begin() + test_size);
                world.sync();

                auto end_time = clock::now();

                auto total_ms =
                    duration<double, std::milli>(end_time - begin_time).count();

                total += total_ms;
            }

            test_results.push_back(total / sample_size);
        }

        auto parameters = bulk::fit(test_sizes, test_results);
        if (parameters) {
            auto g = parameters.value().first * (r / 1000.0);
            auto l = parameters.value().second * (r / 1000.0);
            auto rs = bulk::gather_all(world, r / 1e9);
            auto gs = bulk::gather_all(world, g);
            auto ls = bulk::gather_all(world, l);

            if (s == 0) {
                std::vector<double> durations;
                for (int i = 0; i < 100; ++i) {
                    auto a = clock::now();
                    auto b = clock::now();
                    durations.push_back(
                        duration<double, std::milli>(b - a).count() *
                        (r / 1000.0));
                }

                auto avg_r = bulk::average(rs.begin(), rs.end());
                world.log("> p = %i\n> r = %f GLOPS\n> l = %f FLOPs\n> g = %f "
                          "FLOPs\n> total = %f GLOPS\n> dt = %f FLOPs",
                          p, avg_r, bulk::average(gs.begin(), gs.end()),
                          bulk::average(ls.begin(), ls.end()), avg_r * p,
                          bulk::average(durations.begin(), durations.end()));
            }
        }
    });

    return 0;
}
<|endoftext|>


<commit_before>#include <benchmark/benchmark.h>
#include <cstdlib>
#include <string>
#include <algorithm>
#include <iterator>
#include <map>
#include <iostream>
#include "database.h"
#include "util.h"

using namespace naivedb;

static void Write(benchmark::State &state) {
    Database database(std::tmpnam(nullptr));
    const int KeySize = 16, ValueSize = 100;
    while (state.KeepRunning()) {
        for (int i = 0; i < state.range_x(); i++) {
            state.PauseTiming();
            const std::string key = generateRandomString(KeySize - 1), value = generateRandomString(ValueSize);
            state.ResumeTiming();

            database.set(key, value.c_str(), ValueSize, true);
        }
    }
    state.SetBytesProcessed((KeySize + ValueSize) * state.iterations() * state.range_x());
    state.SetItemsProcessed(state.iterations() * state.range_x());
}

static void Read(benchmark::State &state) {
    static bool setup = false;
    static Database database(std::tmpnam(nullptr));

    const int KeySize = 16, ValueSize = 100;
    static std::map<std::string ,std::string> items;

    if(!setup){

        for(int i = 0;i < 1000000; i++){
            const std::string key = generateRandomString(KeySize - 1), value = generateRandomString(ValueSize);
            items[key] = value;
            database.set(key, value.c_str(), ValueSize, true);
        }
        setup = true;
    }

    char buf[ValueSize];
    while(state.KeepRunning()) {
        for (int i = 0; i < state.range_x(); i++) {
            state.PauseTiming();
            auto it = items.begin();
            std::advance(it, rand() % items.size());
            const std::string key = it->first, value = it->second;
            state.ResumeTiming();

            database.get(key, buf);
        }
    }
    state.SetItemsProcessed(state.iterations() * state.range_x());
    state.SetBytesProcessed((KeySize+ValueSize) * state.iterations() * state.range_x());
}

static void Remove(benchmark::State &state) {

}

BENCHMARK(Write)->Range(2, 1<<20);
BENCHMARK(Read)->Range(2, 1<<20);

BENCHMARK_MAIN();<commit_msg>Optimize benchmark<commit_after>#include <benchmark/benchmark.h>
#include <cstdlib>
#include <string>
#include <algorithm>
#include <iterator>
#include <map>
#include <iostream>
#include "database.h"
#include "util.h"

using namespace naivedb;

static void Write(benchmark::State &state) {
    Database database(std::tmpnam(nullptr));
    const int KeySize = 16, ValueSize = 100;
    while (state.KeepRunning()) {
        for (int i = 0; i < state.range_x(); i++) {
            state.PauseTiming();
            const std::string key = generateRandomString(KeySize - 1), value = generateRandomString(ValueSize);
            state.ResumeTiming();

            database.set(key, value.c_str(), ValueSize, true);
        }
    }
    state.SetBytesProcessed((KeySize + ValueSize) * state.iterations() * state.range_x());
    state.SetItemsProcessed(state.iterations() * state.range_x());
}

static void Read(benchmark::State &state) {
    static bool setup = false;
    static Database database(std::tmpnam(nullptr));

    const int KeySize = 16, ValueSize = 100;
    static std::map<std::string ,std::string> items;
    static std::vector<std::string> keys;

    if(!setup){

        for(int i = 0;i < 1000000; i++){
            const std::string key = generateRandomString(KeySize - 1), value = generateRandomString(ValueSize);
            keys.push_back(key);
            items[key] = value;
            database.set(key, value.c_str(), ValueSize, true);
        }
        setup = true;
    }

    char buf[ValueSize];
    while(state.KeepRunning()) {
        for (int i = 0; i < state.range_x(); i++) {
            state.PauseTiming();
            std::string key = keys.at(std::rand()%keys.size());
            state.ResumeTiming();

            database.get(key, buf);
        }
    }
    state.SetItemsProcessed(state.iterations() * state.range_x());
    state.SetBytesProcessed((KeySize+ValueSize) * state.iterations() * state.range_x());
}

//BENCHMARK(Write)->Range(2, 1<<20);
BENCHMARK(Read)->Range(2, 1<<20);

BENCHMARK_MAIN();<|endoftext|>


<commit_before>#include "jazz.hpp"
#include "jazz_tablabel.hpp"
#include "jazz_sourceview.hpp"
#include <gtksourceview/gtksource.h>

namespace Jazz
{
	void JazzIDE::SetNewPageFont()
	{
		int pages = notebook.get_n_pages();

		if(pages > 1)
		{
			Gtk::Widget* page = notebook.get_nth_page(-1);

			Gtk::Widget* first_page = notebook.get_nth_page(1);

			if(auto scrld = dynamic_cast<Gtk::ScrolledWindow*>(page))
				page = scrld->get_child();

			if(auto scrld = dynamic_cast<Gtk::ScrolledWindow*>(first_page))
				first_page = scrld->get_child();

			auto context = first_page->get_pango_context();

			auto font_des = context->get_font_description();

			page->override_font(font_des);
		}
	}
	void JazzIDE::NewFile()
	{
		//SourceView sourceview;
		SourceView* source_view = Gtk::manage(new SourceView);

		//Gtk::Widget* sourceview_wrap = Glib::wrap(sourceview.gobj());

		TabLabel* tablabel = Gtk::manage(new TabLabel(*source_view)); //*sourceview_wrap));

		notebook.append_page(*source_view, *tablabel); //*sourceview_wrap, *tablabel);

		notebook.set_current_page(-1);

		SetNewPageFont();
	}
	void JazzIDE::OpenFile()
	{
		// Open a file or cancel it :P
		GtkWidget* dialog = gtk_file_chooser_dialog_new("Open File",
			GTK_WINDOW(gobj()), GTK_FILE_CHOOSER_ACTION_OPEN, "_Open",
			GTK_RESPONSE_ACCEPT, "_Cancel", GTK_RESPONSE_CANCEL, NULL);

		// If a user chose a file and selected "Open"
		if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
		{
			gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));

			// Pear down the name to just the short version of the filename eg. this.txt
			std::string shortname = "";
			std::string title = filename;
			if(title.find("/")!=std::string::npos)
				shortname = title.substr(title.find_last_of("/")+1);
			else
				shortname = title;

			// Create a new source view that is scrolled, then get the buffer
			//SourceView sourceview;
			SourceView* source_view = Gtk::manage(new SourceView);

			GtkSourceBuffer* buff = source_view->get_buffer(); //sourceview.get_buffer();

			// Create a new wrapper for the sourceview
			//Gtk::Widget* sourceview_wrap = Glib::wrap(sourceview.gobj());

			// Create a new tab label (box containing label and button) contains a
			// reference to the child the notebook has for it
			TabLabel* tablabel = Gtk::manage(new TabLabel(shortname, *source_view)); //*sourceview_wrap));

			// Add the two objects to the notebook
			notebook.append_page(*source_view, *tablabel); //*sourceview_wrap, *tablabel);

			// ----------------------------------------------------------
			// Open the file and load it with the sourcefileloader object
			// ----------------------------------------------------------
			GFile* new_file = g_file_new_for_path(filename);
			GtkSourceFile* new_source_file = gtk_source_file_new();

			gtk_source_file_set_location(new_source_file, new_file);

			GtkSourceFileLoader* loader = gtk_source_file_loader_new(
				buff, new_source_file);

			// Launch an async call to load the buffer with the contents of the file
			gtk_source_file_loader_load_async(
			loader, G_PRIORITY_DEFAULT, NULL, NULL, NULL,	NULL,
			// Function to 'finish' the loading routine
			[](GObject* source_obj, GAsyncResult* res, gpointer loader) -> void {
				GError* error = nullptr;
				gboolean success = gtk_source_file_loader_load_finish(
					(GtkSourceFileLoader*)loader, res, &error);
				if(success)
					puts("Successfully opened file");
				else
					printf("Failed to open file: %i, %s\n",
						error->code,error->message);
				},
				// Pass the loader as the user data, so that we can just keep
				// the lambda function as is
				(gpointer)loader);

			// Set the language of the source buffer for syntax highlighting
			auto s_lang = gtk_source_language_manager_guess_language(
				language_manager,
				filename,
				nullptr);

			gtk_source_buffer_set_language(GTK_SOURCE_BUFFER(buff), s_lang);

			// Free certain resources
			g_free( filename );
			g_object_unref(new_file);

			// Switch the the newly opened page
			notebook.set_current_page(-1);

			//Set the font of the newly opened page
			SetNewPageFont();

		}
		gtk_widget_destroy(dialog);
	}
	void JazzIDE::SaveFile()
	{
		GtkWidget* dialog = gtk_file_chooser_dialog_new("Save File",
			GTK_WINDOW(gobj()), GTK_FILE_CHOOSER_ACTION_SAVE, "_Save",
			GTK_RESPONSE_ACCEPT, "_Cancel", GTK_RESPONSE_CANCEL, NULL);
		if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
		{
			Gtk::Widget* page = notebook.get_nth_page(notebook.get_current_page());

			if(auto scrld = dynamic_cast<Gtk::ScrolledWindow*>(page))
			{
				page = scrld->get_child();
				puts("Scrolled Window");
				printf("Page new val: %p\n", page);
			}
			else
				puts("Text View");

			GtkSourceBuffer* s_buffer = GTK_SOURCE_BUFFER(
				static_cast<Gtk::TextView*>(page)->get_buffer()->gobj());

			gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER( dialog ));

			GFile* new_file = g_file_new_for_path(filename);

			GtkSourceFile* new_source_file = gtk_source_file_new();

			gtk_source_file_set_location(new_source_file, new_file);

			GtkSourceFileSaver* new_srcfile_saver = gtk_source_file_saver_new_with_target(
				s_buffer, new_source_file, new_file);

			puts("B4 the async launch");
			gtk_source_file_saver_save_async(
			new_srcfile_saver, G_PRIORITY_DEFAULT, NULL, NULL, NULL,	NULL,
			[](GObject* source_obj, GAsyncResult* res, gpointer new_srcfile_saver) -> void {
				GError* error = nullptr;
				puts("Ansync launch b4 finish call");
				gboolean success = gtk_source_file_saver_save_finish(
					(GtkSourceFileSaver*)new_srcfile_saver, res, &error);
				if(success)
					puts("Successfully saved file");
				else
					printf("Failed to save file: %i, %s\n",
						error->code,error->message);
				},
				// Pass the loader as the user data, so that we can just keep
				// the lambda function as is
				(gpointer)new_srcfile_saver);

			puts("After the async launch");

			std::string filenm = filename;

			std::string shortname = filenm.substr(filenm.find_last_of("/")+1);

			Gtk::Box* box = static_cast<Gtk::Box*>(notebook.get_tab_label(*page->get_parent()));

			Gtk::Label* label = static_cast<Gtk::Label*>(box->get_children()[0]);

			label->set_text(shortname);

			g_object_unref(new_file);
			g_free( filename );
		}
		gtk_widget_destroy(dialog);
	}
	void JazzIDE::Quit()
	{
		close();
	}
	void JazzIDE::ChooseFont()
	{
		int pages = notebook.get_n_pages();
		//Gtk::ScrolledWindow* page = static_cast<Gtk::ScrolledWindow *>(notebook.get_nth_page(notebook.get_current_page()));
		//Gtk::TextView* text_area = static_cast<Gtk::TextView*>(page->get_child());

		Gtk::FontChooserDialog dialog("Choose Font", *this);

		if(dialog.run() == Gtk::RESPONSE_OK)
		{
			Glib::ustring font_name = dialog.get_font();
			for(int i = 0; i < pages; i++)
			{
				Gtk::Widget* cur_page = notebook.get_nth_page(i);
				if(auto scrld = dynamic_cast<Gtk::ScrolledWindow*>(cur_page))
				{
					cur_page = scrld->get_child();
				}
				cur_page->override_font(Pango::FontDescription(font_name));
			}
		}
	}
}
<commit_msg>removed cruft<commit_after>#include "jazz.hpp"
#include "jazz_tablabel.hpp"
#include "jazz_sourceview.hpp"
#include <gtksourceview/gtksource.h>

namespace Jazz
{
	void JazzIDE::SetNewPageFont()
	{
		int pages = notebook.get_n_pages();

		if(pages > 1)
		{
			Gtk::Widget* page = notebook.get_nth_page(-1);

			Gtk::Widget* first_page = notebook.get_nth_page(1);

			if(auto scrld = dynamic_cast<Gtk::ScrolledWindow*>(page))
				page = scrld->get_child();

			if(auto scrld = dynamic_cast<Gtk::ScrolledWindow*>(first_page))
				first_page = scrld->get_child();

			auto context = first_page->get_pango_context();

			auto font_des = context->get_font_description();

			page->override_font(font_des);
		}
	}
	void JazzIDE::NewFile()
	{
		SourceView* source_view = Gtk::manage(new SourceView);

		TabLabel* tablabel = Gtk::manage(new TabLabel(*source_view));

		notebook.append_page(*source_view, *tablabel);

		notebook.set_current_page(-1);

		SetNewPageFont();
	}
	void JazzIDE::OpenFile()
	{
		// Open a file or cancel it :P
		GtkWidget* dialog = gtk_file_chooser_dialog_new("Open File",
			GTK_WINDOW(gobj()), GTK_FILE_CHOOSER_ACTION_OPEN, "_Open",
			GTK_RESPONSE_ACCEPT, "_Cancel", GTK_RESPONSE_CANCEL, NULL);

		// If a user chose a file and selected "Open"
		if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
		{
			gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));

			// Pear down the name to just the short version of the filename eg. this.txt
			std::string shortname = "";
			std::string title = filename;
			if(title.find("/")!=std::string::npos)
				shortname = title.substr(title.find_last_of("/")+1);
			else
				shortname = title;

			// Create a new source view that is scrolled, then get the buffer
			SourceView* source_view = Gtk::manage(new SourceView);

			GtkSourceBuffer* buff = source_view->get_buffer(); //sourceview.get_buffer();

			// Create a new tab label (box containing label and button) contains a
			// reference to the child the notebook has for it
			TabLabel* tablabel = Gtk::manage(new TabLabel(shortname, *source_view));

			// Add the two objects to the notebook
			notebook.append_page(*source_view, *tablabel);

			// ----------------------------------------------------------
			// Open the file and load it with the sourcefileloader object
			// ----------------------------------------------------------
			GFile* new_file = g_file_new_for_path(filename);
			GtkSourceFile* new_source_file = gtk_source_file_new();

			gtk_source_file_set_location(new_source_file, new_file);

			GtkSourceFileLoader* loader = gtk_source_file_loader_new(
				buff, new_source_file);

			// Launch an async call to load the buffer with the contents of the file
			gtk_source_file_loader_load_async(
			loader, G_PRIORITY_DEFAULT, NULL, NULL, NULL,	NULL,
			// Function to 'finish' the loading routine
			[](GObject* source_obj, GAsyncResult* res, gpointer loader) -> void {
				GError* error = nullptr;
				gboolean success = gtk_source_file_loader_load_finish(
					(GtkSourceFileLoader*)loader, res, &error);
				if(success)
					puts("Successfully opened file");
				else
					printf("Failed to open file: %i, %s\n",
						error->code,error->message);
				},
				// Pass the loader as the user data, so that we can just keep
				// the lambda function as is
				(gpointer)loader);

			// Set the language of the source buffer for syntax highlighting
			auto s_lang = gtk_source_language_manager_guess_language(
				language_manager,
				filename,
				nullptr);

			gtk_source_buffer_set_language(GTK_SOURCE_BUFFER(buff), s_lang);

			// Free certain resources
			g_free( filename );
			g_object_unref(new_file);

			// Switch the the newly opened page
			notebook.set_current_page(-1);

			//Set the font of the newly opened page
			SetNewPageFont();

		}
		gtk_widget_destroy(dialog);
	}
	void JazzIDE::SaveFile()
	{
		GtkWidget* dialog = gtk_file_chooser_dialog_new("Save File",
			GTK_WINDOW(gobj()), GTK_FILE_CHOOSER_ACTION_SAVE, "_Save",
			GTK_RESPONSE_ACCEPT, "_Cancel", GTK_RESPONSE_CANCEL, NULL);
		if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
		{
			Gtk::Widget* page = notebook.get_nth_page(notebook.get_current_page());

			if(auto scrld = dynamic_cast<Gtk::ScrolledWindow*>(page))
			{
				page = scrld->get_child();
				puts("Scrolled Window");
				printf("Page new val: %p\n", page);
			}
			else
				puts("Text View");

			GtkSourceBuffer* s_buffer = GTK_SOURCE_BUFFER(
				static_cast<Gtk::TextView*>(page)->get_buffer()->gobj());

			gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER( dialog ));

			GFile* new_file = g_file_new_for_path(filename);

			GtkSourceFile* new_source_file = gtk_source_file_new();

			gtk_source_file_set_location(new_source_file, new_file);

			GtkSourceFileSaver* new_srcfile_saver = gtk_source_file_saver_new_with_target(
				s_buffer, new_source_file, new_file);

			puts("B4 the async launch");
			gtk_source_file_saver_save_async(
			new_srcfile_saver, G_PRIORITY_DEFAULT, NULL, NULL, NULL,	NULL,
			[](GObject* source_obj, GAsyncResult* res, gpointer new_srcfile_saver) -> void {
				GError* error = nullptr;
				puts("Ansync launch b4 finish call");
				gboolean success = gtk_source_file_saver_save_finish(
					(GtkSourceFileSaver*)new_srcfile_saver, res, &error);
				if(success)
					puts("Successfully saved file");
				else
					printf("Failed to save file: %i, %s\n",
						error->code,error->message);
				},
				// Pass the loader as the user data, so that we can just keep
				// the lambda function as is
				(gpointer)new_srcfile_saver);

			puts("After the async launch");

			std::string filenm = filename;

			std::string shortname = filenm.substr(filenm.find_last_of("/")+1);

			Gtk::Box* box = static_cast<Gtk::Box*>(notebook.get_tab_label(*page->get_parent()));

			Gtk::Label* label = static_cast<Gtk::Label*>(box->get_children()[0]);

			label->set_text(shortname);

			g_object_unref(new_file);
			g_free( filename );
		}
		gtk_widget_destroy(dialog);
	}
	void JazzIDE::Quit()
	{
		close();
	}
	void JazzIDE::ChooseFont()
	{
		int pages = notebook.get_n_pages();

		Gtk::FontChooserDialog dialog("Choose Font", *this);

		if(dialog.run() == Gtk::RESPONSE_OK)
		{
			Glib::ustring font_name = dialog.get_font();
			for(int i = 0; i < pages; i++)
			{
				Gtk::Widget* cur_page = notebook.get_nth_page(i);
				if(auto scrld = dynamic_cast<Gtk::ScrolledWindow*>(cur_page))
				{
					cur_page = scrld->get_child();
				}
				cur_page->override_font(Pango::FontDescription(font_name));
			}
		}
	}
}
<|endoftext|>


<commit_before>/* File: e8simple.cpp
 * Author: Chris Dellin <cdellin@gmail.com>
 * Copyright: 2015 Carnegie Mellon University
 * License: BSD
 */

#include <boost/chrono.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/graph/adjacency_list.hpp>

#include <ompl/base/ScopedState.h>
#include <ompl/base/spaces/RealVectorStateSpace.h>
#include <ompl/base/SpaceInformation.h>
#include <ompl/base/ProblemDefinition.h>
#include <ompl/base/Planner.h>
#include <ompl/geometric/PathGeometric.h>
#include <ompl/datastructures/NearestNeighbors.h>

#include <pr_bgl/compose_property_map.hpp>
#include <pr_bgl/edge_indexed_graph.h>
#include <pr_bgl/heap_indexed.h>
#include <pr_bgl/string_map.h>
#include <pr_bgl/overlay_manager.h>
#include <ompl_multiset/util.h>
#include <ompl_multiset/BisectPerm.h>
#include <ompl_multiset/Roadmap.h>
#include <ompl_multiset/EffortModel.h>
#include <ompl_multiset/E8Roadmap.h>
#include <ompl_multiset/Family.h>
#include <ompl_multiset/FamilyEffortModel.h>
#include <ompl_multiset/RoadmapHalton.h>

#include <gtest/gtest.h>

class CountingRealVectorStateSpace: public ompl::base::RealVectorStateSpace
{
public:
   mutable unsigned int states_allocated;
   mutable unsigned int states_freed;
   CountingRealVectorStateSpace(unsigned int dim = 0):
      ompl::base::RealVectorStateSpace(dim),
      states_allocated(0), states_freed(0)
   {
   }
   virtual ~CountingRealVectorStateSpace()
   {
   }
   virtual ompl::base::State * allocState() const
   {
      states_allocated++;
      return ompl::base::RealVectorStateSpace::allocState();
   }
   virtual void freeState(ompl::base::State * state) const
   {
      states_freed++;
      ompl::base::RealVectorStateSpace::freeState(state);
   }
};

bool isvalid(const ompl::base::State * state)
{
   double * values = state->as<
      ompl::base::RealVectorStateSpace::StateType>()->values;
   if (values[0] < 0.5 && values[1] < 0.5)
      return false;
   else
      return true;
}

ompl::base::ScopedState<ompl::base::RealVectorStateSpace>
make_state(const ompl::base::StateSpacePtr space, double x, double y)
{
   ompl::base::ScopedState<ompl::base::RealVectorStateSpace>
      state(space);
   double * values = state->as<
      ompl::base::RealVectorStateSpace::StateType>()->values;
   values[0] = x;
   values[1] = y;
   return state;
}

ompl::base::ScopedState<ompl::base::RealVectorStateSpace>
get_path_state(boost::shared_ptr<ompl::geometric::PathGeometric> path, size_t idx)
{
   ompl::base::StateSpacePtr space = path->getSpaceInformation()->getStateSpace();
   ompl::base::ScopedState<ompl::base::RealVectorStateSpace>
      traj_state(space, path->getState(idx));
   return traj_state;
}

TEST(E8SimpleTestCase, E8SimpleTest)
{
   // state space
   boost::shared_ptr<ompl::base::RealVectorStateSpace> space(
      new CountingRealVectorStateSpace(2));
   space->setBounds(0.0, 1.0);
   space->setLongestValidSegmentFraction(
      0.001 / space->getMaximumExtent());
   space->setup();

   // space info
   ompl::base::SpaceInformationPtr si(
      new ompl::base::SpaceInformation(space));
   si->setStateValidityChecker(isvalid);
   si->setup();

   // problem definition
   ompl::base::ProblemDefinitionPtr pdef(
      new ompl::base::ProblemDefinition(si));
   pdef->addStartState(make_state(space, 0.25, 0.75));
   pdef->setGoalState(make_state(space, 0.75, 0.25));

   // roadmap
   ompl_multiset::E8Roadmap::RoadmapPtr roadmap_gen(
      new ompl_multiset::RoadmapHalton<ompl_multiset::E8Roadmap::Roadmap>(
      space, 30, 0.3));

   // family
   ompl_multiset::Family family;
   family.subsets.insert(std::make_pair("space_si",
      ompl_multiset::Family::Subset(si, space->getLongestValidSegmentLength())));
   ompl_multiset::FamilyEffortModel fem(family);
   fem.set_target(si);

   // cache
   ompl_multiset::DummyTagCache<ompl_multiset::E8Roadmap::VIdxTagMap,ompl_multiset::E8Roadmap::EIdxTagsMap> tag_cache;

   // planner
   ompl::base::PlannerPtr planner(new ompl_multiset::E8Roadmap(space, fem, tag_cache, roadmap_gen));
   planner->as<ompl_multiset::E8Roadmap>()->setCoeffDistance(1.);
   planner->as<ompl_multiset::E8Roadmap>()->setCoeffCheckcost(0.);
   planner->as<ompl_multiset::E8Roadmap>()->setCoeffBatch(0.);

   // solve
   planner->setProblemDefinition(pdef);
   ompl::base::PlannerStatus status = planner->solve(
      ompl::base::plannerNonTerminatingCondition());
   ASSERT_EQ(status, ompl::base::PlannerStatus::EXACT_SOLUTION);

   // check resulting path
   boost::shared_ptr<ompl::geometric::PathGeometric> path =
      boost::dynamic_pointer_cast<ompl::geometric::PathGeometric>(
      pdef->getSolutionPath());
   ASSERT_TRUE(path);
   ASSERT_EQ(4, path->getStateCount());
   ASSERT_EQ(make_state(space, 0.25, 0.75),       get_path_state(path,0));
   ASSERT_EQ(make_state(space, 0.40625, 14./27.), get_path_state(path,1));
   ASSERT_EQ(make_state(space, 0.68750, 13./27.), get_path_state(path,2));
   ASSERT_EQ(make_state(space, 0.75, 0.25),       get_path_state(path,3));

   pdef.reset();
   planner.reset();
   path.reset();
   ASSERT_EQ(24713, space->as<CountingRealVectorStateSpace>()->states_allocated);
   ASSERT_EQ(24713, space->as<CountingRealVectorStateSpace>()->states_freed);
}

int main(int argc, char **argv)
{
   testing::InitGoogleTest(&argc, argv);
   return RUN_ALL_TESTS();
}
<commit_msg>update test for lazy edge state generation<commit_after>/* File: e8simple.cpp
 * Author: Chris Dellin <cdellin@gmail.com>
 * Copyright: 2015 Carnegie Mellon University
 * License: BSD
 */

#include <boost/chrono.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/graph/adjacency_list.hpp>

#include <ompl/base/ScopedState.h>
#include <ompl/base/spaces/RealVectorStateSpace.h>
#include <ompl/base/SpaceInformation.h>
#include <ompl/base/ProblemDefinition.h>
#include <ompl/base/Planner.h>
#include <ompl/geometric/PathGeometric.h>
#include <ompl/datastructures/NearestNeighbors.h>

#include <pr_bgl/compose_property_map.hpp>
#include <pr_bgl/edge_indexed_graph.h>
#include <pr_bgl/heap_indexed.h>
#include <pr_bgl/string_map.h>
#include <pr_bgl/overlay_manager.h>
#include <ompl_multiset/util.h>
#include <ompl_multiset/BisectPerm.h>
#include <ompl_multiset/Roadmap.h>
#include <ompl_multiset/EffortModel.h>
#include <ompl_multiset/E8Roadmap.h>
#include <ompl_multiset/Family.h>
#include <ompl_multiset/FamilyEffortModel.h>
#include <ompl_multiset/RoadmapHalton.h>

#include <gtest/gtest.h>

class CountingRealVectorStateSpace: public ompl::base::RealVectorStateSpace
{
public:
   mutable unsigned int states_allocated;
   mutable unsigned int states_freed;
   CountingRealVectorStateSpace(unsigned int dim = 0):
      ompl::base::RealVectorStateSpace(dim),
      states_allocated(0), states_freed(0)
   {
   }
   virtual ~CountingRealVectorStateSpace()
   {
   }
   virtual ompl::base::State * allocState() const
   {
      states_allocated++;
      return ompl::base::RealVectorStateSpace::allocState();
   }
   virtual void freeState(ompl::base::State * state) const
   {
      states_freed++;
      ompl::base::RealVectorStateSpace::freeState(state);
   }
};

bool isvalid(const ompl::base::State * state)
{
   double * values = state->as<
      ompl::base::RealVectorStateSpace::StateType>()->values;
   if (values[0] < 0.5 && values[1] < 0.5)
      return false;
   else
      return true;
}

ompl::base::ScopedState<ompl::base::RealVectorStateSpace>
make_state(const ompl::base::StateSpacePtr space, double x, double y)
{
   ompl::base::ScopedState<ompl::base::RealVectorStateSpace>
      state(space);
   double * values = state->as<
      ompl::base::RealVectorStateSpace::StateType>()->values;
   values[0] = x;
   values[1] = y;
   return state;
}

ompl::base::ScopedState<ompl::base::RealVectorStateSpace>
get_path_state(boost::shared_ptr<ompl::geometric::PathGeometric> path, size_t idx)
{
   ompl::base::StateSpacePtr space = path->getSpaceInformation()->getStateSpace();
   ompl::base::ScopedState<ompl::base::RealVectorStateSpace>
      traj_state(space, path->getState(idx));
   return traj_state;
}

TEST(E8SimpleTestCase, E8SimpleTest)
{
   // state space
   boost::shared_ptr<ompl::base::RealVectorStateSpace> space(
      new CountingRealVectorStateSpace(2));
   space->setBounds(0.0, 1.0);
   space->setLongestValidSegmentFraction(
      0.001 / space->getMaximumExtent());
   space->setup();

   // space info
   ompl::base::SpaceInformationPtr si(
      new ompl::base::SpaceInformation(space));
   si->setStateValidityChecker(isvalid);
   si->setup();

   // problem definition
   ompl::base::ProblemDefinitionPtr pdef(
      new ompl::base::ProblemDefinition(si));
   pdef->addStartState(make_state(space, 0.25, 0.75));
   pdef->setGoalState(make_state(space, 0.75, 0.25));

   // roadmap
   ompl_multiset::E8Roadmap::RoadmapPtr roadmap_gen(
      new ompl_multiset::RoadmapHalton<ompl_multiset::E8Roadmap::Roadmap>(
      space, 30, 0.3));

   // family
   ompl_multiset::Family family;
   family.subsets.insert(std::make_pair("space_si",
      ompl_multiset::Family::Subset(si, space->getLongestValidSegmentLength())));
   ompl_multiset::FamilyEffortModel fem(family);
   fem.set_target(si);

   // cache
   ompl_multiset::DummyTagCache<ompl_multiset::E8Roadmap::VIdxTagMap,ompl_multiset::E8Roadmap::EIdxTagsMap> tag_cache;

   // planner
   ompl::base::PlannerPtr planner(new ompl_multiset::E8Roadmap(space, fem, tag_cache, roadmap_gen));
   planner->as<ompl_multiset::E8Roadmap>()->setCoeffDistance(1.);
   planner->as<ompl_multiset::E8Roadmap>()->setCoeffCheckcost(0.);
   planner->as<ompl_multiset::E8Roadmap>()->setCoeffBatch(0.);

   // solve
   planner->setProblemDefinition(pdef);
   ompl::base::PlannerStatus status = planner->solve(
      ompl::base::plannerNonTerminatingCondition());
   ASSERT_EQ(status, ompl::base::PlannerStatus::EXACT_SOLUTION);

   // check resulting path
   boost::shared_ptr<ompl::geometric::PathGeometric> path =
      boost::dynamic_pointer_cast<ompl::geometric::PathGeometric>(
      pdef->getSolutionPath());
   ASSERT_TRUE(path);
   ASSERT_EQ(4, path->getStateCount());
   ASSERT_EQ(make_state(space, 0.25, 0.75),       get_path_state(path,0));
   ASSERT_EQ(make_state(space, 0.40625, 14./27.), get_path_state(path,1));
   ASSERT_EQ(make_state(space, 0.68750, 13./27.), get_path_state(path,2));
   ASSERT_EQ(make_state(space, 0.75, 0.25),       get_path_state(path,3));

   pdef.reset();
   planner.reset();
   path.reset();
   ASSERT_EQ(1324, space->as<CountingRealVectorStateSpace>()->states_allocated);
   ASSERT_EQ(1324, space->as<CountingRealVectorStateSpace>()->states_freed);
}

int main(int argc, char **argv)
{
   testing::InitGoogleTest(&argc, argv);
   return RUN_ALL_TESTS();
}
<|endoftext|>


<commit_before>#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/IR/LegacyPassManager.h"

#include "AnnotationInfo.h"

using namespace llvm;

namespace {

struct NullChecks : public FunctionPass {
  static char ID;
  NullChecks() : FunctionPass(ID) {}

  virtual void getAnalysisUsage(AnalysisUsage &Info) const {
    Info.addRequired<AnnotationInfo>();
  }

  virtual bool runOnFunction(Function &F) {
    AnnotationInfo &AI = getAnalysis<AnnotationInfo>();
    bool modified = false;

    for (auto &BB : F) {
      for (auto &I : BB) {
        // Is this a load or store? Get the address.
        Value *Ptr = nullptr;
        if (auto *LI = dyn_cast<LoadInst>(&I)) {
          Ptr = LI->getPointerOperand();
        } else if (auto *SI = dyn_cast<StoreInst>(&I)) {
          Ptr = SI->getPointerOperand();
        }

        // Dereferencing a pointer (either for a load or a store). Insert a
        // check if the pointer is nullable.
        if (Ptr) {
          if (AI.hasAnnotation(Ptr, "nullable")) {
            addCheck(*Ptr, I);
            modified = true;
          }
        }
      }
    }

    return modified;
  }

  Function &getCheckFunc(Module &M) {
    LLVMContext &Ctx = M.getContext();

    // Get or add the declaration.
    Constant *C = M.getOrInsertFunction("qualaNullCheck",
        Type::getVoidTy(Ctx), Type::getInt1Ty(Ctx), NULL);
    auto *F = cast<Function>(C);

    // If the function does not have a body yet, write it.
    if (F->empty()) {
      BasicBlock *Entry = BasicBlock::Create(Ctx, "entry", F);
      BasicBlock *Success = BasicBlock::Create(Ctx, "success", F);
      BasicBlock *Failure = BasicBlock::Create(Ctx, "failure", F);

      // Check block.
      Value *isnull = F->arg_begin();
      IRBuilder<> Bld(Entry);
      Bld.CreateCondBr(isnull, Failure, Success);

      // Success (non-null) block.
      Bld.SetInsertPoint(Success);
      Bld.CreateRetVoid();

      // Failure (null) block.
      Bld.SetInsertPoint(Failure);

      // Call perror(3).
      Constant *Perror = M.getOrInsertFunction("perror",
          Type::getVoidTy(Ctx), Type::getInt8PtrTy(Ctx), NULL);
      Value *MsgStr = Bld.CreateGlobalStringPtr(
          "about to dereference null", "errmsg");
      Bld.CreateCall(Perror, MsgStr);

      // Call exit(3).
      AttributeSet Attrs;
      Attrs.addAttribute(Ctx, AttributeSet::FunctionIndex,
          Attribute::NoReturn);
      Constant *Exit = M.getOrInsertFunction("exit", Attrs,
          Type::getVoidTy(Ctx), Type::getInt32Ty(Ctx), NULL);
      Bld.CreateCall(Exit, Bld.getInt32(1));

      // Terminate the failure block.
      Bld.CreateUnreachable();
    }

    return *F;
  }

  // Insert a null check for the given pointer value just before the
  // instruction.
  void addCheck(Value &Ptr, Instruction &I) {
    IRBuilder<> Bld(&I);
    Value *isnull = Bld.CreateIsNull(&Ptr, "isnull");
    Module *M = I.getParent()->getParent()->getParent();
    Bld.CreateCall(&(getCheckFunc(*M)), isnull);
  }
};

}

char NullChecks::ID = 0;

// http://homes.cs.washington.edu/~asampson/blog/clangpass.html
static void registerPass(const PassManagerBuilder &,
                         legacy::PassManagerBase &PM) {
  PM.add(new NullChecks());
}
static RegisterStandardPasses
  RegisterMyPass(PassManagerBuilder::EP_EarlyAsPossible,
                 registerPass);
<commit_msg>Invoke user handler<commit_after>#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/IR/LegacyPassManager.h"

#include "AnnotationInfo.h"

using namespace llvm;

namespace {

struct NullChecks : public FunctionPass {
  static char ID;
  NullChecks() : FunctionPass(ID) {}

  virtual void getAnalysisUsage(AnalysisUsage &Info) const {
    Info.addRequired<AnnotationInfo>();
  }

  virtual bool runOnFunction(Function &F) {
    AnnotationInfo &AI = getAnalysis<AnnotationInfo>();
    bool modified = false;

    for (auto &BB : F) {
      for (auto &I : BB) {
        // Is this a load or store? Get the address.
        Value *Ptr = nullptr;
        if (auto *LI = dyn_cast<LoadInst>(&I)) {
          Ptr = LI->getPointerOperand();
        } else if (auto *SI = dyn_cast<StoreInst>(&I)) {
          Ptr = SI->getPointerOperand();
        }

        // Dereferencing a pointer (either for a load or a store). Insert a
        // check if the pointer is nullable.
        if (Ptr) {
          if (AI.hasAnnotation(Ptr, "nullable")) {
            addCheck(*Ptr, I);
            modified = true;
          }
        }
      }
    }

    return modified;
  }

  Function &getCheckFunc(Module &M) {
    LLVMContext &Ctx = M.getContext();

    // Get or add the declaration.
    Constant *C = M.getOrInsertFunction("qualaNullCheck",
        Type::getVoidTy(Ctx), Type::getInt1Ty(Ctx), NULL);
    auto *F = cast<Function>(C);

    // If the function does not have a body yet, write it.
    if (F->empty()) {
      BasicBlock *Entry = BasicBlock::Create(Ctx, "entry", F);
      BasicBlock *Success = BasicBlock::Create(Ctx, "success", F);
      BasicBlock *Failure = BasicBlock::Create(Ctx, "failure", F);

      // Check block.
      Value *isnull = F->arg_begin();
      IRBuilder<> Bld(Entry);
      Bld.CreateCondBr(isnull, Failure, Success);

      // Success (non-null) block.
      Bld.SetInsertPoint(Success);
      Bld.CreateRetVoid();

      // Failure (null) block. If there's a funciton in the module to handle
      // this, call it. Otherwise, call exit(3).
      Bld.SetInsertPoint(Failure);
      if (Function *Handler = M.getFunction("qualaHandleNull")) {
        // Call the user's handler.
        Bld.CreateCall(Handler);
        Bld.CreateRetVoid();
      } else {
        // Call exit(3).
        AttributeSet Attrs;
        Attrs.addAttribute(Ctx, AttributeSet::FunctionIndex,
            Attribute::NoReturn);
        Constant *Exit = M.getOrInsertFunction("exit", Attrs,
            Type::getVoidTy(Ctx), Type::getInt32Ty(Ctx), NULL);
        Bld.CreateCall(Exit, Bld.getInt32(1));
        Bld.CreateUnreachable();
      }
    }

    return *F;
  }

  // Insert a null check for the given pointer value just before the
  // instruction.
  void addCheck(Value &Ptr, Instruction &I) {
    IRBuilder<> Bld(&I);
    Value *isnull = Bld.CreateIsNull(&Ptr, "isnull");
    Module *M = I.getParent()->getParent()->getParent();
    Bld.CreateCall(&(getCheckFunc(*M)), isnull);
  }
};

}

char NullChecks::ID = 0;

// http://homes.cs.washington.edu/~asampson/blog/clangpass.html
static void registerPass(const PassManagerBuilder &,
                         legacy::PassManagerBase &PM) {
  PM.add(new NullChecks());
}
static RegisterStandardPasses
  RegisterMyPass(PassManagerBuilder::EP_EarlyAsPossible,
                 registerPass);
<|endoftext|>