216 lines
6.9 KiB
C++
216 lines
6.9 KiB
C++
/**
|
|
* @file thor_utils.h
|
|
*
|
|
* Top-level THOR utilities that take care of more high-level actions.
|
|
*
|
|
* This contains functions to read data and to execute a generalized N-body
|
|
* problem in parallel.
|
|
*/
|
|
|
|
#ifndef THOR_UTILS_H
|
|
#define THOR_UTILS_H
|
|
|
|
#include "kdtree.h"
|
|
#include "sched.h"
|
|
#include "rpc.h"
|
|
|
|
#include "par/thread.h"
|
|
#include "par/task.h"
|
|
|
|
#include "distribcache.h"
|
|
|
|
namespace thor {
|
|
|
|
/**
|
|
* Class used to run a multi-threaded dual-tree algorithm.
|
|
*
|
|
* It is probably easier to use thor::RpcDualTree even if you are on just
|
|
* one machine, and it's no more or less efficient either way.
|
|
*
|
|
* Template paramters:
|
|
* @li GNP - the THOR-compatible generalized N-body class
|
|
* @li Solver - a solver such as DualTreeDepthFirst<GNP>
|
|
*/
|
|
template<typename GNP, typename Solver>
|
|
class ThreadedDualTreeSolver {
|
|
private:
|
|
struct WorkerTask : public Task {
|
|
ThreadedDualTreeSolver *solver;
|
|
WorkerTask(ThreadedDualTreeSolver *solver_in) : solver(solver_in) { }
|
|
void Run() { solver->ThreadBody_(); delete this; }
|
|
};
|
|
|
|
private:
|
|
int rank_;
|
|
const typename GNP::Param *param_;
|
|
SchedulerInterface *work_queue_;
|
|
DistributedCache *q_points_cache_;
|
|
DistributedCache *q_nodes_cache_;
|
|
DistributedCache *r_points_cache_;
|
|
DistributedCache *r_nodes_cache_;
|
|
DistributedCache *q_results_cache_;
|
|
typename GNP::GlobalResult global_result_;
|
|
DualTreeRecursionStats stats_;
|
|
Mutex mutex_;
|
|
|
|
public:
|
|
/**
|
|
* Runs a multi-threaded dual-tree problem.
|
|
*
|
|
* @param n_threads the number of threads to run on this machine
|
|
* @param rank the rank of the current machine (rpc::rank() will provide
|
|
* this if RPC is being used, otherwise just specify 0)
|
|
* @param work_queue_in the work queue to get work items from
|
|
* @param param the parameter object for the GNP
|
|
* @param q_points_cache_in the cache containing query points
|
|
* @param q_nodes_cache_in the cache containing the query tree
|
|
* @param r_points_cache_in the cache containing reference points
|
|
* @param r_nodes_cache_in the cache containing the reference tree
|
|
* @param q_results_cache_in the cache containing per-query results.
|
|
*/
|
|
void Doit(index_t n_threads, int rank, SchedulerInterface *work_queue_in,
|
|
const typename GNP::Param& param,
|
|
DistributedCache *q_points_cache_in, DistributedCache *q_nodes_cache_in,
|
|
DistributedCache *r_points_cache_in, DistributedCache *r_nodes_cache_in,
|
|
DistributedCache *q_results_cache_in);
|
|
|
|
/**
|
|
* Gets the GNP's global-result of the entire computation.
|
|
*/
|
|
const typename GNP::GlobalResult& global_result() const {
|
|
return global_result_;
|
|
}
|
|
|
|
/**
|
|
* Recursion statistics.
|
|
*/
|
|
const DualTreeRecursionStats& stats() const {
|
|
return stats_;
|
|
}
|
|
|
|
private:
|
|
void ThreadBody_();
|
|
};
|
|
|
|
/**
|
|
* An rpc-style reductor suitable for condensing global results.
|
|
*
|
|
* Template parameter GNP is the generalized N-body problem containing
|
|
* nested classes Param and GlobalResult.
|
|
*/
|
|
template<typename GNP>
|
|
class GlobalResultReductor {
|
|
private:
|
|
const typename GNP::Param *param_;
|
|
|
|
public:
|
|
/** Initializes the reductor for a given parameter object. */
|
|
void Init(const typename GNP::Param* param_in) {
|
|
param_ = param_in;
|
|
}
|
|
|
|
/**
|
|
* Reduces two elements.
|
|
*
|
|
* @param right a new element to merge
|
|
* @param left the element to merge into
|
|
*/
|
|
void Reduce(typename GNP::GlobalResult& right,
|
|
typename GNP::GlobalResult* left) const {
|
|
left->Accumulate(*param_, right);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Reads points in a data set, just for the master machine.
|
|
*
|
|
* This does all the actual reading into the cache but doesn't do any
|
|
* syncing. It's recommended to just use thor::ReadPoints.
|
|
*
|
|
* Template parameters:
|
|
* @li @c Point - a conformant point type (see gnp.h)
|
|
* @li @c Param - a parameter object used for initializing points
|
|
*/
|
|
template<typename Point, typename Param>
|
|
index_t ReadPointsMaster(
|
|
const Param& param, int points_channel,
|
|
const char *filename, int block_size_kb, double megs,
|
|
DistributedCache *points_cache);
|
|
|
|
/**
|
|
* Reads data points from a file into a data set.
|
|
*
|
|
* The Point object must contain the suitable Init and Set method as does
|
|
* the class ThorVectorPoint in gnp.h.
|
|
*
|
|
* This takes in a module, such that the module's root parameter is the
|
|
* filename. There is optionally another parameter "block_size_kb" which
|
|
* is the maximum block size in kilobytes, and "megs" which is the minimum
|
|
* number of megabytes to dedicate to the cache.
|
|
*
|
|
* Aborts program on error.
|
|
*
|
|
* Template parameters:
|
|
* @li @c Point - a conformant point type (see gnp.h)
|
|
* @li @c Param - a parameter object used for initializing points
|
|
*
|
|
* @param param the parameter object used for initializing the points
|
|
* @param points_channel an rpc channel number that can be used for points
|
|
* @param extra_channel a free channel used for internal purposes
|
|
* @param module parameters (see above)
|
|
* @param points_cache an uninitialized cache that will contain the points
|
|
*
|
|
* @return the number of points read
|
|
*/
|
|
template<typename Point, typename Param>
|
|
index_t ReadPoints(
|
|
const Param& param, int points_channel, int extra_channel,
|
|
datanode *module, DistributedCache *points_cache);
|
|
|
|
/**
|
|
* Does a distributed dual-tree computation.
|
|
*
|
|
* @param module where to get tuning parameters from and store results in
|
|
* @param base_channel the begin of a range of 10 free channels
|
|
* @param param the gnp parameters
|
|
* @param q the query tree
|
|
* @param r the reference tree
|
|
* @param q_results the query results
|
|
* @param global_result_out (output) if non-NULL, it will be initialized to the
|
|
* global result on the root machine; on other machines, this will
|
|
* correspond to a global result of the machine's subtree of processors
|
|
* (probably not useful to you)
|
|
*/
|
|
template<typename GNP, typename SerialSolver, typename QTree, typename RTree>
|
|
void RpcDualTree(datanode *module, int base_channel,
|
|
const typename GNP::Param& param, QTree *q, RTree *r,
|
|
DistributedCache *q_results,
|
|
typename GNP::GlobalResult *global_result_out);
|
|
|
|
/**
|
|
* A "cookie-cutter" main for monochromatic dual tree problems.
|
|
*
|
|
* The @c gnp_name parameter specifies a short name of the problem solved.
|
|
* If @c gnp_name is @c kde, then for example the @c Param object will
|
|
* be initialized with the datanode in @c kde, so on the command line you
|
|
* might type @c kde/bandwidth=1.
|
|
*
|
|
* Other parameters:
|
|
* @li @c n_threads - the number of threads (defaults to 2)
|
|
* @li @c data - the data file, with sub-parameters explained in
|
|
* thor::ReadPoints such as @c data/block_size_kb or @c data/megs
|
|
* @li @c tree - parameters for tree building, such as @c tree/block_size_kb,
|
|
* @c tree/megs, and @c tree/leaf_size.
|
|
*
|
|
* @param module where to read parameters (explained above)
|
|
* @param gnp_name a short textual name of the GNP
|
|
*/
|
|
template<typename GNP, typename Solver>
|
|
void MonochromaticDualTreeMain(datanode *module, const char *gnp_name);
|
|
|
|
}; // end namespace
|
|
|
|
#include "thor_utils_impl.h"
|
|
|
|
#endif
|