reworking distrib infrastructure; server still terminates execution prematurely
git-svn-id: svn://anubis/fart/trunk@237 7f9b0f55-74a9-4bce-be96-3c2cd072584d
This commit is contained in:
parent
e21d948d52
commit
5264f1de7e
146
main/Scene.cc
146
main/Scene.cc
@ -22,14 +22,10 @@ Scene::Scene(const map<string, const char *> & options,
|
||||
m_width = 800;
|
||||
m_height = 600;
|
||||
m_multisample_level = 1;
|
||||
m_output_file_name = "fart.bmp";
|
||||
m_vfov = 60.0;
|
||||
m_verbose = true;
|
||||
m_data = NULL;
|
||||
m_ambient_light = Color(0.2, 0.2, 0.2);
|
||||
m_max_depth = 10;
|
||||
m_transforms.push(Transform());
|
||||
m_server = true;
|
||||
|
||||
load(filename);
|
||||
|
||||
@ -41,79 +37,23 @@ Scene::Scene(const map<string, const char *> & options,
|
||||
if (it->first == "width")
|
||||
{
|
||||
m_width = atoi(it->second);
|
||||
m_client_options.push_back("--width");
|
||||
m_client_options.push_back(it->second);
|
||||
}
|
||||
else if (it->first == "height")
|
||||
{
|
||||
m_height = atoi(it->second);
|
||||
m_client_options.push_back("--height");
|
||||
m_client_options.push_back(it->second);
|
||||
}
|
||||
else if (it->first == "multisample")
|
||||
{
|
||||
m_multisample_level = atoi(it->second);
|
||||
m_client_options.push_back("--multisample");
|
||||
m_client_options.push_back(it->second);
|
||||
}
|
||||
else if (it->first == "field-of-view")
|
||||
{
|
||||
m_vfov = atof(it->second);
|
||||
m_client_options.push_back("--field-of-view");
|
||||
m_client_options.push_back(it->second);
|
||||
}
|
||||
else if (it->first == "output-file")
|
||||
{
|
||||
m_output_file_name = it->second;
|
||||
/* no client option necessary */
|
||||
}
|
||||
else if (it->first == "max-depth")
|
||||
{
|
||||
m_max_depth = atoi(it->second);
|
||||
m_client_options.push_back("--max-depth");
|
||||
m_client_options.push_back(it->second);
|
||||
}
|
||||
else if (it->first == "verbose")
|
||||
{
|
||||
m_verbose = true;
|
||||
/* no client option necessary */
|
||||
}
|
||||
else if (it->first == "host")
|
||||
{
|
||||
m_server_name = it->second;
|
||||
m_server = false;
|
||||
/* no client option necessary */
|
||||
}
|
||||
else if (it->first == "port")
|
||||
{
|
||||
m_server_port = atoi(it->second);
|
||||
/* no client option necessary */
|
||||
}
|
||||
else if (it->first == "hosts")
|
||||
{
|
||||
m_hosts_file = it->second;
|
||||
/* no client option necessary */
|
||||
}
|
||||
}
|
||||
m_client_options.push_back(filename);
|
||||
|
||||
/* start the distribution infrastructure */
|
||||
if (m_server)
|
||||
{
|
||||
if (m_hosts_file != "")
|
||||
m_distrib.readHostFile(m_hosts_file.c_str());
|
||||
m_distrib.startServer();
|
||||
m_distrib.startClients(m_client_options);
|
||||
|
||||
m_data = new unsigned char[m_width * m_height * 3]; /* 24bpp */
|
||||
int num_tasks = (m_width * m_height + (UNIT_TASK_SIZE - 1))
|
||||
/ UNIT_TASK_SIZE;
|
||||
m_distrib.set_num_tasks(num_tasks);
|
||||
m_distrib.set_data(m_data, 3 * m_width * m_height);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_distrib.startClient(m_server_name.c_str(), m_server_port);
|
||||
}
|
||||
|
||||
/* view plane distance is calculated based on the field of view */
|
||||
@ -125,92 +65,6 @@ Scene::Scene(const map<string, const char *> & options,
|
||||
|
||||
Scene::~Scene()
|
||||
{
|
||||
if (m_data != NULL)
|
||||
delete m_data;
|
||||
}
|
||||
|
||||
void Scene::render()
|
||||
{
|
||||
if (m_server)
|
||||
{
|
||||
/* server version */
|
||||
if (m_verbose)
|
||||
{
|
||||
cout << " *** Beginning scene render ***" << endl;
|
||||
cout << "Parameters:" << endl;
|
||||
cout << "----------------------------------------" << endl;
|
||||
cout << " Width: " << m_width << endl;
|
||||
cout << " Height: " << m_height << endl;
|
||||
cout << " Multisample Level: " << m_multisample_level << endl;
|
||||
cout << " Vertical Field of View: " << m_vfov << endl;
|
||||
cout << "----------------------------------------" << endl;
|
||||
}
|
||||
|
||||
if (m_distrib.getNumClients() < 1)
|
||||
{
|
||||
for (int i = 0; i < m_height; i++)
|
||||
{
|
||||
for (int j = 0; j < m_width; j++)
|
||||
{
|
||||
renderPixel(j, i, &m_data[3 * (m_width * i + j)]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* work on tasks in this thread until there are no more */
|
||||
taskLoop();
|
||||
/* TODO: change wait condition */
|
||||
for (;;)
|
||||
{
|
||||
if (m_distrib.getNumTasksInProgress() == 0)
|
||||
break;
|
||||
usleep(100000);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_verbose)
|
||||
{
|
||||
cout << " *** Ending scene render ***" << endl;
|
||||
cout << "Writing output file '" << m_output_file_name
|
||||
<< '\'' << endl;
|
||||
}
|
||||
BMP outputImage(m_output_file_name.c_str(), m_width, m_height, m_data);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* client version */
|
||||
taskLoop();
|
||||
}
|
||||
}
|
||||
|
||||
void Scene::taskLoop()
|
||||
{
|
||||
unsigned char data[3 * UNIT_TASK_SIZE];
|
||||
for (;;)
|
||||
{
|
||||
int task_id = m_distrib.getTask();
|
||||
if (task_id < 0)
|
||||
break;
|
||||
int pixel = task_id * UNIT_TASK_SIZE;
|
||||
int i = pixel / m_width;
|
||||
int j = pixel % m_width;
|
||||
for (int t = 0; t < UNIT_TASK_SIZE; t++)
|
||||
{
|
||||
renderPixel(j, i, &data[3 * t]);
|
||||
j++;
|
||||
if (j >= m_width)
|
||||
{
|
||||
j = 0;
|
||||
i++;
|
||||
if (i >= m_height)
|
||||
break;
|
||||
}
|
||||
}
|
||||
int ret = m_distrib.send_data(task_id, data, 3 * UNIT_TASK_SIZE);
|
||||
if (ret != 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Scene::renderPixel(int x, int y, unsigned char * pixel)
|
||||
|
23
main/Scene.h
23
main/Scene.h
@ -13,8 +13,6 @@
|
||||
#include "util/Color.h"
|
||||
#include "util/Material.h"
|
||||
|
||||
#include "distrib/distrib.h"
|
||||
|
||||
#include "shapes/shapes.h"
|
||||
|
||||
#include "parser/parser.h"
|
||||
@ -30,16 +28,19 @@ class Scene
|
||||
Scene(const std::map<std::string, const char *> & options,
|
||||
const char * filename);
|
||||
~Scene();
|
||||
void render();
|
||||
void setWidth(int width) { m_width = width; }
|
||||
void setHeight(int height) { m_height = height; }
|
||||
void setMultisampleLevel(int level) { m_multisample_level = level; }
|
||||
void setVFOV(double vfov) { m_vfov = vfov; }
|
||||
void setAmbientLight(const Color & al) { m_ambient_light = al; }
|
||||
void renderPixel(int x, int y, unsigned char * pixel);
|
||||
int getWidth() { return m_width; }
|
||||
int getHeight() { return m_height; }
|
||||
int getMultisampleLevel() { return m_multisample_level; }
|
||||
double getVFOV() { return m_vfov; }
|
||||
|
||||
protected:
|
||||
/* private methods */
|
||||
void renderPixel(int x, int y, unsigned char * pixel);
|
||||
Color traceRay(const Ray & ray);
|
||||
Color traceRayRecurse(const Ray & ray, int depth, double factor);
|
||||
Shape::Intersection getRayClosestHit(const Ray & ray);
|
||||
@ -49,7 +50,6 @@ class Scene
|
||||
const Vector & surfaceNormal);
|
||||
Color calculateLightContribution(const Ray & toLight,
|
||||
refptr<Light> light);
|
||||
void taskLoop();
|
||||
|
||||
/* In Scene-load.cc */
|
||||
void load(const char * filename);
|
||||
@ -74,8 +74,6 @@ class Scene
|
||||
int m_width;
|
||||
int m_height;
|
||||
int m_multisample_level;
|
||||
std::string m_output_file_name;
|
||||
bool m_verbose;
|
||||
double m_vfov;
|
||||
Color m_ambient_light;
|
||||
int m_max_depth;
|
||||
@ -89,17 +87,6 @@ class Scene
|
||||
double m_sample_span;
|
||||
double m_half_sample_span;
|
||||
std::map< std::string, refptr<Material> > m_materials;
|
||||
|
||||
/* distribution infrastructure */
|
||||
bool m_server;
|
||||
std::string m_server_name;
|
||||
std::string m_hosts_file;
|
||||
int m_server_port;
|
||||
distrib m_distrib;
|
||||
std::vector<std::string> m_client_options;
|
||||
|
||||
/* framebuffer */
|
||||
unsigned char * m_data;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
134
main/fart.cc
134
main/fart.cc
@ -8,6 +8,8 @@
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include "Scene.h"
|
||||
#include "distrib/distrib.h"
|
||||
#include "BMP.h"
|
||||
using namespace std;
|
||||
|
||||
void usage(const char * progname)
|
||||
@ -21,7 +23,6 @@ void usage(const char * progname)
|
||||
cout << " -f|--field-of-view <vertical-fov>" << endl;
|
||||
cout << " -d|--max-depth <max-recursion-depth>" << endl;
|
||||
cout << " --hosts <hosts-file>" << endl;
|
||||
cout << " -v|--verbose" << endl;
|
||||
exit(42);
|
||||
}
|
||||
|
||||
@ -30,7 +31,14 @@ int main(int argc, char * argv[])
|
||||
int opt;
|
||||
int option_index;
|
||||
map<string, const char *> scene_options;
|
||||
vector<string> client_options;
|
||||
bool server = true;
|
||||
bool distributed = false;
|
||||
const char * hosts_file = NULL;
|
||||
const char * server_name = NULL;
|
||||
int server_port = 0;
|
||||
unsigned char * data = NULL;
|
||||
const char * output_file_name = NULL;
|
||||
|
||||
static const struct option long_options[] = {
|
||||
{ "output-file", required_argument, NULL, 'o' },
|
||||
@ -39,7 +47,6 @@ int main(int argc, char * argv[])
|
||||
{ "multisample", required_argument, NULL, 'm' },
|
||||
{ "field-of-view", required_argument, NULL, 'f' },
|
||||
{ "max-depth", required_argument, NULL, 'd' },
|
||||
{ "verbose", no_argument, NULL, 'v' },
|
||||
{ "help", no_argument, NULL, 256 },
|
||||
{ "host", required_argument, NULL, 257 },
|
||||
{ "port", required_argument, NULL, 258 },
|
||||
@ -47,44 +54,54 @@ int main(int argc, char * argv[])
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
while ((opt = getopt_long(argc, argv, "o:w:h:m:f:d:v",
|
||||
while ((opt = getopt_long(argc, argv, "o:w:h:m:f:d:",
|
||||
long_options, &option_index)) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'o':
|
||||
scene_options["output-file"] = optarg;
|
||||
output_file_name = optarg;
|
||||
break;
|
||||
case 'w':
|
||||
scene_options["width"] = optarg;
|
||||
client_options.push_back("--width");
|
||||
client_options.push_back(optarg);
|
||||
break;
|
||||
case 'h':
|
||||
scene_options["height"] = optarg;
|
||||
client_options.push_back("--height");
|
||||
client_options.push_back(optarg);
|
||||
break;
|
||||
case 'm':
|
||||
scene_options["multisample"] = optarg;
|
||||
client_options.push_back("--multisample");
|
||||
client_options.push_back(optarg);
|
||||
break;
|
||||
case 'f':
|
||||
scene_options["field-of-view"] = optarg;
|
||||
client_options.push_back("--field-of-view");
|
||||
client_options.push_back(optarg);
|
||||
break;
|
||||
case 'd':
|
||||
scene_options["max-depth"] = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
scene_options["verbose"] = optarg;
|
||||
client_options.push_back("--max-depth");
|
||||
client_options.push_back(optarg);
|
||||
break;
|
||||
case 256:
|
||||
usage(argv[0]);
|
||||
break;
|
||||
case 257:
|
||||
scene_options["host"] = optarg;
|
||||
server_name = optarg;
|
||||
server = false;
|
||||
distributed = true;
|
||||
break;
|
||||
case 258:
|
||||
scene_options["port"] = optarg;
|
||||
server_port = atoi(optarg);
|
||||
distributed = true;
|
||||
break;
|
||||
case 259:
|
||||
scene_options["hosts"] = optarg;
|
||||
hosts_file = optarg;
|
||||
distributed = true;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
@ -97,17 +114,110 @@ int main(int argc, char * argv[])
|
||||
usage(argv[0]);
|
||||
}
|
||||
|
||||
Scene scene(scene_options, argv[optind]);
|
||||
const char * filename = argv[optind];
|
||||
client_options.push_back(filename);
|
||||
Scene scene(scene_options, filename);
|
||||
|
||||
const int width = scene.getWidth();
|
||||
const int height = scene.getHeight();
|
||||
|
||||
if (server)
|
||||
{
|
||||
/* allocate data for the image */
|
||||
data = new unsigned char[3 * width * height];
|
||||
|
||||
cout << " *** Beginning scene render ***" << endl;
|
||||
cout << "Parameters:" << endl;
|
||||
cout << "----------------------------------------" << endl;
|
||||
cout << " Width: " << width << endl;
|
||||
cout << " Height: " << height << endl;
|
||||
cout << " Multisample Level: " << scene.getMultisampleLevel() << endl;
|
||||
cout << " Vertical Field of View: " << scene.getVFOV() << endl;
|
||||
cout << "----------------------------------------" << endl;
|
||||
}
|
||||
|
||||
struct timeval before, after;
|
||||
gettimeofday(&before, NULL); /* start timing */
|
||||
|
||||
scene.render();
|
||||
#if 0
|
||||
void Scene::taskLoop()
|
||||
{
|
||||
unsigned char data[3 * UNIT_TASK_SIZE];
|
||||
for (;;)
|
||||
{
|
||||
int task_id = m_distrib.getTask();
|
||||
if (task_id < 0)
|
||||
break;
|
||||
int pixel = task_id * UNIT_TASK_SIZE;
|
||||
int i = pixel / m_width;
|
||||
int j = pixel % m_width;
|
||||
for (int t = 0; t < UNIT_TASK_SIZE; t++)
|
||||
{
|
||||
renderPixel(j, i, &data[3 * t]);
|
||||
j++;
|
||||
if (j >= m_width)
|
||||
{
|
||||
j = 0;
|
||||
i++;
|
||||
if (i >= m_height)
|
||||
break;
|
||||
}
|
||||
}
|
||||
int ret = m_distrib.send_data(task_id, data, 3 * UNIT_TASK_SIZE);
|
||||
if (ret != 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (distributed)
|
||||
{
|
||||
/* start the distribution infrastructure */
|
||||
distrib the_distrib;
|
||||
if (server)
|
||||
{
|
||||
if (strcmp(hosts_file, ""))
|
||||
the_distrib.readHostFile(hosts_file);
|
||||
|
||||
int num_tasks = (width * height + (UNIT_TASK_SIZE - 1))
|
||||
/ UNIT_TASK_SIZE;
|
||||
the_distrib.set_num_tasks(num_tasks);
|
||||
the_distrib.set_data(data, 3 * width * height);
|
||||
|
||||
the_distrib.startServer();
|
||||
the_distrib.startClients(client_options);
|
||||
/* TODO: wait until all tasks are complete */
|
||||
}
|
||||
else
|
||||
{
|
||||
the_distrib.startClient(server_name, server_port);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* "sequential" version */
|
||||
unsigned char * pixel = &data[0];
|
||||
for (int i = 0; i < height; i++)
|
||||
{
|
||||
for (int j = 0; j < width; j++)
|
||||
{
|
||||
scene.renderPixel(j, i, pixel);
|
||||
pixel += 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gettimeofday(&after, NULL); /* stop timing */
|
||||
|
||||
if (server)
|
||||
{
|
||||
cout << " *** Ending scene render ***" << endl;
|
||||
cout << "Writing output file '" << output_file_name << '\'' << endl;
|
||||
|
||||
/* write the image */
|
||||
BMP outputImage(output_file_name, width, height, data);
|
||||
|
||||
/* print how much time has elapsed */
|
||||
double time_before = before.tv_sec + before.tv_usec / 1000000.0;
|
||||
double time_after = after.tv_sec + after.tv_usec / 1000000.0;
|
||||
double total_seconds = time_after - time_before;
|
||||
|
Loading…
x
Reference in New Issue
Block a user