0
$\begingroup$

I'm trying to make the path tracer shown in the Ray Tracing in One Weekend series multithreaded.

Here's the starting of my main function:

//scene setup
    hitable* world = cornell_box();
    auto start = std::chrono::high_resolution_clock::now();
    light_hitable_list = hitable_list(lightsVector);
    string filePath = "img.png";

    Image image(nx, ny);
    TilePool tilePool(nx, ny, 50);

    //maxThreads = std::thread::hardware_concurrency();
    maxThreads = 1;
    std::vector<std::thread> renderThreads;
    renderThreads.resize(maxThreads);

    //RenderSettings renderSettings{world, &image, &tilePool, ns, BLACK_SKY, false, "img.png"};

    for (unsigned int i = 0; i < maxThreads; i++)
    {
        renderThreads[i] = std::thread(&renderScene, world, &image, &tilePool);
    }
    for (unsigned int i = 0; i < maxThreads; i++)
    {
        if (renderThreads[i].joinable())
        {
            renderThreads[i].join();
        }
    }

And here's the renderScene function:

void renderScene(hitable* world, Image* image, TilePool* tilePool) {

    while (tilePool->getPoolSize() > 0)
    {   
        Tile tile = tilePool->getNextTile();

        for (int j = tile.yMax - 1; j >= tile.yMin; j--) {

            for (int i = tile.xMin; i < tile.xMax; i++) {
                vec3 col(0, 0, 0);
                for (int s = 0; s < ns; s++) {
                    float u = (float(i) + random_number()) / float(nx);
                    float v = (float(j) + random_number()) / float(ny);

                    ray r = cam.get_ray(u, v);
                    vec3 p = r.point_at_parameter(2.0);
                    col += de_nan(color(r, world, &light_hitable_list, 0));
                }
                col /= float(ns);
                col = vec3(sqrt(col[0]), sqrt(col[1]), sqrt(col[2]));

                (*image)[3 * i + 3 * nx * (ny - 1 - j)] = col[0];
                (*image)[3 * i + 3 * nx * (ny - 1 - j) + 1] = col[1];
                (*image)[3 * i + 3 * nx * (ny - 1 - j) + 2] = col[2];

            }

        }
    }
}

If I run the code above as it is I get this error:

Exception thrown at 0x00007FF70F601F2E in raytracer.exe: 0xC0000005: Access violation reading location 0x000001C200000190.

here: https://github.com/KarthikRIyer/RayTracer/blob/ec51999070218839e6aef2a65868e57fc6bb728d/src/objects/hitables/hitable_list.h#L29

And instead of using just 1 thread if I use maxThreads = std::thread::hardware_concurrency();

I get this error:

Exception thrown at 0x00007FF79DE01FCE in raytracer.exe: 0xC0000005: Access violation reading location 0x0000015E0000012C.

here: https://github.com/KarthikRIyer/RayTracer/blob/ec51999070218839e6aef2a65868e57fc6bb728d/src/objects/hitables/hitable_list.h#L38

These errors are not for the parameters passed into the function. I have checked if they are NULL. It seems to be for the function call. I'm completely new to multithreaded programming. But it doesn't feel like the error might be due to multithreading because I get such an error even while using maxThreads = 1.

Instead of the cornell box scene if I use the model_scene defined here: https://github.com/KarthikRIyer/RayTracer/blob/ec51999070218839e6aef2a65868e57fc6bb728d/src/Source.cpp#L135 sometimes I get the same error as above and sometimes it randomly starts working even with more than one threads.

Can someone please shed light as to why this might be occuring and what points should I keep in mind while writing a multithreaded path tracer?

$\endgroup$

1 Answer 1

0
$\begingroup$

I found out what was wrong. It wasn't related to multithreading at all. I was taking in a vector in a constructor hitable_list(std::vector<hitable*> listVector) and using a pointer to the first element of the vector elsewhere. So as soon as the vector went out of scope the pointer became invalid.

To solve this issue I just removed this constructor and whenever I need to pass in a vector I make sure that the vector stays in scope always and directly pass in the pointer to the first element of the vector, and it's size.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.