<commit_before>#include <limits>
#include <cgo/minimax/minimax_agent.hpp>

using namespace cgo::base;
using namespace cgo::minimax;

MiniMaxAgent::MiniMaxAgent(Marker marker) :
   Agent(marker), _turnNumber(0)
{}

/* virtual */ MiniMaxAgent::~MiniMaxAgent() {}

Move MiniMaxAgent::makeMove(State& state,
 const boost::optional< Predecessor >& predecessor) {
   int alpha = std::numeric_limits<int>::min();
   int beta = std::numeric_limits<int>::max();
   int depth;

   if (this->_turnNumber < 5) {
      depth = 2;
   } else if (this->_turnNumber < 10) {
      depth = 3;
   } else if (this->_turnNumber < 15) {
      depth = 4;
   } else if (this->_turnNumber < 20) {
      depth = 5;
   } else {
      depth = 6;
   }

   ++this->_turnNumber;

   auto maxMoveValue = this->mmAbMax(state, predecessor, alpha, beta, depth);

   return std::get<0>(maxMoveValue);
}

std::tuple< Move, int > MiniMaxAgent::mmAbMax(State& state,
 const boost::optional< Predecessor >& predecessor, int alpha, int beta,
 int depth) {
   Move maxMove = Pass();
   int maxValue = this->utility(maxMove, state);

   if (predecessor) {
      auto predecessorValue = predecessor.get();
      Move predMove = std::get<0>(predecessorValue);
      const Pass* pass = boost::get< Pass >(&predMove);
      if ((pass != nullptr) && (maxValue > 0)) {
         return std::make_tuple(Pass(), maxValue);
      }
   }

   std::vector< Successor > successors =
    state.getSuccessors(this->_marker, predecessor);

   if (depth == 0) {
      if (successors.size() > 0) {
         Move chosenMove = std::get<0>(successors[0]);
         int chosenScore = std::numeric_limits<int>::min();

         for (auto successor : successors) {
            auto succMove = std::get<0>(successor);
            auto succState = std::get<1>(successor);
            int succScore = this->utility(succMove, succState);

            if (succScore > chosenScore) {
               chosenMove = succMove;
               chosenScore = succScore;
            }
         }

         return std::make_tuple(chosenMove, chosenScore);
      } else {
         return std::make_tuple(maxMove, maxValue);
      }
   }

   for (auto successor : successors) {
      auto succMove = std::get<0>(successor);
      auto succState = std::get<1>(successor);

      auto minMoveValue = this->mmAbMin(succState, successor, alpha, beta,
       depth - 1);
      auto minMove = std::get<0>(minMoveValue);
      auto minValue = std::get<1>(minMoveValue);
      if (minValue > maxValue) {
         maxMove = minMove;
         maxValue = minValue;
      }

      if (maxValue >= beta) {
         return std::make_tuple(maxMove, maxValue);
      }

      if (alpha < maxValue) {
         alpha = maxValue;
         maxMove = succMove;
      }
   }

   return std::make_tuple(maxMove, maxValue);
}

std::tuple< Move, int > MiniMaxAgent::mmAbMin(State& state,
 const boost::optional< Predecessor >& predecessor, int alpha, int beta,
 int depth) {
   Move minMove = Pass();
   int minValue = this->utility(minMove, state);

   if (predecessor) {
      auto predecessorValue = predecessor.get();
      Move predMove = std::get<0>(predecessorValue);
      const Pass* pass = boost::get< Pass >(&predMove);
      if ((pass != nullptr) && (minValue < 0)) {
         return std::make_tuple(Pass(), minValue);
      }
   }

   std::vector< Successor > successors =
    state.getSuccessors(this->_marker, predecessor);
   if (depth == 0) {
      if (successors.size() > 0) {
         Move chosenMove = std::get<0>(successors[0]);
         int chosenScore = std::numeric_limits<int>::max();

         for (auto successor : successors) {
            auto succMove = std::get<0>(successor);
            auto succState = std::get<1>(successor);
            int succScore = this->utility(succMove, succState);

            if (succScore < chosenScore) {
               chosenMove = succMove;
               chosenScore = succScore;
            }
         }

         return std::make_tuple(chosenMove, chosenScore);
      } else {
         return std::make_tuple(minMove, minValue);
      }
   }

   for (auto successor : successors) {
      auto succMove = std::get<0>(successor);
      auto succState = std::get<1>(successor);

      auto maxMoveValue = this->mmAbMax(succState, successor, alpha, beta,
       depth - 1);
      auto maxMove = std::get<0>(maxMoveValue);
      auto maxValue = std::get<1>(maxMoveValue);
      if (maxValue < minValue) {
         minMove = maxMove;
         minValue = maxValue;
      }

      if (minValue <= beta) {
         return std::make_tuple(minMove, minValue);
      }

      if (beta > minValue) {
         beta = minValue;
         minMove = succMove;
      }
   }

   return std::make_tuple(minMove, minValue);
}

std::tuple< int, int > MiniMaxAgent::edgeCosts(const Board& board) {
   int whiteCost = 0;
   int blackCost = 0;

   for (int ndx = 0; ndx < BOARD_DIMENSION; ++ndx) {
      Marker rowMarker1 = board[State::getIndex(Position(ndx, 0))];
      Marker rowMarker2 = board[State::getIndex(Position(ndx, BOARD_DIMENSION - 1))];
      Marker colMarker1 = board[State::getIndex(Position(0, ndx))];
      Marker colMarker2 = board[State::getIndex(Position(BOARD_DIMENSION - 1, ndx))];

      if (rowMarker1 == white) {
         ++whiteCost;
      }
      if (rowMarker2 == white) {
         ++whiteCost;
      }
      if (colMarker1 == white) {
         ++whiteCost;
      }
      if (colMarker2 == white) {
         ++whiteCost;
      }

      if (rowMarker1 == black) {
         ++blackCost;
      }
      if (rowMarker2 == black) {
         ++blackCost;
      }
      if (colMarker1 == black) {
         ++blackCost;
      }
      if (colMarker2 == black) {
         ++blackCost;
      }
   }

   return std::make_tuple(whiteCost, blackCost);
}

int MiniMaxAgent::utility(const Move& move, const State& state) {
   static const int scoreWeight = 1000;
   static const int edgeWeight = 10;
   static const int passWeight = 1;

   auto scores = state.getScores();
   int scoreValue = std::get<0>(scores) - std::get<1>(scores);

   auto edgeCosts = MiniMaxAgent::edgeCosts(state.getBoard());
   int edgeValue = (this->_marker == white) ? -std::get<0>(edgeCosts) :
    std::get<1>(edgeCosts);

   int passValue = 0;
   const Pass* pass = boost::get< Pass >(&move);
   if (pass != nullptr) {
      passValue = (this->_marker == white) ? 1 : -1;
   }

   int totalValue = scoreWeight * scoreValue + edgeWeight * edgeValue +
    passWeight * passValue;

   return (this->_marker == white) ? totalValue : -totalValue;
}
<commit_msg>MiniMax: make a good first move<commit_after>#include <limits>
#include <cmath>
#include <cgo/minimax/minimax_agent.hpp>

using namespace cgo::base;
using namespace cgo::minimax;

MiniMaxAgent::MiniMaxAgent(Marker marker) :
   Agent(marker), _turnNumber(0)
{}

/* virtual */ MiniMaxAgent::~MiniMaxAgent() {}

Move MiniMaxAgent::makeMove(State& state,
 const boost::optional< Predecessor >& predecessor) {
   if (this->_turnNumber == 0) {
      ++this->_turnNumber;

      const int crucialPoint = std::ceil(BOARD_DIMENSION / 3.0f) - 1;

      Position p1(crucialPoint, crucialPoint);
      if (state.getBoard()[State::getIndex(p1)] == none) {
         return Action(this->_marker, p1);
      }

      Position p2(crucialPoint, (BOARD_DIMENSION - 1) - crucialPoint);
      return Action(this->_marker, p2);
   }

   int alpha = std::numeric_limits<int>::min();
   int beta = std::numeric_limits<int>::max();
   int depth;

   if (this->_turnNumber < 5) {
      depth = 2;
   } else if (this->_turnNumber < 10) {
      depth = 3;
   } else if (this->_turnNumber < 15) {
      depth = 4;
   } else if (this->_turnNumber < 20) {
      depth = 5;
   } else {
      depth = 6;
   }

   ++this->_turnNumber;

   auto maxMoveValue = this->mmAbMax(state, predecessor, alpha, beta, depth);

   return std::get<0>(maxMoveValue);
}

std::tuple< Move, int > MiniMaxAgent::mmAbMax(State& state,
 const boost::optional< Predecessor >& predecessor, int alpha, int beta,
 int depth) {
   Move maxMove = Pass();
   int maxValue = this->utility(maxMove, state);

   if (predecessor) {
      auto predecessorValue = predecessor.get();
      Move predMove = std::get<0>(predecessorValue);
      const Pass* pass = boost::get< Pass >(&predMove);
      if ((pass != nullptr) && (maxValue > 0)) {
         return std::make_tuple(Pass(), maxValue);
      }
   }

   std::vector< Successor > successors =
    state.getSuccessors(this->_marker, predecessor);

   if (depth == 0) {
      if (successors.size() > 0) {
         Move chosenMove = std::get<0>(successors[0]);
         int chosenScore = std::numeric_limits<int>::min();

         for (auto successor : successors) {
            auto succMove = std::get<0>(successor);
            auto succState = std::get<1>(successor);
            int succScore = this->utility(succMove, succState);

            if (succScore > chosenScore) {
               chosenMove = succMove;
               chosenScore = succScore;
            }
         }

         return std::make_tuple(chosenMove, chosenScore);
      } else {
         return std::make_tuple(maxMove, maxValue);
      }
   }

   for (auto successor : successors) {
      auto succMove = std::get<0>(successor);
      auto succState = std::get<1>(successor);

      auto minMoveValue = this->mmAbMin(succState, successor, alpha, beta,
       depth - 1);
      auto minMove = std::get<0>(minMoveValue);
      auto minValue = std::get<1>(minMoveValue);
      if (minValue > maxValue) {
         maxMove = minMove;
         maxValue = minValue;
      }

      if (maxValue >= beta) {
         return std::make_tuple(maxMove, maxValue);
      }

      if (alpha < maxValue) {
         alpha = maxValue;
         maxMove = succMove;
      }
   }

   return std::make_tuple(maxMove, maxValue);
}

std::tuple< Move, int > MiniMaxAgent::mmAbMin(State& state,
 const boost::optional< Predecessor >& predecessor, int alpha, int beta,
 int depth) {
   Move minMove = Pass();
   int minValue = this->utility(minMove, state);

   if (predecessor) {
      auto predecessorValue = predecessor.get();
      Move predMove = std::get<0>(predecessorValue);
      const Pass* pass = boost::get< Pass >(&predMove);
      if ((pass != nullptr) && (minValue < 0)) {
         return std::make_tuple(Pass(), minValue);
      }
   }

   std::vector< Successor > successors =
    state.getSuccessors(this->_marker, predecessor);
   if (depth == 0) {
      if (successors.size() > 0) {
         Move chosenMove = std::get<0>(successors[0]);
         int chosenScore = std::numeric_limits<int>::max();

         for (auto successor : successors) {
            auto succMove = std::get<0>(successor);
            auto succState = std::get<1>(successor);
            int succScore = this->utility(succMove, succState);

            if (succScore < chosenScore) {
               chosenMove = succMove;
               chosenScore = succScore;
            }
         }

         return std::make_tuple(chosenMove, chosenScore);
      } else {
         return std::make_tuple(minMove, minValue);
      }
   }

   for (auto successor : successors) {
      auto succMove = std::get<0>(successor);
      auto succState = std::get<1>(successor);

      auto maxMoveValue = this->mmAbMax(succState, successor, alpha, beta,
       depth - 1);
      auto maxMove = std::get<0>(maxMoveValue);
      auto maxValue = std::get<1>(maxMoveValue);
      if (maxValue < minValue) {
         minMove = maxMove;
         minValue = maxValue;
      }

      if (minValue <= beta) {
         return std::make_tuple(minMove, minValue);
      }

      if (beta > minValue) {
         beta = minValue;
         minMove = succMove;
      }
   }

   return std::make_tuple(minMove, minValue);
}

