1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
|
// Copyright 2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
#include "distributed_test_fixture.h"
#include <mpi.h>
#include "ArcballCamera.h"
#include "ospray_testing.h"
extern OSPRayEnvironment *ospEnv;
namespace MPIDistribOSPRayTestScenes {
bool computeDivisor(int x, int &divisor)
{
int upperBound = std::sqrt(x);
for (int i = 2; i <= upperBound; ++i) {
if (x % i == 0) {
divisor = i;
return true;
}
}
return false;
}
// Compute an X x Y x Z grid to have 'num' grid cells,
// only gives a nice grid for numbers with even factors since
// we don't search for factors of the number, we just try dividing by two
vec3i computeGrid(int num)
{
vec3i grid(1);
int axis = 0;
int divisor = 0;
while (computeDivisor(num, divisor)) {
grid[axis] *= divisor;
num /= divisor;
axis = (axis + 1) % 3;
}
if (num != 1) {
grid[axis] *= num;
}
return grid;
}
MPIDistribBase::MPIDistribBase()
{
MPI_Comm_size(MPI_COMM_WORLD, &mpiSize);
MPI_Comm_rank(MPI_COMM_WORLD, &mpiRank);
rankGridDims = computeGrid(mpiSize);
rankBrickId = vec3i(mpiRank % rankGridDims.x,
(mpiRank / rankGridDims.x) % rankGridDims.y,
mpiRank / (rankGridDims.x * rankGridDims.y));
}
void MPIDistribBase::AddInstance(cpp::Instance instance)
{
worldBounds.extend(instance.getBounds<box3f>());
Base::AddInstance(instance);
}
void MPIDistribBase::PerformRenderTest()
{
SetLights();
if (!instances.empty()) {
world.setParam("instance", cpp::CopiedData(instances));
// Determine the bounds of this rank's region in world space
const vec3f regionDims = worldBounds.size() / vec3f(rankGridDims);
box3f localRegion(rankBrickId * regionDims + worldBounds.lower,
rankBrickId * regionDims + regionDims + worldBounds.lower);
// Special case for the ospray test data: we might have geometry right at
// the region bounding box which will z-fight with the clipping region. If
// we have a region at the edge of the domain, apply some padding
for (int i = 0; i < 3; ++i) {
if (localRegion.lower[i] == worldBounds.lower[i]) {
localRegion.lower[i] -= 0.001;
}
if (localRegion.upper[i] == worldBounds.upper[i]) {
localRegion.upper[i] += 0.001;
}
}
world.setParam("region", cpp::CopiedData(localRegion));
}
camera.commit();
world.commit();
renderer.commit();
framebuffer.resetAccumulation();
RenderFrame();
if (mpiRank == 0) {
auto *framebuffer_data = (uint32_t *)framebuffer.map(OSP_FB_COLOR);
if (ospEnv->GetDumpImg()) {
EXPECT_EQ(imageTool->saveTestImage(framebuffer_data), OsprayStatus::Ok);
} else {
EXPECT_EQ(imageTool->compareImgWithBaseline(framebuffer_data),
OsprayStatus::Ok);
}
framebuffer.unmap(framebuffer_data);
}
}
MPIFromOsprayTesting::MPIFromOsprayTesting()
{
auto params = GetParam();
sceneName = std::get<0>(params);
rendererType = "mpiRaycast";
samplesPerPixel = std::get<1>(params);
}
void MPIFromOsprayTesting::SetUp()
{
MPIDistribBase::SetUp();
instances.clear();
auto builder = ospray::testing::newBuilder(sceneName);
ospray::testing::setParam(builder, "rendererType", rendererType);
ospray::testing::commit(builder);
// Build the group to get the bounds
auto group = ospray::testing::buildGroup(builder);
worldBounds = group.getBounds<box3f>();
cpp::Instance instance(group);
instance.commit();
instances.push_back(instance);
ospray::testing::release(builder);
ArcballCamera arcballCamera(worldBounds, imgSize);
camera.setParam("position", arcballCamera.eyePos());
camera.setParam("direction", arcballCamera.lookDir());
camera.setParam("up", arcballCamera.upDir());
}
} // namespace MPIDistribOSPRayTestScenes
|