Difference between revisions of "Parallel Raytracer Assignment"
Line 1: | Line 1: | ||
=Motivation= | =Motivation= | ||
− | [https://en.wikipedia.org/wiki/Ray_tracing_(graphics) Ray tracing] cast (sometimes multiple) rays for each [https://en.wikipedia.org/wiki/Pixel pixel] to compute the illumination of a scene. Each ray can be computed completely independently of all other rays. This "embarrassment of riches" of potential parallelism is referred to [https://en.wikipedia.org/wiki/Embarrassingly_parallel embarrassingly parallel]. We will use ray tracing as our application for the [ | + | [https://en.wikipedia.org/wiki/Ray_tracing_(graphics) Ray tracing] cast (sometimes multiple) rays for each [https://en.wikipedia.org/wiki/Pixel pixel] to compute the illumination of a scene. Each ray can be computed completely independently of all other rays. This "embarrassment of riches" of potential parallelism is referred to [https://en.wikipedia.org/wiki/Embarrassingly_parallel embarrassingly parallel]. We will use ray tracing as our application for the [[Centralized_Work_Queue_Assignment|scheduler]] challenge problem. |
= | = | ||
Revision as of 18:09, 28 April 2023
Motivation
Ray tracing cast (sometimes multiple) rays for each pixel to compute the illumination of a scene. Each ray can be computed completely independently of all other rays. This "embarrassment of riches" of potential parallelism is referred to embarrassingly parallel. We will use ray tracing as our application for the scheduler challenge problem. =
Code To Investigate
RayTraceContext
public interface RayTraceContext { int width(); int height(); void mark(int xMin, int yMin, int xMaxExclusive, int yMaxExclusive); void raytrace(int xMin, int yMin, int xMaxExclusive, int yMaxExclusive); }
Scheduler
public interface Scheduler { void void_fork(Runnable runnable); }
Section
public final class Section { private final int xMin; private final int yMin; private final int xMaxExclusive; private final int yMaxExclusive; public Section(int xMin, int yMin, int xMaxExclusive, int yMaxExclusive) { this.xMin = xMin; this.yMin = yMin; this.xMaxExclusive = xMaxExclusive; this.yMaxExclusive = yMaxExclusive; } public int xMin() { return xMin; } public int yMin() { return yMin; } public int xMaxExclusive() { return xMaxExclusive; } public int yMaxExclusive() { return yMaxExclusive; } }
Code To Implement
SplitFourWayRayTracer
class: | SplitFourWayRayTracer.java | |
methods: | rayTrace | |
package: | raytrace.exercise | |
source folder: | student/src/main/java |
rayTrace
method: public void rayTrace(RayTraceContext context, Scheduler scheduler)
(parallel implementation required)
Split the image into four quadrants using the x and y coordinates contained in the RayTraceContext. Recall that the scheduler has a void_fork() method you can use to do this (remember: it's unnecessary to void_fork() the last quadrant. You can just leave some work behind for the continuation).
LoopRayTracer
class: | LoopRayTracer.java | |
methods: | constructor sectionsCreator rayTrace |
|
package: | raytrace.exercise | |
source folder: | student/src/main/java |
constructor
method: public LoopRayTracer(int sectionSize
(sequential implementation only)
Hang onto the sectionSize in an instance variable. You will need it.
sectionSize
method: int sectionSize()
(sequential implementation only)
Return the sectionSize you stored in an instance variable.
rayTrace
method: public void rayTrace(RayTraceContext context, Scheduler scheduler)
(parallel implementation required)
Use the sectionSize to create a list of Sections.
To call createSections(), use the Sections class, i.e. Sections.createSections(rayTraceContext, size).
public class Sections {
public static List<Section> createSections(int xMin, int yMin, int xMaxExclusive, int yMaxExclusive, int size) {
List<Section> sections = new LinkedList<>();
for (int y = yMin; y < yMaxExclusive; y += size) {
for (int x = xMin; x < xMaxExclusive; x += size) {
sections.add(new Section(x, y, Math.min(x + size, xMaxExclusive), Math.min(y + size, yMaxExclusive)));
}
}
return sections;
}
public static List<Section> createSections(RayTraceContext rayTraceContext, int size) {
return createSections(0, 0, rayTraceContext.width(), rayTraceContext.height(), size);
}
}
Then create a rayTrace task for each section.
DivideAndConquerRayTracer
class: | DivideAndConquerRayTracer.java | |
methods: | constructor thresholdPredicate rayTraceKernel |
|
package: | raytrace.exercise | |
source folder: | student/src/main/java |
constructor
method: public DivideAndConquerRayTracer(BiPredicate<Integer, Integer> thresholdPredicate)
(sequential implementation only)
Hang onto the thresholdPredicate in an instance variable. You will need it.
thresholdPredicate
determines the threshold for division. If thresholdPredicate.test()
is true, then the section is still large enough for more division of work.
thresholdPredicate
method: public BiPredicate<Integer, Integer> thresholdPredicate()
(sequential implementation only)
Return the thresholdPredicate you stored in an instance variable.
rayTrace
method: public void rayTrace(RayTraceContext context, Scheduler scheduler)
(parallel implementation required)
Use the threshold predicate to know whether or not to continue dividing, or to just render the current quadrant. ThresholdPredicate now takes two parameters, which are the height and width of the quadrant.
Checking Your Solution
Visualization
class: | RayTracerViz.java | VIZ |
package: | raytrace.viz | |
source folder: | student/src/main/java |
Correctness
class: | _ParallelRayTracerTestSuite.java | |
package: | raytrace.exercise | |
source folder: | testing/src/test/java |