std::tuple< int, int > MiniMaxAgent::edgeCosts(const Board& board) {
   int whiteCost = 0;
   int blackCost = 0;

   for (int ndx = 0; ndx < BOARD_DIMENSION; ++ndx) {
      Marker rowMarker1 = board[State::getIndex(Position(ndx, 0))];
      Marker rowMarker2 = board[State::getIndex(Position(ndx, BOARD_DIMENSION - 1))];
      Marker colMarker1 = board[State::getIndex(Position(0, ndx))];
      Marker colMarker2 = board[State::getIndex(Position(BOARD_DIMENSION - 1, ndx))];

      if (rowMarker1 == white) {
         ++whiteCost;
      }
      if (rowMarker2 == white) {
         ++whiteCost;
      }
      if (colMarker1 == white) {
         ++whiteCost;
      }
      if (colMarker2 == white) {
         ++whiteCost;
      }

      if (rowMarker1 == black) {
         ++blackCost;
      }
      if (rowMarker2 == black) {
         ++blackCost;
      }
      if (colMarker1 == black) {
         ++blackCost;
      }
      if (colMarker2 == black) {
         ++blackCost;
      }
   }

   return std::make_tuple(whiteCost, blackCost);
}

int MiniMaxAgent::utility(const Move& move, const State& state) {
   static const int scoreWeight = 1000;
   static const int edgeWeight = 10;
   static const int passWeight = 1;

   auto scores = state.getScores();
   int scoreValue = std::get<0>(scores) - std::get<1>(scores);

   auto edgeCosts = MiniMaxAgent::edgeCosts(state.getBoard());
   int edgeValue = (this->_marker == white) ? -std::get<0>(edgeCosts) :
    std::get<1>(edgeCosts);

   int passValue = 0;
   const Pass* pass = boost::get< Pass >(&move);
   if (pass != nullptr) {
      passValue = (this->_marker == white) ? 1 : -1;
   }

   int totalValue = scoreWeight * scoreValue + edgeWeight * edgeValue +
    passWeight * passValue;

   return (this->_marker == white) ? totalValue : -totalValue;
}
<|endoftext|>


<commit_before>#include "moc_sweeper.hpp"

#include "error.hpp"

using std::endl;
using std::cout;

namespace mocc {

    MoCSweeper::MoCSweeper( const pugi::xml_node &input,
            const CoreMesh &mesh ):
        TransportSweeper( mesh ),
        ang_quad_( input.child("ang_quad") ),
        rays_( input.child("rays"), ang_quad_, mesh ),
        xstr_( n_reg_, 1 ),
        flux_1g_( n_reg_, 1 ),
        qbar_( n_reg_, 1 ),
        bc_type_( mesh_.boundary() )
    {

        // Make sure we have input from the XML
        if( input.empty() ) {
            Error("No input specified to initialize MoC sweeper.");
        }

        // Parse the number of inner iterations
        int int_in = input.attribute("n_inner").as_int(-1);
        if(int_in < 0) {
            Error("Invalid number of inner iterations specified (n_inner).");
        }
        n_inner_ = int_in;

        // Set up the array of volumes (surface area)
        int ireg = 0;
        for( auto pin=mesh_.begin_pin(); pin!=mesh_.end_pin(); ++pin ) {
            const VecF& pin_vol = (*pin)->vol();
            for( auto &v: pin_vol ) {
                vol_(ireg) = v;
                ireg++;
            }
        }

        // allocate space to store the boundary conditions
        boundary_.resize( ng_ );
        for( auto &group_rays: boundary_ ) {
cout << " group " << endl;
            group_rays.resize( mesh_.nz() );
            for( auto &angle_rays: group_rays ) {
                // We actually allocate BCs for all 4 octants to make things a
                // little simpler.
                angle_rays.resize( ang_quad_.ndir_oct()*4 );
                int iang = 0;
                for( auto ang_it=ang_quad_.octant(1);
                        ang_it!=ang_quad_.octant(5); ang_it++ ) {
                    angle_rays[iang].resize(rays_.n_rays(iang));
                    iang++;
                }
            }
        }
        boundary_out_.resize( mesh_.nz() );
        for( auto &angle_rays: boundary_out_ ) {
            // We actually allocate BCs for all 4 octants to make things a
            // little simpler.
            angle_rays.resize( ang_quad_.ndir_oct()*4 );
            int iang = 0;
            for( auto ang_it=ang_quad_.octant(1);
                    ang_it!=ang_quad_.octant(5); ang_it++ ) {
                angle_rays[iang].resize(rays_.n_rays(iang));
                iang++;
            }
        }

        return;
    }

    void MoCSweeper::sweep( int group ) {
        cout << "moc sweep: " << n_inner_ << endl;

        // set up the xstr_ array
        for( auto &xsr: xs_mesh_ ) {
            float_t xstr = xsr.xsmactr()[group];
            for( auto &ireg: xsr.reg() ) {
                xstr_(ireg) = xstr;
            }
        }

        flux_1g_ = flux_.col( group );
        for( unsigned int inner=0; inner<n_inner_; inner++ ) {
            // update the self-scattering source
            source_->self_scatter( group, flux_1g_, qbar_ );
            this->sweep1g( group );
        }
cout.precision(10);
cout << flux_1g_ << endl;
char a;
std::cin >> a;

        flux_.col( group ) = flux_1g_;

        return;
    }

    void MoCSweeper::sweep1g( int group ) {
        flux_1g_.fill(0.0);

cout << qbar_ << endl;

        ArrayX e_tau(rays_.max_segments(), 1);

        int iplane = 0;
        for( auto &plane_rays: rays_ ) {
            int first_reg = mesh_.first_reg_plane(iplane);
            int iang = 0;
            for( auto &ang_rays: plane_rays ) {
                int iang1 = iang;
                int iang2 = ang_quad_.reverse(iang);
                float_t stheta = sin(ang_quad_[iang].theta);
                float_t rstheta = 1.0/stheta;
                float_t wt_v_st = ang_quad_[iang].weight * rays_.spacing(iang) *
                    stheta * PI;

                int iray = 0;
                for( auto &ray: ang_rays ) {
                    int bc1 = ray.bc(0);
                    int bc2 = ray.bc(1);

                    // Compute exponentials
                    for( int iseg=0; iseg<ray.nseg(); iseg++ ) {
                        int ireg = ray.seg_index(iseg) + first_reg;
                        e_tau(iseg) = 1.0 - exp( -xstr_(ireg) *
                                ray.seg_len(iseg) * rstheta );
                    }

                    // Forward direction
                    {
                        // Initialize from bc
                        float_t psi =
                            boundary_[group][iplane][iang1][bc1];
                        // Propagate through core geometry
                        for( int iseg=0; iseg<ray.nseg(); iseg++ ) {
                            int ireg = ray.seg_index(iseg);// + first_reg;
                            float_t psi_diff = (psi - qbar_(ireg)) * e_tau(iseg);
                            psi -= psi_diff;
                            flux_1g_(ireg) += psi_diff*wt_v_st;
                        }
                        // Store boundary condition
                        boundary_out_[iplane][iang1][bc1] = psi;
                    }

                    // Backward direction
                    {
                        // Initialize from bc
                        float_t psi =
                            boundary_[group][iplane][iang2][bc2];
                        // Propagate through core geometry
                        for( int iseg=ray.nseg()-1; iseg>=0; iseg-- ) {
                            int ireg = ray.seg_index(iseg) + first_reg;
                            float_t psi_diff = (psi - qbar_(ireg)) * e_tau(iseg);
                            psi -= psi_diff;
                            flux_1g_(ireg) += psi_diff*wt_v_st;
                        }
                        // Store boundary condition
                        boundary_out_[iplane][iang2][bc2] = psi;
                    }
                    iray++;
                } // Rays
                iang++;
            } // angles
            iplane++;

            // Scale the scalar flux by the volume and add back the source
            flux_1g_ = flux_1g_/(xstr_*vol_) + qbar_*FPI;
        } // planes

        this->update_boundary( group );

        return;
    }

    void MoCSweeper::update_boundary( int group ) {
        int iplane=0;
        for( auto &plane_bcs: boundary_[group] ) {
            for( unsigned int iang=0; iang<plane_bcs.size(); iang++ ) {
                int nx = rays_.nx(iang);
                int ny = rays_.ny(iang);

                if( bc_type_[Surface::WEST] == REFLECT ) {
                    int ang_ref = ang_quad_.reflect(iang, WEST);
                    for( int ibc=0; ibc<ny; ibc++ ) {
                        plane_bcs[iang][ibc] =
                            boundary_out_[iplane][ang_ref][ibc];
                    }
                } else {
                    for( int ibc=0; ibc<ny; ibc++ ) {
                        plane_bcs[iang][ibc] = 0.0;
                    }
                }

                if( bc_type_[Surface::SOUTH] == REFLECT ) {
                    int ang_ref = ang_quad_.reflect(iang, SOUTH);
                    for( int ibc=ny; ibc<(ny+nx); ibc++ ) {
                        plane_bcs[iang][ibc] =
                            boundary_out_[iplane][ang_ref][ibc];
                    }
                } else {
                    for( int ibc=ny; ibc<(ny+nx); ibc++ ) {
                        plane_bcs[iang][ibc] = 0.0;
                    }
                }

                if( bc_type_[Surface::EAST] == REFLECT ) {
                    int ang_ref = ang_quad_.reflect(iang, EAST);
                    for( int ibc=0; ibc<ny; ibc++ ) {
                       plane_bcs[iang][ibc] =
                            boundary_out_[iplane][ang_ref][ibc];
                    }
                } else {
                    for( int ibc=0; ibc<ny; ibc++ ) {
                        plane_bcs[iang][ibc] = 0.0;
                    }
                }

                if( bc_type_[Surface::NORTH] == REFLECT ) {
                    int ang_ref = ang_quad_.reflect(iang, NORTH);
                    for( int ibc=ny; ibc<(nx+ny); ibc++ ) {
                        plane_bcs[iang][ibc] =
                            boundary_out_[iplane][ang_ref][ibc];
                    }
                } else {
                    for( int ibc=ny; ibc<(nx+ny); ibc++ ) {
                        plane_bcs[iang][ibc] = 0.0;
                    }
                }
            }
            iplane++;
        }
    }

    void MoCSweeper::initialize() {
        // There are better ways to do this, but for now, just start with 1.0
        flux_.fill(1.0);

        // Walk through the boundary conditions and initialize them the 1/4pi
        float_t val = 1.0/FPI;
        for( auto &group_rays: boundary_ ) {
            for( auto &plane_rays: group_rays ) {
                for( auto &angle_rays: plane_rays ) {
                    for( auto &ray: angle_rays ) {
                        ray = val;
                    }
                }
            }
        }
        return;
    }

