Skip to content
Snippets Groups Projects
Commit 1568bfec authored by Lukas Werner's avatar Lukas Werner
Browse files

Initial working version

parent de7040ca
No related merge requests found
......@@ -30,6 +30,33 @@ real_t deg2rad(real_t deg) {
namespace walberla {
namespace pe {
namespace raytracing {
void BodyIntersectionInfo_Comparator_MPI_OP( BodyIntersectionInfo_MPI *in, BodyIntersectionInfo_MPI *inout, int *len, MPI_Datatype *dptr) {
for (int i = 0; i < *len; i++) {
if (in->bodySystemID != 0 && inout->bodySystemID != 0) {
/*if (in->imageX != inout->imageX || in->imageY != inout->imageY) {
WALBERLA_LOG_INFO("coordinates of infos do not match: " << in->imageX << "/" << in->imageY << " and " << inout->imageX << "/" << inout->imageY << ", bodyIDs: " << in->bodySystemID << ", " << inout->bodySystemID << ", i: " << i);
}*/
WALBERLA_ASSERT(in->imageX == inout->imageX, "coordinates of infos do not match: " << in->imageX << "/" << in->imageY << " and " << inout->imageX << "/" << inout->imageY << ", bodyIDs: " << in->bodySystemID << ", " << inout->bodySystemID << ", i: " << i);
WALBERLA_ASSERT(in->imageY == inout->imageY, "coordinates of infos do not match: " << in->imageX << "/" << in->imageY << " and " << inout->imageX << "/" << inout->imageY << ", bodyIDs: " << in->bodySystemID << ", " << inout->bodySystemID << ", i: " << i);
}
if ((in->t < inout->t && in->bodySystemID != 0) || (inout->bodySystemID == 0 && in->bodySystemID != 0)) {
// info in "in" is closer than the one in "inout" -> update inout to values of in
inout->imageX = in->imageX;
inout->imageY = in->imageY;
inout->bodySystemID = in->bodySystemID;
inout->t = in->t;
inout->r = in->r;
inout->g = in->g;
inout->b = in->b;
}
in++;
inout++;
}
}
/*!\brief Instantiation constructor for the Raytracer class.
*
* \param forest BlockForest the raytracer operates on.
......@@ -69,6 +96,7 @@ Raytracer::Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageI
setupView_();
setupFilenameRankWidth_();
setupMPI_();
}
/*!\brief Instantiation constructor for the Raytracer class using a config object for view setup.
......@@ -125,6 +153,7 @@ Raytracer::Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageI
setupView_();
setupFilenameRankWidth_();
setupMPI_();
}
/*!\brief Utility function for setting up the view plane and calculating required variables.
......@@ -153,6 +182,10 @@ void Raytracer::setupFilenameRankWidth_() {
filenameRankWidth_ = int8_c(log10(numProcesses))+1;
}
void Raytracer::setupMPI_() {
MPI_Op_create((MPI_User_function *)BodyIntersectionInfo_Comparator_MPI_OP, true, &bodyIntersectionInfo_reduction_op);
}
/*!\brief Generates the filename for output files.
* \param base String that precedes the timestap and rank info.
* \param timestep Timestep this image is from.
......
......@@ -33,6 +33,11 @@
#include "Lighting.h"
#include "ShadingFunctions.h"
#include "core/mpi/MPIManager.h"
#include "core/mpi/MPIWrapper.h"
#include "core/mpi/all.h"
#include <stddef.h>
using namespace walberla;
using namespace walberla::pe;
using namespace walberla::timing;
......@@ -44,13 +49,23 @@ namespace raytracing {
/*!\brief Contains information about a ray-body intersection.
*/
struct BodyIntersectionInfo {
size_t imageX; //!< viewing plane x pixel coordinate the ray belongs to.
size_t imageY; //!< viewing plane y pixel coordinate the ray belongs to.
walberla::id_t bodySystemID; //!< system ID of body which was hit.
real_t t; //!< distance from camera to intersection point on body.
Vec3 color; //!< color computed for the pixel.
size_t imageX; //!< Viewing plane x pixel coordinate the ray belongs to.
size_t imageY; //!< Viewing plane y pixel coordinate the ray belongs to.
walberla::id_t bodySystemID; //!< System ID of body which was hit.
real_t t; //!< Distance from camera to intersection point on body.
Vec3 color; //!< Color computed for the pixel.
};
struct BodyIntersectionInfo_MPI {
unsigned int imageX; //!< Viewing plane x pixel coordinate the ray belongs to. -> MPI_UNSIGNED
unsigned int imageY; //!< Viewing plane y pixel coordinate the ray belongs to. -> MPI_UNSIGNED
walberla::id_t bodySystemID; //!< System ID of body which was hit. -> MPI_UNSIGNED_LONG_LONG
double t; //!< Distance from camera to intersection point on body. -> MPI_DOUBLE
double r; //!< Red value for the pixel. -> MPI_DOUBLE
double g; //!< Green value for the pixel. -> MPI_DOUBLE
double b; //!< Blue value for the pixel. -> MPI_DOUBLE
};
class Raytracer {
public:
/*!\name Constructors */
......@@ -119,6 +134,8 @@ private:
real_t pixelHeight_; //!< The height of a pixel of the generated image in the viewing plane.
//@}
MPI_Op bodyIntersectionInfo_reduction_op;
public:
/*!\name Get functions */
//@{
......@@ -155,6 +172,7 @@ public:
void setupView_();
void setupFilenameRankWidth_();
void setupMPI_();
private:
std::string getOutputFilename(const std::string& base, size_t timestep, bool isGlobalImage) const;
......@@ -382,6 +400,9 @@ void Raytracer::rayTrace(const size_t timestep, WcTimingTree* tt) {
std::vector<Color> imageBuffer(pixelsVertical_ * pixelsHorizontal_);
std::vector<BodyIntersectionInfo> intersections; // contains for each pixel information about an intersection, if existent
std::vector<BodyIntersectionInfo_MPI> intersectionsBuffer(pixelsVertical_ * pixelsHorizontal_);
real_t t, t_closest;
Vec3 n;
Vec3 n_closest;
......@@ -460,7 +481,19 @@ void Raytracer::rayTrace(const size_t timestep, WcTimingTree* tt) {
t_closest,
color
};
BodyIntersectionInfo_MPI mpi_intersectionInfo = {
static_cast<unsigned int>(x),
static_cast<unsigned int>(y),
body_closest->getSystemID(),
t_closest,
color[0],
color[1],
color[2]
};
intersections.push_back(intersectionInfo);
intersectionsBuffer[coordinateToArrayIndex(x, y)] = mpi_intersectionInfo;
}
tBuffer[coordinateToArrayIndex(x, y)] = t_closest;
......@@ -470,7 +503,83 @@ void Raytracer::rayTrace(const size_t timestep, WcTimingTree* tt) {
if (tt != NULL) tt->start("Reduction");
// intersections synchronisieren
mpi::SendBuffer sendBuffer;
const int recvRank = 0;
int myRank;
MPI_Comm_rank( MPI_COMM_WORLD, &myRank );
const int nblocks = 7;
const int blocklengths[nblocks] = {1,1,1,1,1,1,1};
MPI_Datatype types[nblocks] = {
MPI_UNSIGNED, // for coordinate
MPI_UNSIGNED, // for coordinate
MPI_UNSIGNED_LONG_LONG, // for id
MPI_DOUBLE, // for distance
MPI_DOUBLE, // for color
MPI_DOUBLE, // for color
MPI_DOUBLE // for color
};
MPI_Aint displacements[nblocks];
displacements[0] = offsetof(BodyIntersectionInfo_MPI, imageX);
displacements[1] = offsetof(BodyIntersectionInfo_MPI, imageY);
displacements[2] = offsetof(BodyIntersectionInfo_MPI, bodySystemID);
displacements[3] = offsetof(BodyIntersectionInfo_MPI, t);
displacements[4] = offsetof(BodyIntersectionInfo_MPI, r);
displacements[5] = offsetof(BodyIntersectionInfo_MPI, g);
displacements[6] = offsetof(BodyIntersectionInfo_MPI, b);
MPI_Datatype tmp_type;
MPI_Type_create_struct(nblocks, blocklengths, displacements, types, &tmp_type);
MPI_Aint lb, extent;
MPI_Type_get_extent( tmp_type, &lb, &extent );
MPI_Datatype mpi_bodyintersection_type;
MPI_Type_create_resized( tmp_type, lb, extent, &mpi_bodyintersection_type );
MPI_Type_commit(&mpi_bodyintersection_type);
/*BodyIntersectionInfo_MPI testInfo = {
500, 500,
12,
real_t(14.323),
real_t(14.323),
real_t(14.323),
real_t(14.323)
};
if (myRank == recvRank) {
BodyIntersectionInfo_MPI testRecInfo;
MPI_Recv(&testRecInfo, 1, mpi_bodyintersection_type, 2, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
WALBERLA_LOG_INFO("Received info: " << testRecInfo.imageX << ", " << testRecInfo.bodySystemID << ", " << testRecInfo.t);
} else if (myRank == 2) {
MPI_Send(&testInfo, 1, mpi_bodyintersection_type, recvRank, 0, MPI_COMM_WORLD);
WALBERLA_LOG_INFO("Sent info.");
}*/
if( myRank == recvRank ) {
MPI_Reduce(MPI_IN_PLACE,
&intersectionsBuffer[0], int_c(intersectionsBuffer.size()),
mpi_bodyintersection_type, bodyIntersectionInfo_reduction_op,
recvRank, MPI_COMM_WORLD);
} else {
MPI_Reduce(&intersectionsBuffer[0], 0, int_c(intersectionsBuffer.size()),
mpi_bodyintersection_type, bodyIntersectionInfo_reduction_op,
recvRank, MPI_COMM_WORLD);
}
if (tt != NULL) tt->stop("Reduction");
WALBERLA_ROOT_SECTION() {
std::vector<Color> fullImageBuffer(pixelsHorizontal_ * pixelsVertical_, backgroundColor_);
for (auto& info: intersectionsBuffer) {
fullImageBuffer[coordinateToArrayIndex(info.imageX, info.imageY)] = Color(info.r, info.g, info.b);
}
writeImageBufferToFile(fullImageBuffer, timestep, true);
}
/*mpi::SendBuffer sendBuffer;
for (auto& info: intersections) {
sendBuffer << info.imageX << info.imageY
<< info.bodySystemID << info.t
......@@ -526,7 +635,7 @@ void Raytracer::rayTrace(const size_t timestep, WcTimingTree* tt) {
writeTBufferToFile(fullTBuffer, timestep, true);
}
}
if (tt != NULL) tt->stop("Output");
if (tt != NULL) tt->stop("Output");*/
if (tt != NULL) tt->stop("Raytracing");
}
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment