From 5dedb6f836f8e914356ab3540d7db28b792e9c1a Mon Sep 17 00:00:00 2001 From: Matt Pharr Date: Wed, 7 Sep 2011 20:07:51 -0700 Subject: [PATCH] Add --scale command line argument to mandelbrot and rt examples. This applies a floating-point scale factor to the image resolution; it's useful for experiments with many-core systems where the base image resolution may not give enough work for good load-balancing with tasks. --- examples/mandelbrot_tasks/mandelbrot.cpp | 25 +++++++++- examples/rt/rt.cpp | 58 ++++++++++++++++-------- examples/rt/rt.ispc | 28 ++++++++---- examples/rt/rt_serial.cpp | 8 +++- 4 files changed, 88 insertions(+), 31 deletions(-) diff --git a/examples/mandelbrot_tasks/mandelbrot.cpp b/examples/mandelbrot_tasks/mandelbrot.cpp index a7d2a032..2de7affd 100644 --- a/examples/mandelbrot_tasks/mandelbrot.cpp +++ b/examples/mandelbrot_tasks/mandelbrot.cpp @@ -99,8 +99,12 @@ ensureTargetISAIsSupported() { } } +static void usage() { + fprintf(stderr, "usage: mandelbrot [--scale=] \n"); + exit(1); +} + + int main(int argc, char *argv[]) { - if (argc != 2) { - fprintf(stderr, "usage: rt \n"); - exit(1); + float scale = 1.f; + const char *filename = NULL; + for (int i = 1; i < argc; ++i) { + if (strncmp(argv[i], "--scale=", 8) == 0) { + scale = atof(argv[i] + 8); + if (scale == 0.f) + usage(); + } + else if (filename != NULL) + usage(); + else + filename = argv[i]; } + if (filename == NULL) + usage(); ensureTargetISAIsSupported(); @@ -145,10 +163,10 @@ int main(int argc, char *argv[]) { // Read the camera specification information from the camera file // char fnbuf[1024]; - sprintf(fnbuf, "%s.camera", argv[1]); + sprintf(fnbuf, "%s.camera", filename); FILE *f = fopen(fnbuf, "rb"); if (!f) { - perror(argv[1]); + perror(fnbuf); return 1; } @@ -156,20 +174,20 @@ int main(int argc, char *argv[]) { // Nothing fancy, and trouble if we run on a big-endian system, just // fread in the bits // - int width, height; + int baseWidth, baseHeight; float camera2world[4][4], raster2camera[4][4]; - READ(width, 1); - READ(height, 1); + READ(baseWidth, 1); + READ(baseHeight, 1); READ(camera2world[0][0], 16); READ(raster2camera[0][0], 16); // // Read in the serialized BVH // - sprintf(fnbuf, "%s.bvh", argv[1]); + sprintf(fnbuf, "%s.bvh", filename); f = fopen(fnbuf, "rb"); if (!f) { - perror(argv[2]); + perror(fnbuf); return 1; } @@ -216,10 +234,10 @@ int main(int argc, char *argv[]) { } fclose(f); - // round image resolution up to multiple of 4 to make things easy for + // round image resolution up to multiple of 16 to make things easy for // the code that assigns pixels to ispc program instances - height = (height + 3) & ~3; - width = (width + 3) & ~3; + int height = (int(baseHeight * scale) + 0xf) & ~0xf; + int width = (int(baseWidth * scale) + 0xf) & ~0xf; // allocate images; one to hold hit object ids, one to hold depth to // the first interseciton @@ -232,8 +250,8 @@ int main(int argc, char *argv[]) { double minTimeISPC = 1e30; for (int i = 0; i < 3; ++i) { reset_and_start_timer(); - raytrace_ispc(width, height, raster2camera, camera2world, - image, id, nodes, triangles); + raytrace_ispc(width, height, baseWidth, baseHeight, raster2camera, + camera2world, image, id, nodes, triangles); double dt = get_elapsed_mcycles(); minTimeISPC = std::min(dt, minTimeISPC); } @@ -251,8 +269,8 @@ int main(int argc, char *argv[]) { double minTimeISPCtasks = 1e30; for (int i = 0; i < 3; ++i) { reset_and_start_timer(); - raytrace_ispc_tasks(width, height, raster2camera, camera2world, - image, id, nodes, triangles); + raytrace_ispc_tasks(width, height, baseWidth, baseHeight, raster2camera, + camera2world, image, id, nodes, triangles); double dt = get_elapsed_mcycles(); minTimeISPCtasks = std::min(dt, minTimeISPCtasks); } @@ -271,8 +289,8 @@ int main(int argc, char *argv[]) { double minTimeSerial = 1e30; for (int i = 0; i < 3; ++i) { reset_and_start_timer(); - raytrace_serial(width, height, raster2camera, camera2world, - image, id, nodes, triangles); + raytrace_serial(width, height, baseWidth, baseHeight, raster2camera, + camera2world, image, id, nodes, triangles); double dt = get_elapsed_mcycles(); minTimeSerial = std::min(dt, minTimeSerial); } diff --git a/examples/rt/rt.ispc b/examples/rt/rt.ispc index 8e5ddf5e..92ca2421 100644 --- a/examples/rt/rt.ispc +++ b/examples/rt/rt.ispc @@ -227,12 +227,17 @@ bool BVHIntersect(const LinearBVHNode nodes[], const Triangle tris[], static void raytrace_tile(uniform int x0, uniform int x1, - uniform int y0, uniform int y1, uniform int width, + uniform int y0, uniform int y1, + uniform int width, uniform int height, + uniform int baseWidth, uniform int baseHeight, const uniform float raster2camera[4][4], const uniform float camera2world[4][4], uniform float image[], uniform int id[], const LinearBVHNode nodes[], const Triangle triangles[]) { + uniform float widthScale = (float)(baseWidth) / (float)(width); + uniform float heightScale = (float)(baseHeight) / (float)(height); + static const uniform float udx[16] = { 0, 1, 0, 1, 2, 3, 2, 3, 0, 1, 0, 1, 2, 3, 2, 3 }; static const uniform float udy[16] = { 0, 0, 1, 1, 0, 0, 1, 1, @@ -252,7 +257,8 @@ static void raytrace_tile(uniform int x0, uniform int x1, const float dy = udy[o * programCount + programIndex]; Ray ray; - generateRay(raster2camera, camera2world, x+dx, y+dy, ray); + generateRay(raster2camera, camera2world, (x+dx)*widthScale, + (y+dy)*heightScale, ray); BVHIntersect(nodes, triangles, ray); int offset = (y + (int)dy) * width + (x + (int)dx); @@ -265,29 +271,35 @@ static void raytrace_tile(uniform int x0, uniform int x1, export void raytrace_ispc(uniform int width, uniform int height, + uniform int baseWidth, uniform int baseHeight, const uniform float raster2camera[4][4], const uniform float camera2world[4][4], uniform float image[], uniform int id[], const LinearBVHNode nodes[], const Triangle triangles[]) { - raytrace_tile(0, width, 0, height, width, raster2camera, camera2world, image, + raytrace_tile(0, width, 0, height, width, height, baseWidth, baseHeight, + raster2camera, camera2world, image, id, nodes, triangles); } task void raytrace_tile_task(uniform int x0, uniform int x1, - uniform int y0, uniform int y1, uniform int width, + uniform int y0, uniform int y1, + uniform int width, uniform int height, + uniform int baseWidth, uniform int baseHeight, const uniform float raster2camera[4][4], const uniform float camera2world[4][4], uniform float image[], uniform int id[], const LinearBVHNode nodes[], const Triangle triangles[]) { - raytrace_tile(x0, x1, y0, y1, width, raster2camera, camera2world, image, + raytrace_tile(x0, x1, y0, y1, width, height, baseWidth, baseHeight, + raster2camera, camera2world, image, id, nodes, triangles); } export void raytrace_ispc_tasks(uniform int width, uniform int height, + uniform int baseWidth, uniform int baseHeight, const uniform float raster2camera[4][4], const uniform float camera2world[4][4], uniform float image[], uniform int id[], @@ -298,9 +310,9 @@ export void raytrace_ispc_tasks(uniform int width, uniform int height, uniform int y1 = min(y + dy, height); for (uniform int x = 0; x < width; x += dx) { uniform int x1 = min(x + dx, width); - launch < raytrace_tile_task(x, x1, y, y1, width, raster2camera, - camera2world, image, id, nodes, - triangles) >; + launch < raytrace_tile_task(x, x1, y, y1, width, height, baseWidth, + baseHeight, raster2camera, camera2world, + image, id, nodes, triangles) >; } } } diff --git a/examples/rt/rt_serial.cpp b/examples/rt/rt_serial.cpp index f830b273..6ce1a34b 100644 --- a/examples/rt/rt_serial.cpp +++ b/examples/rt/rt_serial.cpp @@ -258,17 +258,21 @@ bool BVHIntersect(const LinearBVHNode nodes[], const Triangle tris[], } -void raytrace_serial(int width, int height, +void raytrace_serial(int width, int height, int baseWidth, int baseHeight, const float raster2camera[4][4], const float camera2world[4][4], float image[], int id[], const LinearBVHNode nodes[], const Triangle triangles[]) { + float widthScale = float(baseWidth) / float(width); + float heightScale = float(baseHeight) / float(height); + for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { Ray ray; - generateRay(raster2camera, camera2world, x, y, ray); + generateRay(raster2camera, camera2world, x * widthScale, + y * heightScale, ray); BVHIntersect(nodes, triangles, ray); int offset = y * width + x;