    void MoCSweeper::calc_fission_source( float_t k,
            ArrayX& fission_source ) const {

        float_t rkeff = 1.0/k;
        fission_source.fill(0.0);
        for( auto &xsr: xs_mesh_ ) {
            const auto& xsnf = xsr.xsmacnf();
            for(unsigned int ig=0; ig<xs_mesh_.n_grp(); ig++ ) {
                for( auto &ireg: xsr.reg() ) {
                    fission_source(ireg) += rkeff*xsnf[ig]*flux_(ireg, ig);
                }
            }
        }
        return;
    }

}
<commit_msg>Remove debug statements from the MoC sweeper<commit_after>#include "moc_sweeper.hpp"

#include "error.hpp"

using std::endl;
using std::cout;

namespace mocc {

    MoCSweeper::MoCSweeper( const pugi::xml_node &input,
            const CoreMesh &mesh ):
        TransportSweeper( mesh ),
        ang_quad_( input.child("ang_quad") ),
        rays_( input.child("rays"), ang_quad_, mesh ),
        xstr_( n_reg_, 1 ),
        flux_1g_( n_reg_, 1 ),
        qbar_( n_reg_, 1 ),
        bc_type_( mesh_.boundary() )
    {

        // Make sure we have input from the XML
        if( input.empty() ) {
            Error("No input specified to initialize MoC sweeper.");
        }

        // Parse the number of inner iterations
        int int_in = input.attribute("n_inner").as_int(-1);
        if(int_in < 0) {
            Error("Invalid number of inner iterations specified (n_inner).");
        }
        n_inner_ = int_in;

        // Set up the array of volumes (surface area)
        int ireg = 0;
        for( auto pin=mesh_.begin_pin(); pin!=mesh_.end_pin(); ++pin ) {
            const VecF& pin_vol = (*pin)->vol();
            for( auto &v: pin_vol ) {
                vol_(ireg) = v;
                ireg++;
            }
        }

        // allocate space to store the boundary conditions
        boundary_.resize( ng_ );
        for( auto &group_rays: boundary_ ) {
            group_rays.resize( mesh_.nz() );
            for( auto &angle_rays: group_rays ) {
                // We actually allocate BCs for all 4 octants to make things a
                // little simpler.
                angle_rays.resize( ang_quad_.ndir_oct()*4 );
                int iang = 0;
                for( auto ang_it=ang_quad_.octant(1);
                        ang_it!=ang_quad_.octant(5); ang_it++ ) {
                    angle_rays[iang].resize(rays_.n_rays(iang));
                    iang++;
                }
            }
        }
        boundary_out_.resize( mesh_.nz() );
        for( auto &angle_rays: boundary_out_ ) {
            // We actually allocate BCs for all 4 octants to make things a
            // little simpler.
            angle_rays.resize( ang_quad_.ndir_oct()*4 );
            int iang = 0;
            for( auto ang_it=ang_quad_.octant(1);
                    ang_it!=ang_quad_.octant(5); ang_it++ ) {
                angle_rays[iang].resize(rays_.n_rays(iang));
                iang++;
            }
        }

        return;
    }

    void MoCSweeper::sweep( int group ) {
        // set up the xstr_ array
        for( auto &xsr: xs_mesh_ ) {
            float_t xstr = xsr.xsmactr()[group];
            for( auto &ireg: xsr.reg() ) {
                xstr_(ireg) = xstr;
            }
        }

        flux_1g_ = flux_.col( group );
        for( unsigned int inner=0; inner<n_inner_; inner++ ) {
            // update the self-scattering source
            source_->self_scatter( group, flux_1g_, qbar_ );
            this->sweep1g( group );
        }

        flux_.col( group ) = flux_1g_;

        return;
    }

    void MoCSweeper::sweep1g( int group ) {
        flux_1g_.fill(0.0);

        ArrayX e_tau(rays_.max_segments(), 1);

        int iplane = 0;
        for( auto &plane_rays: rays_ ) {
            int first_reg = mesh_.first_reg_plane(iplane);
            int iang = 0;
            for( auto &ang_rays: plane_rays ) {
                int iang1 = iang;
                int iang2 = ang_quad_.reverse(iang);
                float_t stheta = sin(ang_quad_[iang].theta);
                float_t rstheta = 1.0/stheta;
                float_t wt_v_st = ang_quad_[iang].weight * rays_.spacing(iang) *
                    stheta * PI;

                int iray = 0;
                for( auto &ray: ang_rays ) {
                    int bc1 = ray.bc(0);
                    int bc2 = ray.bc(1);

                    // Compute exponentials
                    for( int iseg=0; iseg<ray.nseg(); iseg++ ) {
                        int ireg = ray.seg_index(iseg) + first_reg;
                        e_tau(iseg) = 1.0 - exp( -xstr_(ireg) *
                                ray.seg_len(iseg) * rstheta );
                    }

                    // Forward direction
                    {
                        // Initialize from bc
                        float_t psi =
                            boundary_[group][iplane][iang1][bc1];

                        // Propagate through core geometry
                        for( int iseg=0; iseg<ray.nseg(); iseg++ ) {
                            int ireg = ray.seg_index(iseg) + first_reg;
                            float_t psi_diff = (psi - qbar_(ireg)) * e_tau(iseg);
                            psi -= psi_diff;
                            flux_1g_(ireg) += psi_diff*wt_v_st;
                        }
                        // Store boundary condition
                        boundary_out_[iplane][iang1][bc1] = psi;
                    }

                    // Backward direction
                    {
                        // Initialize from bc
                        float_t psi =
                            boundary_[group][iplane][iang2][bc2];

                        // Propagate through core geometry
                        for( int iseg=ray.nseg()-1; iseg>=0; iseg-- ) {
                            int ireg = ray.seg_index(iseg) + first_reg;
                            float_t psi_diff = (psi - qbar_(ireg)) * e_tau(iseg);
                            psi -= psi_diff;
                            flux_1g_(ireg) += psi_diff*wt_v_st;
                        }
                        // Store boundary condition
                        boundary_out_[iplane][iang2][bc2] = psi;
                    }
                    iray++;
                } // Rays
                iang++;
            } // angles
            iplane++;

            // Scale the scalar flux by the volume and add back the source
            flux_1g_ = flux_1g_/(xstr_*vol_) + qbar_*FPI;
        } // planes

        this->update_boundary( group );

        return;
    }

    void MoCSweeper::update_boundary( int group ) {
        int iplane=0;
        for( auto &plane_bcs: boundary_[group] ) {
            for( unsigned int iang=0; iang<plane_bcs.size(); iang++ ) {
                int nx = rays_.nx(iang);
                int ny = rays_.ny(iang);

                if( bc_type_[Surface::WEST] == REFLECT ) {
                    int ang_ref = ang_quad_.reflect(iang, WEST);
                    for( int ibc=0; ibc<ny; ibc++ ) {
                        plane_bcs[iang][ibc] =
                            boundary_out_[iplane][ang_ref][ibc];
                    }
                } else {
                    for( int ibc=0; ibc<ny; ibc++ ) {
                        plane_bcs[iang][ibc] = 0.0;
                    }
                }

                if( bc_type_[Surface::SOUTH] == REFLECT ) {
                    int ang_ref = ang_quad_.reflect(iang, SOUTH);
                    for( int ibc=ny; ibc<(ny+nx); ibc++ ) {
                        plane_bcs[iang][ibc] =
                            boundary_out_[iplane][ang_ref][ibc];
                    }
                } else {
                    for( int ibc=ny; ibc<(ny+nx); ibc++ ) {
                        plane_bcs[iang][ibc] = 0.0;
                    }
                }

                if( bc_type_[Surface::EAST] == REFLECT ) {
                    int ang_ref = ang_quad_.reflect(iang, EAST);
                    for( int ibc=0; ibc<ny; ibc++ ) {
                       plane_bcs[iang][ibc] =
                            boundary_out_[iplane][ang_ref][ibc];
                    }
                } else {
                    for( int ibc=0; ibc<ny; ibc++ ) {
                        plane_bcs[iang][ibc] = 0.0;
                    }
                }

                if( bc_type_[Surface::NORTH] == REFLECT ) {
                    int ang_ref = ang_quad_.reflect(iang, NORTH);
                    for( int ibc=ny; ibc<(nx+ny); ibc++ ) {
                        plane_bcs[iang][ibc] =
                            boundary_out_[iplane][ang_ref][ibc];
                    }
                } else {
                    for( int ibc=ny; ibc<(nx+ny); ibc++ ) {
                        plane_bcs[iang][ibc] = 0.0;
                    }
                }
            } // angle loop
            iplane++;
        } // plane loop
    }

    void MoCSweeper::initialize() {
        // There are better ways to do this, but for now, just start with 1.0
        flux_.fill(1.0);

        // Walk through the boundary conditions and initialize them the 1/4pi
        float_t val = 1.0/FPI;
        for( auto &group_rays: boundary_ ) {
            for( auto &plane_rays: group_rays ) {
                for( auto &angle_rays: plane_rays ) {
                    for( auto &ray: angle_rays ) {
                        ray = val;
                    }
                }
            }
        }
        return;
    }

    void MoCSweeper::calc_fission_source( float_t k,
            ArrayX& fission_source ) const {

        float_t rkeff = 1.0/k;
        fission_source.fill(0.0);
        for( auto &xsr: xs_mesh_ ) {
            const auto& xsnf = xsr.xsmacnf();
            for(unsigned int ig=0; ig<xs_mesh_.n_grp(); ig++ ) {
                for( auto &ireg: xsr.reg() ) {
                    fission_source(ireg) += rkeff*xsnf[ig]*flux_(ireg, ig);
                }
            }
        }
        return;
    }

}
<|endoftext|>


<commit_before>#include <papki/RootDirFile.hpp>

#include "ResourceManager.hpp"

#include "util/util.hpp"

using namespace morda;

namespace{
const char* include_c = "include";
const char* includeSubdirs_c = "includeSubdirs";
}

void ResourceManager::mountResPack(const papki::File& fi){
	ASSERT(!fi.isOpened())
//	TRACE(<< "ResourceManager::mountResPack(): fi->path() = " << fi.path() << std::endl)

	std::string dir = fi.dir();

	if(fi.notDir().size() == 0){
		fi.setPath(dir + "main.res");
	}

	std::unique_ptr<stob::Node> resScript = utki::makeUnique<stob::Node>();
	resScript->setNext(stob::load(fi));
	ASSERT(!fi.isOpened())
	//handle includeSubdirs
	if(resScript->next(includeSubdirs_c).get_node()){
//		TRACE(<< "includeSubdirs encountered!!!!!!!!!!!!!!!" << std::endl)
		fi.setPath(fi.dir());
		auto dirContents = fi.list_dir();
		ASSERT(!fi.isOpened())
		for(auto& fileName : dirContents){
			if(fileName.size() != 0 && fileName[fileName.size() - 1] == '/'){
				fi.setPath(dir + fileName);
//				TRACE(<< "mounting respack " << fi.path() << std::endl)
				this->mountResPack(fi);
			}
		}
	}

	//handle includes
	for(auto np = resScript->next(include_c); np.get_node(); np = np.prev()->next(include_c)){
		ASSERT(np.prev())
		auto incNode = np.prev()->removeNext()->removeChildren();

		fi.setPath(dir + incNode->value());
		this->mountResPack(fi);
	}

	if(!resScript->next()){
		return;
	}

	ResPackEntry rpe;
	rpe.fi = papki::RootDirFile::makeUniqueConst(fi.spawn(), dir);
	rpe.script = stob_to_puu(resScript->chopNext().get());

	this->resPacks.push_back(std::move(rpe));
	ASSERT(this->resPacks.back().fi)
	ASSERT(!this->resPacks.back().script.empty())
}

