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:
Josh Holtrop 2009-04-14 02:33:37 +00:00
parent e21d948d52
commit 5264f1de7e
3 changed files with 127 additions and 176 deletions

View File

@ -22,14 +22,10 @@ Scene::Scene(const map<string, const char *> & options,
m_width = 800; m_width = 800;
m_height = 600; m_height = 600;
m_multisample_level = 1; m_multisample_level = 1;
m_output_file_name = "fart.bmp";
m_vfov = 60.0; m_vfov = 60.0;
m_verbose = true;
m_data = NULL;
m_ambient_light = Color(0.2, 0.2, 0.2); m_ambient_light = Color(0.2, 0.2, 0.2);
m_max_depth = 10; m_max_depth = 10;
m_transforms.push(Transform()); m_transforms.push(Transform());
m_server = true;
load(filename); load(filename);
@ -41,79 +37,23 @@ Scene::Scene(const map<string, const char *> & options,
if (it->first == "width") if (it->first == "width")
{ {
m_width = atoi(it->second); m_width = atoi(it->second);
m_client_options.push_back("--width");
m_client_options.push_back(it->second);
} }
else if (it->first == "height") else if (it->first == "height")
{ {
m_height = atoi(it->second); m_height = atoi(it->second);
m_client_options.push_back("--height");
m_client_options.push_back(it->second);
} }
else if (it->first == "multisample") else if (it->first == "multisample")
{ {
m_multisample_level = atoi(it->second); 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") else if (it->first == "field-of-view")
{ {
m_vfov = atof(it->second); 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") else if (it->first == "max-depth")
{ {
m_max_depth = atoi(it->second); 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 */ /* 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() 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) void Scene::renderPixel(int x, int y, unsigned char * pixel)

View File

@ -13,8 +13,6 @@
#include "util/Color.h" #include "util/Color.h"
#include "util/Material.h" #include "util/Material.h"
#include "distrib/distrib.h"
#include "shapes/shapes.h" #include "shapes/shapes.h"
#include "parser/parser.h" #include "parser/parser.h"
@ -30,16 +28,19 @@ class Scene
Scene(const std::map<std::string, const char *> & options, Scene(const std::map<std::string, const char *> & options,
const char * filename); const char * filename);
~Scene(); ~Scene();
void render();
void setWidth(int width) { m_width = width; } void setWidth(int width) { m_width = width; }
void setHeight(int height) { m_height = height; } void setHeight(int height) { m_height = height; }
void setMultisampleLevel(int level) { m_multisample_level = level; } void setMultisampleLevel(int level) { m_multisample_level = level; }
void setVFOV(double vfov) { m_vfov = vfov; } void setVFOV(double vfov) { m_vfov = vfov; }
void setAmbientLight(const Color & al) { m_ambient_light = al; } 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: protected:
/* private methods */ /* private methods */
void renderPixel(int x, int y, unsigned char * pixel);
Color traceRay(const Ray & ray); Color traceRay(const Ray & ray);
Color traceRayRecurse(const Ray & ray, int depth, double factor); Color traceRayRecurse(const Ray & ray, int depth, double factor);
Shape::Intersection getRayClosestHit(const Ray & ray); Shape::Intersection getRayClosestHit(const Ray & ray);
@ -49,7 +50,6 @@ class Scene
const Vector & surfaceNormal); const Vector & surfaceNormal);
Color calculateLightContribution(const Ray & toLight, Color calculateLightContribution(const Ray & toLight,
refptr<Light> light); refptr<Light> light);
void taskLoop();
/* In Scene-load.cc */ /* In Scene-load.cc */
void load(const char * filename); void load(const char * filename);
@ -74,8 +74,6 @@ class Scene
int m_width; int m_width;
int m_height; int m_height;
int m_multisample_level; int m_multisample_level;
std::string m_output_file_name;
bool m_verbose;
double m_vfov; double m_vfov;
Color m_ambient_light; Color m_ambient_light;
int m_max_depth; int m_max_depth;
@ -89,17 +87,6 @@ class Scene
double m_sample_span; double m_sample_span;
double m_half_sample_span; double m_half_sample_span;
std::map< std::string, refptr<Material> > m_materials; 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 #endif

View File

@ -8,6 +8,8 @@
#include <string> #include <string>
#include <map> #include <map>
#include "Scene.h" #include "Scene.h"
#include "distrib/distrib.h"
#include "BMP.h"
using namespace std; using namespace std;
void usage(const char * progname) void usage(const char * progname)
@ -21,7 +23,6 @@ void usage(const char * progname)
cout << " -f|--field-of-view <vertical-fov>" << endl; cout << " -f|--field-of-view <vertical-fov>" << endl;
cout << " -d|--max-depth <max-recursion-depth>" << endl; cout << " -d|--max-depth <max-recursion-depth>" << endl;
cout << " --hosts <hosts-file>" << endl; cout << " --hosts <hosts-file>" << endl;
cout << " -v|--verbose" << endl;
exit(42); exit(42);
} }
@ -30,7 +31,14 @@ int main(int argc, char * argv[])
int opt; int opt;
int option_index; int option_index;
map<string, const char *> scene_options; map<string, const char *> scene_options;
vector<string> client_options;
bool server = true; 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[] = { static const struct option long_options[] = {
{ "output-file", required_argument, NULL, 'o' }, { "output-file", required_argument, NULL, 'o' },
@ -39,7 +47,6 @@ int main(int argc, char * argv[])
{ "multisample", required_argument, NULL, 'm' }, { "multisample", required_argument, NULL, 'm' },
{ "field-of-view", required_argument, NULL, 'f' }, { "field-of-view", required_argument, NULL, 'f' },
{ "max-depth", required_argument, NULL, 'd' }, { "max-depth", required_argument, NULL, 'd' },
{ "verbose", no_argument, NULL, 'v' },
{ "help", no_argument, NULL, 256 }, { "help", no_argument, NULL, 256 },
{ "host", required_argument, NULL, 257 }, { "host", required_argument, NULL, 257 },
{ "port", required_argument, NULL, 258 }, { "port", required_argument, NULL, 258 },
@ -47,44 +54,54 @@ int main(int argc, char * argv[])
{ NULL, 0, NULL, 0 } { 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) long_options, &option_index)) != -1)
{ {
switch (opt) switch (opt)
{ {
case 'o': case 'o':
scene_options["output-file"] = optarg; output_file_name = optarg;
break; break;
case 'w': case 'w':
scene_options["width"] = optarg; scene_options["width"] = optarg;
client_options.push_back("--width");
client_options.push_back(optarg);
break; break;
case 'h': case 'h':
scene_options["height"] = optarg; scene_options["height"] = optarg;
client_options.push_back("--height");
client_options.push_back(optarg);
break; break;
case 'm': case 'm':
scene_options["multisample"] = optarg; scene_options["multisample"] = optarg;
client_options.push_back("--multisample");
client_options.push_back(optarg);
break; break;
case 'f': case 'f':
scene_options["field-of-view"] = optarg; scene_options["field-of-view"] = optarg;
client_options.push_back("--field-of-view");
client_options.push_back(optarg);
break; break;
case 'd': case 'd':
scene_options["max-depth"] = optarg; scene_options["max-depth"] = optarg;
break; client_options.push_back("--max-depth");
case 'v': client_options.push_back(optarg);
scene_options["verbose"] = optarg;
break; break;
case 256: case 256:
usage(argv[0]); usage(argv[0]);
break; break;
case 257: case 257:
scene_options["host"] = optarg; server_name = optarg;
server = false; server = false;
distributed = true;
break; break;
case 258: case 258:
scene_options["port"] = optarg; server_port = atoi(optarg);
distributed = true;
break; break;
case 259: case 259:
scene_options["hosts"] = optarg; hosts_file = optarg;
distributed = true;
break; break;
default: default:
usage(argv[0]); usage(argv[0]);
@ -97,17 +114,110 @@ int main(int argc, char * argv[])
usage(argv[0]); 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; struct timeval before, after;
gettimeofday(&before, NULL); /* start timing */ 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 */ gettimeofday(&after, NULL); /* stop timing */
if (server) 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_before = before.tv_sec + before.tv_usec / 1000000.0;
double time_after = after.tv_sec + after.tv_usec / 1000000.0; double time_after = after.tv_sec + after.tv_usec / 1000000.0;
double total_seconds = time_after - time_before; double total_seconds = time_after - time_before;