| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| |
|
| | #ifndef MPI_SERVER_H_ |
| | #define MPI_SERVER_H_ |
| |
|
| | #include <FLANN/mpi/index.h> |
| | #include <stdio.h> |
| | #include <time.h> |
| |
|
| | #include <cstdlib> |
| | #include <iostream> |
| | #include <boost/bind.hpp> |
| | #include <boost/shared_ptr.hpp> |
| | #include <boost/asio.hpp> |
| | #include <boost/thread/thread.hpp> |
| |
|
| | #include "queries.h" |
| |
|
| | namespace flann { |
| |
|
| | namespace mpi { |
| |
|
| | template<typename Distance> |
| | class Server |
| | { |
| |
|
| | typedef typename Distance::ElementType ElementType; |
| | typedef typename Distance::ResultType DistanceType; |
| | typedef boost::shared_ptr<tcp::socket> socket_ptr; |
| | typedef flann::mpi::Index<Distance> FlannIndex; |
| |
|
| | void session(socket_ptr sock) |
| | { |
| | boost::mpi::communicator world; |
| | try { |
| | Request<ElementType> req; |
| | if (world.rank()==0) { |
| | read_object(*sock,req); |
| | std::cout << "Received query\n"; |
| | } |
| | |
| | boost::mpi::broadcast(world, req, 0); |
| |
|
| | Response<DistanceType> resp; |
| | if (world.rank()==0) { |
| | int rows = req.queries.rows; |
| | int cols = req.nn; |
| | resp.indices = flann::Matrix<int>(new int[rows*cols], rows, cols); |
| | resp.dists = flann::Matrix<DistanceType>(new DistanceType[rows*cols], rows, cols); |
| | } |
| |
|
| | std::cout << "Searching in process " << world.rank() << "\n"; |
| | index_->knnSearch(req.queries, resp.indices, resp.dists, req.nn, flann::SearchParams(req.checks)); |
| |
|
| | if (world.rank()==0) { |
| | std::cout << "Sending result\n"; |
| | write_object(*sock,resp); |
| | } |
| |
|
| | delete[] req.queries.ptr(); |
| | if (world.rank()==0) { |
| | delete[] resp.indices.ptr(); |
| | delete[] resp.dists.ptr(); |
| | } |
| |
|
| | } |
| | catch (std::exception& e) { |
| | std::cerr << "Exception in thread: " << e.what() << "\n"; |
| | } |
| | } |
| |
|
| |
|
| |
|
| | public: |
| | Server(const std::string& filename, const std::string& dataset, short port, const IndexParams& params) : |
| | port_(port) |
| | { |
| | boost::mpi::communicator world; |
| | if (world.rank()==0) { |
| | std::cout << "Reading dataset and building index..."; |
| | std::flush(std::cout); |
| | } |
| | index_ = new FlannIndex(filename, dataset, params); |
| | index_->buildIndex(); |
| | world.barrier(); |
| | if (world.rank()==0) { |
| | std::cout << "done.\n"; |
| | } |
| | } |
| |
|
| |
|
| | void run() |
| | { |
| | boost::mpi::communicator world; |
| | boost::shared_ptr<boost::asio::io_service> io_service; |
| | boost::shared_ptr<tcp::acceptor> acceptor; |
| |
|
| | if (world.rank()==0) { |
| | io_service.reset(new boost::asio::io_service()); |
| | acceptor.reset(new tcp::acceptor(*io_service, tcp::endpoint(tcp::v4(), port_))); |
| | std::cout << "Start listening for queries...\n"; |
| | } |
| | for (;;) { |
| | socket_ptr sock; |
| | if (world.rank()==0) { |
| | sock.reset(new tcp::socket(*io_service)); |
| | acceptor->accept(*sock); |
| | std::cout << "Accepted connection\n"; |
| | } |
| | world.barrier(); |
| | boost::thread t(boost::bind(&Server::session, this, sock)); |
| | t.join(); |
| | } |
| |
|
| | } |
| |
|
| | private: |
| | FlannIndex* index_; |
| | short port_; |
| | }; |
| |
|
| |
|
| | } |
| | } |
| |
|
| | #endif |
| |
|