ResourceManager::FindInScriptRet ResourceManager::findResourceInScript(const std::string& resName){
//	TRACE(<< "ResourceManager::FindResourceInScript(): resName = " << (resName.c_str()) << std::endl)

	for(auto i = this->resPacks.rbegin(); i != this->resPacks.rend(); ++i){
		auto j = std::find(i->script.begin(), i->script.end(), resName);
		if(j != i->script.end()){
			return FindInScriptRet(*i, *j);
		}
	}
	TRACE(<< "resource name not found in mounted resource packs: " << resName << std::endl)
	std::stringstream ss;
	ss << "resource name not found in mounted resource packs: " << resName;
	throw ResourceManager::Exc(ss.str());
}

void ResourceManager::addResource(const std::shared_ptr<Resource>& res, const std::string& name){
	ASSERT(res)

	ASSERT(this->resMap.find(name) == this->resMap.end())

	//add the resource to the resources map of ResMan
	auto result = this->resMap.insert(
			std::make_pair(name, std::weak_ptr<Resource>(res))
		);
	if(!result.second){
		ASSERT(false)
	}

//#ifdef DEBUG
//	for(T_ResMap::iterator i = this->resMap->rm.begin(); i != this->resMap->rm.end(); ++i){
//		TRACE(<< "\t" << *(*i).first << std::endl)
//	}
//#endif
}
<commit_msg>stuff<commit_after>#include <papki/RootDirFile.hpp>

#include "ResourceManager.hpp"

#include "util/util.hpp"

using namespace morda;

namespace{
const char* include_c = "include";
const char* includeSubdirs_c = "includeSubdirs";
}

void ResourceManager::mountResPack(const papki::File& fi){
	ASSERT(!fi.isOpened())
//	TRACE(<< "ResourceManager::mountResPack(): fi->path() = " << fi.path() << std::endl)

	std::string dir = fi.dir();

	if(fi.notDir().size() == 0){
		fi.setPath(dir + "main.res");
	}

	std::unique_ptr<stob::Node> resScript = utki::makeUnique<stob::Node>();
	resScript->setNext(stob::load(fi));
	ASSERT(!fi.isOpened())
	//handle includeSubdirs
	if(resScript->next(includeSubdirs_c).get_node()){
//		TRACE(<< "includeSubdirs encountered!!!!!!!!!!!!!!!" << std::endl)
		fi.setPath(fi.dir());
		auto dirContents = fi.list_dir();
		ASSERT(!fi.isOpened())
		for(auto& fileName : dirContents){
			if(fileName.size() != 0 && fileName[fileName.size() - 1] == '/'){
				fi.setPath(dir + fileName);
//				TRACE(<< "mounting respack " << fi.path() << std::endl)
				this->mountResPack(fi);
			}
		}
	}

	//handle includes
	for(auto np = resScript->next(include_c); np.get_node(); np = np.prev()->next(include_c)){
		ASSERT(np.prev())
		auto incNode = np.prev()->removeNext()->removeChildren();

		fi.setPath(dir + incNode->value());
		this->mountResPack(fi);
	}

	ResPackEntry rpe;
	rpe.fi = papki::RootDirFile::makeUniqueConst(fi.spawn(), dir);
	rpe.script = stob_to_puu(resScript->chopNext().get());

	this->resPacks.push_back(std::move(rpe));
	ASSERT(this->resPacks.back().fi)
	ASSERT(!this->resPacks.back().script.empty())
}

ResourceManager::FindInScriptRet ResourceManager::findResourceInScript(const std::string& resName){
//	TRACE(<< "ResourceManager::FindResourceInScript(): resName = " << (resName.c_str()) << std::endl)

	for(auto i = this->resPacks.rbegin(); i != this->resPacks.rend(); ++i){
		auto j = std::find(i->script.begin(), i->script.end(), resName);
		if(j != i->script.end()){
			return FindInScriptRet(*i, *j);
		}
	}
	TRACE(<< "resource name not found in mounted resource packs: " << resName << std::endl)
	std::stringstream ss;
	ss << "resource name not found in mounted resource packs: " << resName;
	throw ResourceManager::Exc(ss.str());
}

void ResourceManager::addResource(const std::shared_ptr<Resource>& res, const std::string& name){
	ASSERT(res)

	ASSERT(this->resMap.find(name) == this->resMap.end())

	//add the resource to the resources map of ResMan
	auto result = this->resMap.insert(
			std::make_pair(name, std::weak_ptr<Resource>(res))
		);
	if(!result.second){
		ASSERT(false)
	}

//#ifdef DEBUG
//	for(T_ResMap::iterator i = this->resMap->rm.begin(); i != this->resMap->rm.end(); ++i){
//		TRACE(<< "\t" << *(*i).first << std::endl)
//	}
//#endif
}
<|endoftext|>


<commit_before>#include "stabiliser_graph.h"

double IStabiliserGraph::SpaceTimeDistance(int node1, int node2) const {
    int num_stab = GetNumStabilisers();
    if ((node1 < num_stab) && (node2 < num_stab)){
        return Distance(node1, node2);
    }
    int t1 = node1 / num_stab;
    int r1 = node1 % num_stab;
    int t2 = node2 / num_stab;
    int r2 = node2 % num_stab;
    return std::abs(t2-t1) + Distance(r1, r2);
}

std::vector<int> IStabiliserGraph::SpaceTimeShortestPath(int node1, int node2) const {
    int num_stab = GetNumStabilisers();
    int r1 = node1 % num_stab;
    int r2 = node2 % num_stab;
    return ShortestPath(r1, r2);
}<commit_msg>add include for abs() on linux<commit_after>#include <cstdlib>
#include "stabiliser_graph.h"

double IStabiliserGraph::SpaceTimeDistance(int node1, int node2) const {
    int num_stab = GetNumStabilisers();
    if ((node1 < num_stab) && (node2 < num_stab)){
        return Distance(node1, node2);
    }
    int t1 = node1 / num_stab;
    int r1 = node1 % num_stab;
    int t2 = node2 / num_stab;
    int r2 = node2 % num_stab;
    return std::abs(t2-t1) + Distance(r1, r2);
}

std::vector<int> IStabiliserGraph::SpaceTimeShortestPath(int node1, int node2) const {
    int num_stab = GetNumStabilisers();
    int r1 = node1 % num_stab;
    int r2 = node2 % num_stab;
    return ShortestPath(r1, r2);
}
<|endoftext|>


<commit_before>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * OpenSceneGraph Public License for more details.
*/

#include <osgSim/LightPointNode>

#include "LightPointDrawable.h"

#include <osg/Timer>
#include <osg/BoundingBox>
#include <osg/BlendFunc>
#include <osg/Material>

#include <osgUtil/CullVisitor>

#include <typeinfo>

using namespace osgSim;

LightPointNode::LightPointNode():
    _minPixelSize(0.0f),
    _maxPixelSize(30.0f),
    _maxVisableDistance2(FLT_MAX)
{
}

/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
LightPointNode::LightPointNode(const LightPointNode& lpn,const osg::CopyOp& copyop):
    osg::Node(lpn,copyop),
    _lightPointList(lpn._lightPointList),
    _minPixelSize(lpn._minPixelSize),
    _maxPixelSize(lpn._maxPixelSize),
    _maxVisableDistance2(lpn._maxVisableDistance2)
{
}

unsigned int LightPointNode::addLightPoint(const LightPoint& lp)
{
    unsigned int num = _lightPointList.size();
    _lightPointList.push_back(lp);
    dirtyBound();
    return num;
}

void LightPointNode::removeLightPoint(unsigned int pos)
{
    if (pos<_lightPointList.size())
    {
        _lightPointList.erase(_lightPointList.begin()+pos);
        dirtyBound();
    }
    dirtyBound();
}

bool LightPointNode::computeBound() const
{
    _bsphere.init();
    _bbox.init();

    LightPointList::const_iterator itr;
    for(itr=_lightPointList.begin();
        itr!=_lightPointList.end();
        ++itr)
    {
        _bbox.expandBy(itr->_position);
    }

    _bsphere.set(_bbox.center(),0.0f);

    for(itr=_lightPointList.begin();
        itr!=_lightPointList.end();
        ++itr)
    {
        osg::Vec3 dv(itr->_position-_bsphere.center());
        float radius = dv.length()+itr->_radius;
        if (_bsphere.radius()<radius) _bsphere.radius()=radius;
    }

    _bsphere.radius()+=1.0f;

    _bsphere_computed=true;
    return true;
}

