2012-10-22 07:22:42 +08:00
|
|
|
// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
|
|
|
|
/*
|
|
|
|
|
|
|
|
This is an example illustrating the use of the Bulk Synchronous Parallel
|
|
|
|
processing tools from the dlib C++ Library.
|
|
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "dlib/cmd_line_parser.h"
|
|
|
|
#include "dlib/bsp.h"
|
|
|
|
#include "dlib/matrix.h"
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
|
|
|
|
typedef dlib::cmd_line_parser<char>::check_1a_c clp_parser;
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
using namespace dlib;
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
double f ( double x)
|
|
|
|
{
|
|
|
|
return std::pow(x-2.0, 2.0);
|
|
|
|
}
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
void bsp_job_node_0 (
|
2012-10-22 07:40:19 +08:00
|
|
|
bsp_context& bsp,
|
2012-10-22 07:22:42 +08:00
|
|
|
double& min_value,
|
|
|
|
double& optimal_x
|
|
|
|
)
|
|
|
|
{
|
|
|
|
double left = -100;
|
|
|
|
double right = 100;
|
|
|
|
|
|
|
|
min_value = std::numeric_limits<double>::infinity();
|
|
|
|
double interval_width = std::abs(right-left);
|
|
|
|
|
2012-10-22 07:40:19 +08:00
|
|
|
for (int i = 0; i < 100; ++i)
|
2012-10-22 07:22:42 +08:00
|
|
|
{
|
2012-10-22 07:40:19 +08:00
|
|
|
bsp.broadcast(left);
|
|
|
|
bsp.broadcast(right);
|
2012-10-22 07:22:42 +08:00
|
|
|
|
2012-10-22 07:40:19 +08:00
|
|
|
for (unsigned int k = 1; k < bsp.number_of_nodes(); ++k)
|
2012-10-22 07:22:42 +08:00
|
|
|
{
|
|
|
|
std::pair<double,double> val;
|
2012-10-22 07:40:19 +08:00
|
|
|
bsp.receive(val);
|
2012-10-22 07:22:42 +08:00
|
|
|
if (val.second < min_value)
|
|
|
|
{
|
|
|
|
min_value = val.second;
|
|
|
|
optimal_x = val.first;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
interval_width *= 0.5;
|
|
|
|
left = optimal_x - interval_width/2;
|
|
|
|
right = optimal_x + interval_width/2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
void bsp_job_other_nodes (
|
2012-10-22 07:40:19 +08:00
|
|
|
bsp_context& bsp,
|
2012-10-22 07:22:42 +08:00
|
|
|
long grid_resolution
|
|
|
|
)
|
|
|
|
{
|
|
|
|
double left, right;
|
2012-10-22 07:40:19 +08:00
|
|
|
while (bsp.try_receive(left))
|
2012-10-22 07:22:42 +08:00
|
|
|
{
|
2012-10-22 07:40:19 +08:00
|
|
|
bsp.receive(right);
|
2012-10-22 07:22:42 +08:00
|
|
|
|
2012-10-22 07:40:19 +08:00
|
|
|
const double l = (bsp.node_id()-1)/(bsp.number_of_nodes()-1.0);
|
|
|
|
const double r = bsp.node_id() /(bsp.number_of_nodes()-1.0);
|
2012-10-22 07:22:42 +08:00
|
|
|
|
|
|
|
const double width = right-left;
|
|
|
|
const matrix<double> values_to_check = linspace(left+l*width, left+r*width, grid_resolution);
|
|
|
|
|
|
|
|
double best_x;
|
|
|
|
double best_val = std::numeric_limits<double>::infinity();
|
|
|
|
for (long j = 0; j < values_to_check.size(); ++j)
|
|
|
|
{
|
|
|
|
double temp = f(values_to_check(j));
|
|
|
|
if (temp < best_val)
|
|
|
|
{
|
|
|
|
best_val = temp;
|
|
|
|
best_x = values_to_check(j);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-10-22 07:40:19 +08:00
|
|
|
bsp.send(make_pair(best_x, best_val), 0);
|
2012-10-22 07:22:42 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
int main(int argc, char** argv)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
clp_parser parser;
|
|
|
|
parser.add_option("h","Display this help message.");
|
|
|
|
parser.add_option("l","Run as a listening BSP node.",1);
|
|
|
|
|
|
|
|
parser.parse(argc, argv);
|
|
|
|
parser.check_option_arg_range("l", 1, 65535);
|
|
|
|
|
|
|
|
if (parser.option("h"))
|
|
|
|
{
|
|
|
|
// display all the command line options
|
|
|
|
cout << "Usage: bsp_ex (-l port | <list of hosts>)\n";
|
|
|
|
parser.print_options(cout);
|
|
|
|
cout << endl;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (parser.option("l"))
|
|
|
|
{
|
|
|
|
const unsigned short listening_port = get_option(parser, "l", 0);
|
|
|
|
cout << "Listening in port " << listening_port << endl;
|
|
|
|
const long grid_resolution = 100;
|
|
|
|
bsp_listen(listening_port, bsp_job_other_nodes, grid_resolution);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (parser.number_of_arguments() == 0)
|
|
|
|
{
|
|
|
|
cout << "You must give some listening BSP nodes as arguments to this program!" << endl;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<network_address> hosts;
|
|
|
|
for (unsigned long i = 0; i < parser.number_of_arguments(); ++i)
|
|
|
|
hosts.push_back(parser[i]);
|
|
|
|
|
|
|
|
double min_value, optimal_x;
|
|
|
|
bsp_connect(hosts, bsp_job_node_0, dlib::ref(min_value), dlib::ref(optimal_x));
|
|
|
|
|
|
|
|
cout << "optimal_x: "<< optimal_x << endl;
|
|
|
|
cout << "min_value: "<< min_value << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
catch (std::exception& e)
|
|
|
|
{
|
|
|
|
cout << "error in main(): " << e.what() << endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|