void LightPointNode::traverse(osg::NodeVisitor& nv)
{
    //#define USE_TIMER
    #ifdef USE_TIMER
    osg::Timer timer;
    osg::Timer_t t1=0,t2=0,t3=0,t4=0,t5=0,t6=0,t7=0,t8=0;
    #endif

#ifdef USE_TIMER
    t1 = timer.tick();
#endif

    osgUtil::CullVisitor* cv = NULL;
    if (typeid(nv)==typeid(osgUtil::CullVisitor))
    {
        cv = static_cast<osgUtil::CullVisitor*>(&nv);
    }

#ifdef USE_TIMER
    t2 = timer.tick();
#endif

    // should we disabled small feature culling here?
    if (cv /*&& !cv->isCulled(_bbox)*/)
    {

        osg::Matrix matrix = cv->getModelViewMatrix();
        osg::RefMatrix& projection = cv->getProjectionMatrix();
        osgUtil::RenderGraph* rg = cv->getCurrentRenderGraph();

        if (rg->leaves_empty())
        {
            // this is first leaf to be added to RenderGraph
            // and therefore should not already know to current render bin,
            // so need to add it.
            cv->getCurrentRenderBin()->addRenderGraph(rg);
        }

#ifdef USE_TIMER
        t3 = timer.tick();
#endif

        LightPointDrawable* drawable = NULL;
        osg::Referenced* object = rg->getUserData();
        if (object)
        {
            if (typeid(*object)==typeid(LightPointDrawable))
            {
                // resuse the user data attached to the render graph.
                drawable = static_cast<LightPointDrawable*>(object);

            }
            else
            {
                // will need to replace UserData.
                osg::notify(osg::WARN) << "Warning: Replacing osgUtil::RenderGraph::_userData to support osgSim::LightPointNode, may have undefined results."<<std::endl;
            }
        }

        if (!drawable)
        {
            // set it for the frst time.
            drawable = new LightPointDrawable;
            rg->setUserData(drawable);

            if (cv->getFrameStamp())
            {
                drawable->setReferenceTime(cv->getFrameStamp()->getReferenceTime());
            }
        }

        // search for a drawable in the RenderLead list equal to the attached the one attached to RenderGraph user data
        // as this will be our special light point drawable.
        osgUtil::RenderGraph::LeafList::iterator litr;
        for(litr = rg->_leaves.begin();
            litr != rg->_leaves.end() && (*litr)->_drawable!=drawable;
            ++litr)
        {}

        if (litr == rg->_leaves.end())
        {
            // havn't found the drawable added in the RenderLeaf list, there this my be the
            // first time through LightPointNode in this frame, so need to add drawable into the RenderGraph RenderLeaf list
            // and update its time signatures.

            drawable->reset();
            rg->addLeaf(new osgUtil::RenderLeaf(drawable,&projection,NULL,FLT_MAX));

            // need to update the drawable's frame count.
            if (cv->getFrameStamp())
            {
                drawable->updateReferenceTime(cv->getFrameStamp()->getReferenceTime());
            }

        }

#ifdef USE_TIMER
        t4 = timer.tick();
#endif

#ifdef USE_TIMER
        t7 = timer.tick();
#endif

        cv->updateCalculatedNearFar(matrix,_bbox);

        const float minimumIntensity = 1.0f/256.0f;
        const osg::Vec3 eyePoint = cv->getEyeLocal();

        double time=drawable->getReferenceTime();
        double timeInterval=drawable->getReferenceTimeInterval();

        const osg::Polytope clipvol(cv->getModelViewCullingStack().back()->getFrustum());
        const bool computeClipping = false;//(clipvol.getCurrentMask()!=0);

        //LightPointDrawable::ColorPosition cp;
        for(LightPointList::iterator itr=_lightPointList.begin();
            itr!=_lightPointList.end();
            ++itr)
        {
            const LightPoint& lp = *itr;

	    if (!lp._on) continue;

            const osg::Vec3& position = lp._position;

            // skip light point if it is not contianed in the view frustum.
            if (computeClipping && !clipvol.contains(position)) continue;

            // delta vector between eyepoint and light point.
            osg::Vec3 dv(eyePoint-position);

            float intensity = lp._intensity;

            // slip light point if it is intensity is 0.0 or negative.
            if (intensity<=minimumIntensity) continue;

            if (_maxVisableDistance2!=FLT_MAX)
            {
                if (dv.length2()>_maxVisableDistance2) continue;
            }

            osg::Vec4 color = lp._color;

            // check the sector.
            if (lp._sector.valid())
            {
                intensity *= (*lp._sector)(dv);

                // slip light point if it is intensity is 0.0 or negative.
                if (intensity<=minimumIntensity) continue;

            }

            // temporary accounting of intensity.
            //color *= intensity;

            // check the blink sequence.
            if (lp._blinkSequence.valid())
            {
                osg::Vec4 bs = lp._blinkSequence->color(time,timeInterval);
                color[0] *= bs[0];
                color[1] *= bs[1];
                color[2] *= bs[2];
                color[3] *= bs[3];
            }

            // if alpha value is less than the min intentsive then skip
            if (color[3]<=minimumIntensity) continue;

            float pixelSize = cv->pixelSize(position,lp._radius);

//            cout << "pixelsize = "<<pixelSize<<endl;

            // adjust pixel size to account for intensity.
            if (intensity!=1.0) pixelSize *= sqrt(intensity);

            // round up to the minimum pixel size if required.
            if (pixelSize<_minPixelSize) pixelSize = _minPixelSize;

            osg::Vec3 xpos(position*matrix);

            if (lp._blendingMode==LightPoint::BLENDED)
            {
                if (pixelSize<1.0f)
                {
                    // need to use alpha blending...
                    //color[3] = pixelSize;
                    color[3] *= osg::square(pixelSize);

                    if (color[3]<=minimumIntensity) continue;

                    drawable->addBlendedLightPoint(0, xpos,color);
                }
                else if (pixelSize<_maxPixelSize)
                {

                    unsigned int lowerBoundPixelSize = (unsigned int)pixelSize;
                    //float remainder = pixelSize-(float)lowerBoundPixelSize;
                    float remainder = osg::square(pixelSize-(float)lowerBoundPixelSize);
                    float alpha = color[3];
                    drawable->addBlendedLightPoint(lowerBoundPixelSize-1, xpos,color);

                    color[3] = alpha*remainder;
                    drawable->addBlendedLightPoint(lowerBoundPixelSize, xpos,color);
                }
                else // use a billboard geometry.
                {
                    drawable->addBlendedLightPoint((unsigned int)(_maxPixelSize-1.0), xpos,color);
                }
            }
            else // ADDITIVE blending.
            {
                if (pixelSize<1.0f)
                {
                    // need to use alpha blending...
                    //color[3] = pixelSize;
                    color[3] *= osg::square(pixelSize);

                    if (color[3]<=minimumIntensity) continue;

                    drawable->addAdditiveLightPoint(0, xpos,color);
                }
                else if (pixelSize<_maxPixelSize)
                {

                    unsigned int lowerBoundPixelSize = (unsigned int)pixelSize;
                    //float remainder = pixelSize-(float)lowerBoundPixelSize;
                    float remainder = osg::square(pixelSize-(float)lowerBoundPixelSize);
                    float alpha = color[3];
                    color[3] = alpha*(1.0f-remainder);
                    drawable->addAdditiveLightPoint(lowerBoundPixelSize-1, xpos,color);

                    color[3] = alpha*remainder;
                    drawable->addAdditiveLightPoint(lowerBoundPixelSize, xpos,color);
                }
                else // use a billboard geometry.
                {
                    drawable->addAdditiveLightPoint((unsigned int)(_maxPixelSize-1.0), xpos,color);
                }
            }
        }

#ifdef USE_TIMER
        t8 = timer.tick();
#endif

    }
#ifdef USE_TIMER
    cout << "compute"<<endl;
    cout << "  t2-t1="<<t2-t1<<endl;
    cout << "  t4-t3="<<t4-t3<<endl;
    cout << "  t6-t5="<<t6-t5<<endl;
    cout << "  t8-t7="<<t8-t7<<endl;
    cout << "_lightPointList.size()="<<_lightPointList.size()<<endl;
    cout << "  t8-t7/size = "<<(float)(t8-t7)/(float)_lightPointList.size()<<endl;
#endif
}

<commit_msg>From Brede, added   if (cv->getComputeNearFarMode() != osgUtil::CullVisitor::DO_NOT_COMPUTE_NEAR_FAR) to protect   cv->updateCalculatedNearFar(matrix,_bbox); call to avoid inapporpriate near/far warnings.<commit_after>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * OpenSceneGraph Public License for more details.
*/

#include <osgSim/LightPointNode>

#include "LightPointDrawable.h"

#include <osg/Timer>
#include <osg/BoundingBox>
#include <osg/BlendFunc>
#include <osg/Material>

#include <osgUtil/CullVisitor>

#include <typeinfo>

using namespace osgSim;

LightPointNode::LightPointNode():
    _minPixelSize(0.0f),
    _maxPixelSize(30.0f),
    _maxVisableDistance2(FLT_MAX)
{
}

/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
LightPointNode::LightPointNode(const LightPointNode& lpn,const osg::CopyOp& copyop):
    osg::Node(lpn,copyop),
    _lightPointList(lpn._lightPointList),
    _minPixelSize(lpn._minPixelSize),
    _maxPixelSize(lpn._maxPixelSize),
    _maxVisableDistance2(lpn._maxVisableDistance2)
{
}

unsigned int LightPointNode::addLightPoint(const LightPoint& lp)
{
    unsigned int num = _lightPointList.size();
    _lightPointList.push_back(lp);
    dirtyBound();
    return num;
}

void LightPointNode::removeLightPoint(unsigned int pos)
{
    if (pos<_lightPointList.size())
    {
        _lightPointList.erase(_lightPointList.begin()+pos);
        dirtyBound();
    }
    dirtyBound();
}

bool LightPointNode::computeBound() const
{
    _bsphere.init();
    _bbox.init();

    LightPointList::const_iterator itr;
    for(itr=_lightPointList.begin();
        itr!=_lightPointList.end();
        ++itr)
    {
        _bbox.expandBy(itr->_position);
    }

    _bsphere.set(_bbox.center(),0.0f);

    for(itr=_lightPointList.begin();
        itr!=_lightPointList.end();
        ++itr)
    {
        osg::Vec3 dv(itr->_position-_bsphere.center());
        float radius = dv.length()+itr->_radius;
        if (_bsphere.radius()<radius) _bsphere.radius()=radius;
    }

    _bsphere.radius()+=1.0f;

    _bsphere_computed=true;
    return true;
}

void LightPointNode::traverse(osg::NodeVisitor& nv)
{
    //#define USE_TIMER
    #ifdef USE_TIMER
    osg::Timer timer;
    osg::Timer_t t1=0,t2=0,t3=0,t4=0,t5=0,t6=0,t7=0,t8=0;
    #endif

#ifdef USE_TIMER
    t1 = timer.tick();
#endif

    osgUtil::CullVisitor* cv = NULL;
    if (typeid(nv)==typeid(osgUtil::CullVisitor))
    {
        cv = static_cast<osgUtil::CullVisitor*>(&nv);
    }

#ifdef USE_TIMER
    t2 = timer.tick();
#endif

    // should we disabled small feature culling here?
    if (cv /*&& !cv->isCulled(_bbox)*/)
    {

        osg::Matrix matrix = cv->getModelViewMatrix();
        osg::RefMatrix& projection = cv->getProjectionMatrix();
        osgUtil::RenderGraph* rg = cv->getCurrentRenderGraph();

        if (rg->leaves_empty())
        {
            // this is first leaf to be added to RenderGraph
            // and therefore should not already know to current render bin,
            // so need to add it.
            cv->getCurrentRenderBin()->addRenderGraph(rg);
        }

#ifdef USE_TIMER
        t3 = timer.tick();
#endif

        LightPointDrawable* drawable = NULL;
        osg::Referenced* object = rg->getUserData();
        if (object)
        {
            if (typeid(*object)==typeid(LightPointDrawable))
            {
                // resuse the user data attached to the render graph.
                drawable = static_cast<LightPointDrawable*>(object);

            }
            else
            {
                // will need to replace UserData.
                osg::notify(osg::WARN) << "Warning: Replacing osgUtil::RenderGraph::_userData to support osgSim::LightPointNode, may have undefined results."<<std::endl;
            }
        }

        if (!drawable)
        {
            // set it for the frst time.
            drawable = new LightPointDrawable;
            rg->setUserData(drawable);

            if (cv->getFrameStamp())
            {
                drawable->setReferenceTime(cv->getFrameStamp()->getReferenceTime());
            }
        }

        // search for a drawable in the RenderLead list equal to the attached the one attached to RenderGraph user data
        // as this will be our special light point drawable.
        osgUtil::RenderGraph::LeafList::iterator litr;
        for(litr = rg->_leaves.begin();
            litr != rg->_leaves.end() && (*litr)->_drawable!=drawable;
            ++litr)
        {}

        if (litr == rg->_leaves.end())
        {
            // havn't found the drawable added in the RenderLeaf list, there this my be the
            // first time through LightPointNode in this frame, so need to add drawable into the RenderGraph RenderLeaf list
            // and update its time signatures.

            drawable->reset();
            rg->addLeaf(new osgUtil::RenderLeaf(drawable,&projection,NULL,FLT_MAX));

            // need to update the drawable's frame count.
            if (cv->getFrameStamp())
            {
                drawable->updateReferenceTime(cv->getFrameStamp()->getReferenceTime());
            }

        }

#ifdef USE_TIMER
        t4 = timer.tick();
#endif

#ifdef USE_TIMER
        t7 = timer.tick();
#endif

        if (cv->getComputeNearFarMode() != osgUtil::CullVisitor::DO_NOT_COMPUTE_NEAR_FAR)
            cv->updateCalculatedNearFar(matrix,_bbox);

        const float minimumIntensity = 1.0f/256.0f;
        const osg::Vec3 eyePoint = cv->getEyeLocal();

        double time=drawable->getReferenceTime();
        double timeInterval=drawable->getReferenceTimeInterval();

        const osg::Polytope clipvol(cv->getModelViewCullingStack().back()->getFrustum());
        const bool computeClipping = false;//(clipvol.getCurrentMask()!=0);

        //LightPointDrawable::ColorPosition cp;
        for(LightPointList::iterator itr=_lightPointList.begin();
            itr!=_lightPointList.end();
            ++itr)
        {
            const LightPoint& lp = *itr;

	    if (!lp._on) continue;

            const osg::Vec3& position = lp._position;

            // skip light point if it is not contianed in the view frustum.
            if (computeClipping && !clipvol.contains(position)) continue;

            // delta vector between eyepoint and light point.
            osg::Vec3 dv(eyePoint-position);

            float intensity = lp._intensity;

            // slip light point if it is intensity is 0.0 or negative.
            if (intensity<=minimumIntensity) continue;

            if (_maxVisableDistance2!=FLT_MAX)
            {
                if (dv.length2()>_maxVisableDistance2) continue;
            }

            osg::Vec4 color = lp._color;

            // check the sector.
            if (lp._sector.valid())
            {
                intensity *= (*lp._sector)(dv);

                // slip light point if it is intensity is 0.0 or negative.
                if (intensity<=minimumIntensity) continue;

            }

            // temporary accounting of intensity.
            //color *= intensity;

            // check the blink sequence.
            if (lp._blinkSequence.valid())
            {
                osg::Vec4 bs = lp._blinkSequence->color(time,timeInterval);
                color[0] *= bs[0];
                color[1] *= bs[1];
                color[2] *= bs[2];
                color[3] *= bs[3];
            }

            // if alpha value is less than the min intentsive then skip
            if (color[3]<=minimumIntensity) continue;

            float pixelSize = cv->pixelSize(position,lp._radius);

//            cout << "pixelsize = "<<pixelSize<<endl;

            // adjust pixel size to account for intensity.
            if (intensity!=1.0) pixelSize *= sqrt(intensity);

            // round up to the minimum pixel size if required.
            if (pixelSize<_minPixelSize) pixelSize = _minPixelSize;

            osg::Vec3 xpos(position*matrix);

            if (lp._blendingMode==LightPoint::BLENDED)
            {
                if (pixelSize<1.0f)
                {
                    // need to use alpha blending...
                    //color[3] = pixelSize;
                    color[3] *= osg::square(pixelSize);

                    if (color[3]<=minimumIntensity) continue;

                    drawable->addBlendedLightPoint(0, xpos,color);
                }
                else if (pixelSize<_maxPixelSize)
                {

                    unsigned int lowerBoundPixelSize = (unsigned int)pixelSize;
                    //float remainder = pixelSize-(float)lowerBoundPixelSize;
                    float remainder = osg::square(pixelSize-(float)lowerBoundPixelSize);
                    float alpha = color[3];
                    drawable->addBlendedLightPoint(lowerBoundPixelSize-1, xpos,color);

                    color[3] = alpha*remainder;
                    drawable->addBlendedLightPoint(lowerBoundPixelSize, xpos,color);
                }
                else // use a billboard geometry.
                {
                    drawable->addBlendedLightPoint((unsigned int)(_maxPixelSize-1.0), xpos,color);
                }
            }
            else // ADDITIVE blending.
            {
                if (pixelSize<1.0f)
                {
                    // need to use alpha blending...
                    //color[3] = pixelSize;
                    color[3] *= osg::square(pixelSize);

                    if (color[3]<=minimumIntensity) continue;

                    drawable->addAdditiveLightPoint(0, xpos,color);
                }
                else if (pixelSize<_maxPixelSize)
                {

                    unsigned int lowerBoundPixelSize = (unsigned int)pixelSize;
                    //float remainder = pixelSize-(float)lowerBoundPixelSize;
                    float remainder = osg::square(pixelSize-(float)lowerBoundPixelSize);
                    float alpha = color[3];
                    color[3] = alpha*(1.0f-remainder);
                    drawable->addAdditiveLightPoint(lowerBoundPixelSize-1, xpos,color);

                    color[3] = alpha*remainder;
                    drawable->addAdditiveLightPoint(lowerBoundPixelSize, xpos,color);
                }
                else // use a billboard geometry.
                {
                    drawable->addAdditiveLightPoint((unsigned int)(_maxPixelSize-1.0), xpos,color);
                }
            }
        }

#ifdef USE_TIMER
        t8 = timer.tick();
#endif

    }
#ifdef USE_TIMER
    cout << "compute"<<endl;
    cout << "  t2-t1="<<t2-t1<<endl;
    cout << "  t4-t3="<<t4-t3<<endl;
    cout << "  t6-t5="<<t6-t5<<endl;
    cout << "  t8-t7="<<t8-t7<<endl;
    cout << "_lightPointList.size()="<<_lightPointList.size()<<endl;
    cout << "  t8-t7/size = "<<(float)(t8-t7)/(float)_lightPointList.size()<<endl;
#endif
}

<|endoftext|>


<commit_before>/* Copyright 2016 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include <deque>
#include <vector>

#include "tensorflow/core/common_runtime/device.h"
#include "tensorflow/core/common_runtime/executor.h"
#include "tensorflow/core/common_runtime/function.h"
#include "tensorflow/core/common_runtime/memory_types.h"
#include "tensorflow/core/framework/function.h"
#include "tensorflow/core/framework/op.h"
#include "tensorflow/core/framework/op_kernel.h"
#include "tensorflow/core/framework/register_types.h"
#include "tensorflow/core/graph/algorithm.h"
#include "tensorflow/core/graph/gradients.h"
#include "tensorflow/core/graph/graph_constructor.h"
#include "tensorflow/core/platform/macros.h"

namespace tensorflow {

static const char* const kGradientOp = "SymbolicGradient";

class ArgOp : public OpKernel {
 public:
  explicit ArgOp(OpKernelConstruction* ctx) : OpKernel(ctx) {
    OP_REQUIRES_OK(ctx, ctx->GetAttr("T", &dtype_));
    OP_REQUIRES_OK(ctx, ctx->GetAttr("index", &index_));
  }

  void Compute(OpKernelContext* ctx) override {
    auto frame = ctx->call_frame();
    OP_REQUIRES(ctx, frame != nullptr, errors::Internal("no call frame"));
    Tensor val;
    OP_REQUIRES_OK(ctx, frame->GetArg(index_, &val));
    OP_REQUIRES(ctx, val.dtype() == dtype_,
                errors::InvalidArgument(
                    "Type mismatch: actual ", DataTypeString(val.dtype()),
                    " vs. expect ", DataTypeString(dtype_)));
    ctx->set_output(0, val);
  }

 private:
  int index_;
  DataType dtype_;

  TF_DISALLOW_COPY_AND_ASSIGN(ArgOp);
};

class RetvalOp : public OpKernel {
 public:
  explicit RetvalOp(OpKernelConstruction* ctx) : OpKernel(ctx) {
    OP_REQUIRES_OK(ctx, ctx->GetAttr("T", &dtype_));
    OP_REQUIRES_OK(ctx, ctx->GetAttr("index", &index_));
  }

  void Compute(OpKernelContext* ctx) override {
    const Tensor& val = ctx->input(0);
    OP_REQUIRES(ctx, val.dtype() == dtype_,
                errors::InvalidArgument(
                    "Type mismatch: actual ", DataTypeString(val.dtype()),
                    " vs. expect ", DataTypeString(dtype_)));
    auto frame = ctx->call_frame();
    OP_REQUIRES(ctx, frame != nullptr, errors::Internal("no call frame"));
    OP_REQUIRES_OK(ctx, frame->SetRetval(index_, val));
  }

 private:
  int index_;
  DataType dtype_;

  TF_DISALLOW_COPY_AND_ASSIGN(RetvalOp);
};

REGISTER_KERNEL_BUILDER(Name("_Arg").Device(DEVICE_CPU), ArgOp);
REGISTER_KERNEL_BUILDER(Name("_Retval").Device(DEVICE_CPU), RetvalOp);

#if TENSORFLOW_USE_SYCL
#define REGISTER(type)     \
  REGISTER_KERNEL_BUILDER( \
      Name("_Arg").Device(DEVICE_SYCL).TypeConstraint<type>("T"), ArgOp);
TF_CALL_NUMBER_TYPES_NO_INT32(REGISTER)
TF_CALL_bool(REGISTER) REGISTER_KERNEL_BUILDER(Name("_Arg")
                                                   .Device(DEVICE_GPU)
                                                   .HostMemory("output")
                                                   .TypeConstraint<int32>("T"),
                                               ArgOp);
#undef REGISTER
#define REGISTER(type)                                               \
  REGISTER_KERNEL_BUILDER(                                           \
      Name("_Retval").Device(DEVICE_SYCL).TypeConstraint<type>("T"), \
      RetvalOp);
TF_CALL_NUMBER_TYPES_NO_INT32(REGISTER)
TF_CALL_bool(REGISTER) REGISTER_KERNEL_BUILDER(Name("_Retval")
                                                   .Device(DEVICE_GPU)
                                                   .HostMemory("input")
                                                   .TypeConstraint<int32>("T"),
                                               RetvalOp);
#undef REGISTER
#endif

#define REGISTER(type)     \
  REGISTER_KERNEL_BUILDER( \
      Name("_Arg").Device(DEVICE_GPU).TypeConstraint<type>("T"), ArgOp);
TF_CALL_NUMBER_TYPES_NO_INT32(REGISTER)
TF_CALL_bool(REGISTER) REGISTER_KERNEL_BUILDER(Name("_Arg")
                                                   .Device(DEVICE_GPU)
                                                   .HostMemory("output")
                                                   .TypeConstraint<int32>("T"),
                                               ArgOp);
#undef REGISTER

#define REGISTER(type)     \
  REGISTER_KERNEL_BUILDER( \
      Name("_Retval").Device(DEVICE_GPU).TypeConstraint<type>("T"), RetvalOp);
TF_CALL_NUMBER_TYPES_NO_INT32(REGISTER)
TF_CALL_bool(REGISTER) REGISTER_KERNEL_BUILDER(Name("_Retval")
                                                   .Device(DEVICE_GPU)
                                                   .HostMemory("input")
                                                   .TypeConstraint<int32>("T"),
                                               RetvalOp);
#undef REGISTER

class PassOn : public OpKernel {
 public:
  explicit PassOn(OpKernelConstruction* ctx) : OpKernel(ctx) {
    OP_REQUIRES(ctx, ctx->num_inputs() == ctx->num_outputs(),
                errors::Internal("#inputs != #outputs : ", ctx->num_inputs(),
                                 " vs. ", ctx->num_outputs()));
    for (int i = 0; i < ctx->num_inputs(); ++i) {
      OP_REQUIRES(
          ctx, input_type(i) == output_type(i),
          errors::Internal("Input and output types for position ", i,
                           " do not match: ", DataTypeString(input_type(i)),
                           " vs. ", DataTypeString(output_type(i))));
    }
  }

  void Compute(OpKernelContext* ctx) override {
    for (int i = 0; i < ctx->num_inputs(); ++i) {
      ctx->set_output(i, ctx->input(i));
    }
  }
};

REGISTER_KERNEL_BUILDER(Name("_ListToArray").Device(DEVICE_CPU), PassOn);
REGISTER_KERNEL_BUILDER(Name("_ArrayToList").Device(DEVICE_CPU), PassOn);

#define REGISTER_GPU_KERNELS(type)                                       \
  REGISTER_KERNEL_BUILDER(                                               \
      Name("_ListToArray").Device(DEVICE_GPU).TypeConstraint<type>("T"), \
      PassOn);                                                           \
  REGISTER_KERNEL_BUILDER(                                               \
      Name("_ArrayToList").Device(DEVICE_GPU).TypeConstraint<type>("T"), \
      PassOn);

REGISTER_GPU_KERNELS(Eigen::half);
REGISTER_GPU_KERNELS(float);
REGISTER_GPU_KERNELS(double);

#undef REGISTER_GPU_KERNELS

REGISTER_KERNEL_BUILDER(Name("_ListToArray")
                            .Device(DEVICE_GPU)
                            .HostMemory("input")
                            .HostMemory("output")
                            .TypeConstraint<int32>("T"),
                        PassOn);
REGISTER_KERNEL_BUILDER(Name("_ArrayToList")
                            .Device(DEVICE_GPU)
                            .HostMemory("input")
                            .HostMemory("output")
                            .TypeConstraint<int32>("T"),
                        PassOn);

class SymbolicGradientOp : public AsyncOpKernel {
 public:
  SymbolicGradientOp(OpKernelConstruction* ctx)
      : AsyncOpKernel(ctx), handle_(-1) {}

  ~SymbolicGradientOp() override {}

  void ComputeAsync(OpKernelContext* ctx, DoneCallback done) override {
    FunctionLibraryRuntime* lib = ctx->function_library();
    OP_REQUIRES_ASYNC(ctx, lib != nullptr,
                      errors::Internal("No function library is provided."),
                      done);

    OP_REQUIRES_OK_ASYNC(
        ctx, lib->Instantiate(kGradientOp, def().attr(), &handle_), done);

    FunctionLibraryRuntime::Options opts;
    opts.step_id = ctx->step_id();
    opts.runner = ctx->runner();
    std::vector<Tensor> args;
    args.reserve(ctx->num_inputs());
    for (int i = 0; i < ctx->num_inputs(); ++i) {
      args.push_back(ctx->input(i));
    }
    std::vector<Tensor>* rets = new std::vector<Tensor>;
    lib->Run(
        opts, handle_, args, rets, [ctx, done, rets](const Status& status) {
          if (!status.ok()) {
            ctx->SetStatus(status);
          } else if (rets->size() != ctx->num_outputs()) {
            ctx->SetStatus(errors::InvalidArgument(
                "SymGrad expects to return ", ctx->num_outputs(),
                " tensor(s), but get ", rets->size(), " tensor(s) instead."));
          } else {
            for (size_t i = 0; i < rets->size(); ++i) {
              ctx->set_output(i, (*rets)[i]);
            }
          }
          delete rets;
          done();
        });
  }

 private:
  FunctionLibraryRuntime::Handle handle_;

  TF_DISALLOW_COPY_AND_ASSIGN(SymbolicGradientOp);
};

REGISTER_KERNEL_BUILDER(Name(kGradientOp).Device(DEVICE_CPU),
                        SymbolicGradientOp);
REGISTER_KERNEL_BUILDER(Name(kGradientOp).Device(DEVICE_GPU),
                        SymbolicGradientOp);

}  // namespace tensorflow
<commit_msg>Added OpenCL support for symbolic gradients<commit_after>/* Copyright 2016 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include <deque>
#include <vector>

#include "tensorflow/core/common_runtime/device.h"
#include "tensorflow/core/common_runtime/executor.h"
#include "tensorflow/core/common_runtime/function.h"
#include "tensorflow/core/common_runtime/memory_types.h"
#include "tensorflow/core/framework/function.h"
#include "tensorflow/core/framework/op.h"
#include "tensorflow/core/framework/op_kernel.h"
#include "tensorflow/core/framework/register_types.h"
#include "tensorflow/core/graph/algorithm.h"
#include "tensorflow/core/graph/gradients.h"
#include "tensorflow/core/graph/graph_constructor.h"
#include "tensorflow/core/platform/macros.h"

namespace tensorflow {

static const char* const kGradientOp = "SymbolicGradient";

class ArgOp : public OpKernel {
 public:
  explicit ArgOp(OpKernelConstruction* ctx) : OpKernel(ctx) {
    OP_REQUIRES_OK(ctx, ctx->GetAttr("T", &dtype_));
    OP_REQUIRES_OK(ctx, ctx->GetAttr("index", &index_));
  }

  void Compute(OpKernelContext* ctx) override {
    auto frame = ctx->call_frame();
    OP_REQUIRES(ctx, frame != nullptr, errors::Internal("no call frame"));
    Tensor val;
    OP_REQUIRES_OK(ctx, frame->GetArg(index_, &val));
    OP_REQUIRES(ctx, val.dtype() == dtype_,
                errors::InvalidArgument(
                    "Type mismatch: actual ", DataTypeString(val.dtype()),
                    " vs. expect ", DataTypeString(dtype_)));
    ctx->set_output(0, val);
  }

 private:
  int index_;
  DataType dtype_;

  TF_DISALLOW_COPY_AND_ASSIGN(ArgOp);
};

class RetvalOp : public OpKernel {
 public:
  explicit RetvalOp(OpKernelConstruction* ctx) : OpKernel(ctx) {
    OP_REQUIRES_OK(ctx, ctx->GetAttr("T", &dtype_));
    OP_REQUIRES_OK(ctx, ctx->GetAttr("index", &index_));
  }

  void Compute(OpKernelContext* ctx) override {
    const Tensor& val = ctx->input(0);
    OP_REQUIRES(ctx, val.dtype() == dtype_,
                errors::InvalidArgument(
                    "Type mismatch: actual ", DataTypeString(val.dtype()),
                    " vs. expect ", DataTypeString(dtype_)));
    auto frame = ctx->call_frame();
    OP_REQUIRES(ctx, frame != nullptr, errors::Internal("no call frame"));
    OP_REQUIRES_OK(ctx, frame->SetRetval(index_, val));
  }

 private:
  int index_;
  DataType dtype_;

  TF_DISALLOW_COPY_AND_ASSIGN(RetvalOp);
};

REGISTER_KERNEL_BUILDER(Name("_Arg").Device(DEVICE_CPU), ArgOp);
REGISTER_KERNEL_BUILDER(Name("_Retval").Device(DEVICE_CPU), RetvalOp);

#if TENSORFLOW_USE_SYCL
#define REGISTER(type)     \
  REGISTER_KERNEL_BUILDER( \
      Name("_Arg").Device(DEVICE_SYCL).TypeConstraint<type>("T"), ArgOp);
TF_CALL_NUMBER_TYPES_NO_INT32(REGISTER)
TF_CALL_bool(REGISTER) REGISTER_KERNEL_BUILDER(Name("_Arg")
                                                   .Device(DEVICE_GPU)
                                                   .HostMemory("output")
                                                   .TypeConstraint<int32>("T"),
                                               ArgOp);
#undef REGISTER
#define REGISTER(type)                                               \
  REGISTER_KERNEL_BUILDER(                                           \
      Name("_Retval").Device(DEVICE_SYCL).TypeConstraint<type>("T"), \
      RetvalOp);
TF_CALL_NUMBER_TYPES_NO_INT32(REGISTER)
TF_CALL_bool(REGISTER) REGISTER_KERNEL_BUILDER(Name("_Retval")
                                                   .Device(DEVICE_GPU)
                                                   .HostMemory("input")
                                                   .TypeConstraint<int32>("T"),
                                               RetvalOp);
#undef REGISTER
#endif

#define REGISTER(type)     \
  REGISTER_KERNEL_BUILDER( \
      Name("_Arg").Device(DEVICE_GPU).TypeConstraint<type>("T"), ArgOp);
TF_CALL_NUMBER_TYPES_NO_INT32(REGISTER)
TF_CALL_bool(REGISTER) REGISTER_KERNEL_BUILDER(Name("_Arg")
                                                   .Device(DEVICE_GPU)
                                                   .HostMemory("output")
                                                   .TypeConstraint<int32>("T"),
                                               ArgOp);
#undef REGISTER

#define REGISTER(type)     \
  REGISTER_KERNEL_BUILDER( \
      Name("_Retval").Device(DEVICE_GPU).TypeConstraint<type>("T"), RetvalOp);
TF_CALL_NUMBER_TYPES_NO_INT32(REGISTER)
TF_CALL_bool(REGISTER) REGISTER_KERNEL_BUILDER(Name("_Retval")
                                                   .Device(DEVICE_GPU)
                                                   .HostMemory("input")
                                                   .TypeConstraint<int32>("T"),
                                               RetvalOp);
#undef REGISTER

class PassOn : public OpKernel {
 public:
  explicit PassOn(OpKernelConstruction* ctx) : OpKernel(ctx) {
    OP_REQUIRES(ctx, ctx->num_inputs() == ctx->num_outputs(),
                errors::Internal("#inputs != #outputs : ", ctx->num_inputs(),
                                 " vs. ", ctx->num_outputs()));
    for (int i = 0; i < ctx->num_inputs(); ++i) {
      OP_REQUIRES(
          ctx, input_type(i) == output_type(i),
          errors::Internal("Input and output types for position ", i,
                           " do not match: ", DataTypeString(input_type(i)),
                           " vs. ", DataTypeString(output_type(i))));
    }
  }

  void Compute(OpKernelContext* ctx) override {
    for (int i = 0; i < ctx->num_inputs(); ++i) {
      ctx->set_output(i, ctx->input(i));
    }
  }
};

REGISTER_KERNEL_BUILDER(Name("_ListToArray").Device(DEVICE_CPU), PassOn);
REGISTER_KERNEL_BUILDER(Name("_ArrayToList").Device(DEVICE_CPU), PassOn);

#define REGISTER_GPU_KERNELS(type)                                       \
  REGISTER_KERNEL_BUILDER(                                               \
      Name("_ListToArray").Device(DEVICE_GPU).TypeConstraint<type>("T"), \
      PassOn);                                                           \
  REGISTER_KERNEL_BUILDER(                                               \
      Name("_ArrayToList").Device(DEVICE_GPU).TypeConstraint<type>("T"), \
      PassOn);

REGISTER_GPU_KERNELS(Eigen::half);
REGISTER_GPU_KERNELS(float);
REGISTER_GPU_KERNELS(double);

#undef REGISTER_GPU_KERNELS

REGISTER_KERNEL_BUILDER(Name("_ListToArray")
                            .Device(DEVICE_GPU)
                            .HostMemory("input")
                            .HostMemory("output")
                            .TypeConstraint<int32>("T"),
                        PassOn);
REGISTER_KERNEL_BUILDER(Name("_ArrayToList")
                            .Device(DEVICE_GPU)
                            .HostMemory("input")
                            .HostMemory("output")
                            .TypeConstraint<int32>("T"),
                        PassOn);

class SymbolicGradientOp : public AsyncOpKernel {
 public:
  SymbolicGradientOp(OpKernelConstruction* ctx)
      : AsyncOpKernel(ctx), handle_(-1) {}

  ~SymbolicGradientOp() override {}

  void ComputeAsync(OpKernelContext* ctx, DoneCallback done) override {
    FunctionLibraryRuntime* lib = ctx->function_library();
    OP_REQUIRES_ASYNC(ctx, lib != nullptr,
                      errors::Internal("No function library is provided."),
                      done);

    OP_REQUIRES_OK_ASYNC(
        ctx, lib->Instantiate(kGradientOp, def().attr(), &handle_), done);

    FunctionLibraryRuntime::Options opts;
    opts.step_id = ctx->step_id();
    opts.runner = ctx->runner();
    std::vector<Tensor> args;
    args.reserve(ctx->num_inputs());
    for (int i = 0; i < ctx->num_inputs(); ++i) {
      args.push_back(ctx->input(i));
    }
    std::vector<Tensor>* rets = new std::vector<Tensor>;
    lib->Run(
        opts, handle_, args, rets, [ctx, done, rets](const Status& status) {
          if (!status.ok()) {
            ctx->SetStatus(status);
          } else if (rets->size() != ctx->num_outputs()) {
            ctx->SetStatus(errors::InvalidArgument(
                "SymGrad expects to return ", ctx->num_outputs(),
                " tensor(s), but get ", rets->size(), " tensor(s) instead."));
          } else {
            for (size_t i = 0; i < rets->size(); ++i) {
              ctx->set_output(i, (*rets)[i]);
            }
          }
          delete rets;
          done();
        });
  }

 private:
  FunctionLibraryRuntime::Handle handle_;

  TF_DISALLOW_COPY_AND_ASSIGN(SymbolicGradientOp);
};

REGISTER_KERNEL_BUILDER(Name(kGradientOp).Device(DEVICE_CPU),
                        SymbolicGradientOp);
REGISTER_KERNEL_BUILDER(Name(kGradientOp).Device(DEVICE_GPU),
                        SymbolicGradientOp);
#if TENSORFLOW_USE_SYCL
REGISTER_KERNEL_BUILDER(Name(kGradientOp).Device(DEVICE_SYCL),
                        SymbolicGradientOp);

#endif
}  // namespace tensorflow
<|endoftext|>


<commit_before>/*
* this file is part of the oxygen gtk engine
* Copyright (c) 2010 Hugo Pereira Da Costa <hugo@oxygen-icons.org>
*
* inspired notably from kdelibs/kdeui/color/kcolorutils.h
* Copyright (C) 2007 Matthew Woehlke <mw_triad@users.sourceforge.net>
* Copyright (C) 2007 Thomas Zander <zander@kde.org>
* Copyright (C) 2007 Zack Rusin <zack@kde.org>
*
* This  library is free  software; you can  redistribute it and/or
* modify it  under  the terms  of the  GNU Lesser  General  Public
* License  as published  by the Free  Software  Foundation; either
* version 2 of the License, or( at your option ) any later version.
*
* This library is distributed  in the hope that it will be useful,
* but  WITHOUT ANY WARRANTY; without even  the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License  along  with  this library;  if not,  write to  the Free
* Software Foundation, Inc., 51  Franklin St, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/

#include "oxygenapplicationname.h"
#include "oxygengtkutils.h"
#include "config.h"

#include <fstream>
#include <iostream>
#include <sstream>

namespace Oxygen
{

    //__________________________________________________________________________
    void ApplicationName::initialize( void )
    {

        // get application name from gtk
        const std::string gtkAppName( fromGtk() );

        // get application name from pid
        const std::string pidAppName( fromPid( getpid() ) );

        #if OXYGEN_DEBUG
        std::cerr << "ApplicationName::initialize -"
            << " from pid: " << pidAppName
            << " from gtk: " << gtkAppName
            << std::endl;
        #endif

        if( pidAppName == "opera" ) _name = Opera;
        else if( pidAppName == "java" ) {

            if( !gtkAppName.empty() ) _name = JavaSwt;
            else _name = Java;

        } else if( gtkAppName == "acroread" ) _name = Acrobat;
        else if( gtkAppName.find("firefox") == 0 ) _name = Firefox;
        else if( gtkAppName.find("xulrunner") == 0 ) _name = Xul;
        else if( gtkAppName.find("thunderbird") == 0 ) _name = Thunderbird;
        else if( gtkAppName.find("seamonkey" ) == 0 ) _name = Seamonkey;
        else if( gtkAppName == "soffice" ) _name = OpenOffice;
        else if( gtkAppName == "gimp" ) _name = Gimp;
        else if(
            gtkAppName == "chromium" ||
            gtkAppName == "chromium-browser" ||
            gtkAppName == "google-chrome" ) _name = GoogleChrome;
        else if( gtkAppName == "eclipse" ) _name = Eclipse;
        else _name = Unknown;

    }

    //__________________________________________________________________________
    bool ApplicationName::isMozilla( GtkWidget* widget ) const
    {
        if( !isMozilla() ) return false;

        GtkWidget* parent( gtk_widget_get_toplevel( widget ) );

        // check parent
        if( parent && GTK_IS_DIALOG( parent ) ) return false;
        else return true;

    }

    //__________________________________________________________________________
    bool ApplicationName::isAcrobat( GtkWidget* widget ) const
    {
        if( !isAcrobat() ) return false;

        GtkWidget* parent( gtk_widget_get_toplevel( widget ) );

        // check parent
        if( parent && GTK_IS_DIALOG( parent ) ) return false;
        else return true;

    }
    //__________________________________________________________________________
    bool ApplicationName::isJavaSwt( GtkWidget* widget ) const
    {
        if( !isJavaSwt() ) return false;

        GtkWidget* parent( gtk_widget_get_toplevel( widget ) );

        // check parent
        if( parent && GTK_IS_DIALOG( parent ) ) return false;
        else return true;

    }

    //__________________________________________________________________________
    bool ApplicationName::useFlatBackground( GtkWidget* widget ) const
    {

        // first check parent
        GtkWidget* parent( gtk_widget_get_toplevel( widget ) );

        // check parent
        if( parent && GTK_IS_DIALOG( parent ) ) return false;
        else return
            isMozilla() ||
            isAcrobat() ||
            isJavaSwt() ||
            isOpenOffice() ||
            isEclipse();

    }

    //__________________________________________________________________________
    std::string ApplicationName::fromGtk( void ) const
    {
        if( const char* gtkAppName = g_get_prgname() ) return gtkAppName;
        else return "";
    }

    //__________________________________________________________________________
    std::string ApplicationName::fromPid( int pid ) const
    {

        // generate /proc filename
        std::ostringstream filename;
        filename << "/proc/" << pid << "/cmdline";

        // try read file
        std::ifstream in( filename.str().c_str() );
        if( !in ) return std::string();

        /*
        somehow std::getline gets some extra crap (non char) from the procfile
        one has to use ifstream::getline, and pass it a fixed size line
        */
        char lineC[1024];
        in.getline( lineC, 1024, '\n' );
        std::string line( lineC );

        // get position of last "/" character, and truncate accordingly
        const size_t pos = line.rfind( '/' );
        if( pos == std::string::npos ) return line;
        else return line.substr( pos+1 );

    }

}
<commit_msg>Fix eclipse detection after configuration rereading (gtkAppName changes from 'eclipse' to 'Eclipse' for some reason)<commit_after>/*
* this file is part of the oxygen gtk engine
* Copyright (c) 2010 Hugo Pereira Da Costa <hugo@oxygen-icons.org>
*
* inspired notably from kdelibs/kdeui/color/kcolorutils.h
* Copyright (C) 2007 Matthew Woehlke <mw_triad@users.sourceforge.net>
* Copyright (C) 2007 Thomas Zander <zander@kde.org>
* Copyright (C) 2007 Zack Rusin <zack@kde.org>
*
* This  library is free  software; you can  redistribute it and/or
* modify it  under  the terms  of the  GNU Lesser  General  Public
* License  as published  by the Free  Software  Foundation; either
* version 2 of the License, or( at your option ) any later version.
*
* This library is distributed  in the hope that it will be useful,
* but  WITHOUT ANY WARRANTY; without even  the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License  along  with  this library;  if not,  write to  the Free
* Software Foundation, Inc., 51  Franklin St, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/

#include "oxygenapplicationname.h"
#include "oxygengtkutils.h"
#include "config.h"

#include <fstream>
#include <iostream>
#include <sstream>

namespace Oxygen
{

    //__________________________________________________________________________
    void ApplicationName::initialize( void )
    {

        // get application name from gtk
        const std::string gtkAppName( fromGtk() );

        // get application name from pid
        const std::string pidAppName( fromPid( getpid() ) );

        #if OXYGEN_DEBUG
        std::cerr << "ApplicationName::initialize -"
            << " from pid: " << pidAppName
            << " from gtk: " << gtkAppName
            << std::endl;
        #endif

        if( pidAppName == "opera" ) _name = Opera;
        else if( pidAppName == "java" ) {

            if( !gtkAppName.empty() ) _name = JavaSwt;
            else _name = Java;

        } else if( gtkAppName == "acroread" ) _name = Acrobat;
        else if( gtkAppName.find("firefox") == 0 ) _name = Firefox;
        else if( gtkAppName.find("xulrunner") == 0 ) _name = Xul;
        else if( gtkAppName.find("thunderbird") == 0 ) _name = Thunderbird;
        else if( gtkAppName.find("seamonkey" ) == 0 ) _name = Seamonkey;
        else if( gtkAppName == "soffice" ) _name = OpenOffice;
        else if( gtkAppName == "gimp" ) _name = Gimp;
        else if(
            gtkAppName == "chromium" ||
            gtkAppName == "chromium-browser" ||
            gtkAppName == "google-chrome" ) _name = GoogleChrome;
        else if( gtkAppName == "eclipse" || gtkAppName == "Eclipse" ) _name = Eclipse;
        else _name = Unknown;

    }

    //__________________________________________________________________________
    bool ApplicationName::isMozilla( GtkWidget* widget ) const
    {
        if( !isMozilla() ) return false;

        GtkWidget* parent( gtk_widget_get_toplevel( widget ) );

        // check parent
        if( parent && GTK_IS_DIALOG( parent ) ) return false;
        else return true;

    }

    //__________________________________________________________________________
    bool ApplicationName::isAcrobat( GtkWidget* widget ) const
    {
        if( !isAcrobat() ) return false;

        GtkWidget* parent( gtk_widget_get_toplevel( widget ) );

        // check parent
        if( parent && GTK_IS_DIALOG( parent ) ) return false;
        else return true;

    }
    //__________________________________________________________________________
    bool ApplicationName::isJavaSwt( GtkWidget* widget ) const
    {
        if( !isJavaSwt() ) return false;

        GtkWidget* parent( gtk_widget_get_toplevel( widget ) );

        // check parent
        if( parent && GTK_IS_DIALOG( parent ) ) return false;
        else return true;

    }

    //__________________________________________________________________________
    bool ApplicationName::useFlatBackground( GtkWidget* widget ) const
    {

        // first check parent
        GtkWidget* parent( gtk_widget_get_toplevel( widget ) );

        // check parent
        if( parent && GTK_IS_DIALOG( parent ) ) return false;
        else return
            isMozilla() ||
            isAcrobat() ||
            isJavaSwt() ||
            isOpenOffice() ||
            isEclipse();

    }

    //__________________________________________________________________________
    std::string ApplicationName::fromGtk( void ) const
    {
        if( const char* gtkAppName = g_get_prgname() ) return gtkAppName;
        else return "";
    }

    //__________________________________________________________________________
    std::string ApplicationName::fromPid( int pid ) const
    {

        // generate /proc filename
        std::ostringstream filename;
        filename << "/proc/" << pid << "/cmdline";

        // try read file
        std::ifstream in( filename.str().c_str() );
        if( !in ) return std::string();

        /*
        somehow std::getline gets some extra crap (non char) from the procfile
        one has to use ifstream::getline, and pass it a fixed size line
        */
        char lineC[1024];
        in.getline( lineC, 1024, '\n' );
        std::string line( lineC );

        // get position of last "/" character, and truncate accordingly
        const size_t pos = line.rfind( '/' );
        if( pos == std::string::npos ) return line;
        else return line.substr( pos+1 );

    }

}
<|endoftext|>