feat: Implement CUDA support for VoxRaytracer, add CUDA tests for voxel image operations, and update CMake to enable CUDA compilation.
This commit is contained in:
@@ -24,5 +24,6 @@ set(LIBRARIES
|
||||
uLib_add_tests(Math)
|
||||
|
||||
if(USE_CUDA)
|
||||
set_source_files_properties(VoxImageFilterTest.cpp PROPERTIES LANGUAGE CUDA)
|
||||
set_source_files_properties(VoxImageTest.cpp VoxImageCopyTest.cpp VoxImageFilterTest.cpp VoxRaytracerTest.cpp PROPERTIES LANGUAGE CUDA)
|
||||
set_source_files_properties(VoxRaytracerTest.cpp PROPERTIES CXX_STANDARD 17 CUDA_STANDARD 17)
|
||||
endif()
|
||||
|
||||
@@ -23,55 +23,44 @@
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
|
||||
|
||||
#include "testing-prototype.h"
|
||||
|
||||
#include "Math/VoxImage.h"
|
||||
|
||||
using namespace uLib;
|
||||
|
||||
|
||||
struct TestVoxel {
|
||||
Scalarf Value;
|
||||
unsigned int Count;
|
||||
Scalarf Value;
|
||||
unsigned int Count;
|
||||
};
|
||||
|
||||
int main() {
|
||||
BEGIN_TESTING(Math VoxImage Copy);
|
||||
BEGIN_TESTING(Math VoxImage Copy);
|
||||
|
||||
{
|
||||
VoxImage<TestVoxel> img(Vector3i(10,10,10));
|
||||
TestVoxel zero = {0,0};
|
||||
img.InitVoxels(zero);
|
||||
TestVoxel nonzero = {5.552368, 0};
|
||||
img[Vector3i(5,1,7)] = nonzero;
|
||||
img[img.Find(HPoint3f(3,3,3))].Value = 5.552369;
|
||||
TEST1( img.GetValue(Vector3i(5,1,7)) == 5.552368f );
|
||||
{
|
||||
VoxImage<TestVoxel> img(Vector3i(10, 10, 10));
|
||||
TestVoxel zero = {0.f, 0};
|
||||
img.InitVoxels(zero);
|
||||
TestVoxel nonzero = {5.552368f, 0};
|
||||
img[Vector3i(5, 1, 7)] = nonzero;
|
||||
img[img.Find(HPoint3f(3, 3, 3))].Value = 5.552369;
|
||||
TEST1(img.GetValue(Vector3i(5, 1, 7)) == 5.552368f);
|
||||
|
||||
img.SetOrigin(Vector3f(4, 5, 6));
|
||||
|
||||
img.SetOrigin(Vector3f(4,5,6));
|
||||
std::cout << "\n";
|
||||
|
||||
std::cout << "\n";
|
||||
img.PrintSelf(std::cout);
|
||||
|
||||
img.PrintSelf(std::cout);
|
||||
VoxImage<TestVoxel> img2 = img;
|
||||
img2.PrintSelf(std::cout);
|
||||
|
||||
VoxImage<TestVoxel> img2 = img;
|
||||
img2.PrintSelf(std::cout);
|
||||
TEST1(img.GetOrigin() == img2.GetOrigin());
|
||||
TEST1(img.GetSpacing() == img2.GetSpacing());
|
||||
|
||||
TEST1( img.GetOrigin() == img2.GetOrigin() );
|
||||
TEST1( img.GetSpacing() == img2.GetSpacing() );
|
||||
img2 = img;
|
||||
}
|
||||
|
||||
img2 = img;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
std::cout << "returns " << _fail << "\n";
|
||||
END_TESTING;
|
||||
std::cout << "returns " << _fail << "\n";
|
||||
END_TESTING;
|
||||
}
|
||||
|
||||
@@ -23,99 +23,91 @@
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include "testing-prototype.h"
|
||||
#include "Math/StructuredGrid.h"
|
||||
#include "Math/VoxImage.h"
|
||||
#include "Math/StructuredGrid.h"
|
||||
#include "testing-prototype.h"
|
||||
|
||||
using namespace uLib;
|
||||
|
||||
|
||||
struct TestVoxel {
|
||||
Scalarf Value;
|
||||
unsigned int Count;
|
||||
Scalarf Value;
|
||||
unsigned int Count;
|
||||
};
|
||||
|
||||
int main() {
|
||||
BEGIN_TESTING(Math StructuredGrid);
|
||||
BEGIN_TESTING(Math StructuredGrid);
|
||||
|
||||
{ // SIMPLE TESTS //
|
||||
StructuredGrid img(Vector3i(10,10,10));
|
||||
img.SetSpacing(Vector3f(3,3,3));
|
||||
TEST1( img.GetWorldPoint(2,0,0) == HPoint3f(6,0,0) );
|
||||
TEST1( img.GetWorldPoint(1,1,1) == HPoint3f(3,3,3) );
|
||||
{ // SIMPLE TESTS //
|
||||
StructuredGrid img(Vector3i(10, 10, 10));
|
||||
img.SetSpacing(Vector3f(3, 3, 3));
|
||||
TEST1(img.GetWorldPoint(2, 0, 0) == HPoint3f(6, 0, 0));
|
||||
TEST1(img.GetWorldPoint(1, 1, 1) == HPoint3f(3, 3, 3));
|
||||
|
||||
img.SetPosition(Vector3f(1,1,1));
|
||||
TEST1( img.GetWorldPoint(1,1,1) == HPoint3f(4,4,4) );
|
||||
TEST1( img.GetLocalPoint(4,4,4) == HPoint3f(1,1,1) );
|
||||
img.SetPosition(Vector3f(1, 1, 1));
|
||||
TEST1(img.GetWorldPoint(1, 1, 1) == HPoint3f(4, 4, 4));
|
||||
TEST1(img.GetLocalPoint(4, 4, 4) == HPoint3f(1, 1, 1));
|
||||
|
||||
TEST0( img.IsInsideBounds(HPoint3f(5,33,-5)));
|
||||
TEST0( img.IsInsideBounds(HPoint3f(0,0,0)));
|
||||
TEST1( img.IsInsideBounds(HPoint3f(1,1,1)));
|
||||
}
|
||||
TEST0(img.IsInsideBounds(HPoint3f(5, 33, -5)));
|
||||
TEST0(img.IsInsideBounds(HPoint3f(0, 0, 0)));
|
||||
TEST1(img.IsInsideBounds(HPoint3f(1, 1, 1)));
|
||||
}
|
||||
|
||||
{ // TEST WITH ORIGIN //
|
||||
StructuredGrid img(Vector3i(10,10,10));
|
||||
img.SetSpacing(Vector3f(3,3,3));
|
||||
img.SetOrigin(Vector3f(-1,1,-1));
|
||||
img.SetPosition(Vector3f(1,1,1));
|
||||
TEST1( img.GetWorldPoint(1,1,1) == HPoint3f(3,5,3) );
|
||||
}
|
||||
{ // TEST WITH ORIGIN //
|
||||
StructuredGrid img(Vector3i(10, 10, 10));
|
||||
img.SetSpacing(Vector3f(3, 3, 3));
|
||||
img.SetOrigin(Vector3f(-1, 1, -1));
|
||||
img.SetPosition(Vector3f(1, 1, 1));
|
||||
TEST1(img.GetWorldPoint(1, 1, 1) == HPoint3f(3, 5, 3));
|
||||
}
|
||||
|
||||
{
|
||||
VoxImage<TestVoxel> img(Vector3i(10, 10, 10));
|
||||
TestVoxel zero = {0.f, 0};
|
||||
img.InitVoxels(zero);
|
||||
TestVoxel nonzero = {5.552368f, 0};
|
||||
img[Vector3i(5, 1, 7)] = nonzero;
|
||||
img[img.Find(HPoint3f(3, 3, 3))].Value = 5.552369;
|
||||
img.ExportToVtk("./test_vox_image.vtk", 0);
|
||||
img.ExportToVtkXml("./test_vox_image.vti", 0);
|
||||
TEST1(img.GetValue(Vector3i(5, 1, 7)) == 5.552368f);
|
||||
}
|
||||
|
||||
{
|
||||
VoxImage<TestVoxel> img(Vector3i(10,10,10));
|
||||
TestVoxel zero = {0,0};
|
||||
img.InitVoxels(zero);
|
||||
TestVoxel nonzero = {5.552368, 0};
|
||||
img[Vector3i(5,1,7)] = nonzero;
|
||||
img[img.Find(HPoint3f(3,3,3))].Value = 5.552369;
|
||||
img.ExportToVtk("./test_vox_image.vtk",0);
|
||||
img.ExportToVtkXml("./test_vox_image.vti",0);
|
||||
TEST1( img.GetValue(Vector3i(5,1,7)) == 5.552368f );
|
||||
}
|
||||
{
|
||||
VoxImage<TestVoxel> img(Vector3i(4, 4, 4));
|
||||
TestVoxel zero = {0.f, 0};
|
||||
img.InitVoxels(zero);
|
||||
img.SetSpacing(Vector3f(2, 2, 2));
|
||||
img.SetPosition(Vector3f(-4, -4, -4));
|
||||
TEST1(img.GetWorldPoint(img.GetLocalPoint(HPoint3f(5, 5, 5))) ==
|
||||
HPoint3f(5, 5, 5));
|
||||
}
|
||||
|
||||
{
|
||||
VoxImage<TestVoxel> img(Vector3i(4,4,4));
|
||||
TestVoxel zero = {0,0};
|
||||
img.InitVoxels(zero);
|
||||
img.SetSpacing(Vector3f(2,2,2));
|
||||
img.SetPosition(Vector3f(-4,-4,-4));
|
||||
TEST1( img.GetWorldPoint(img.GetLocalPoint(HPoint3f(5,5,5))) == HPoint3f(5,5,5));
|
||||
}
|
||||
{
|
||||
VoxImage<TestVoxel> imgR(Vector3i(0, 0, 0));
|
||||
imgR.ImportFromVtk("./test_vox_image.vtk");
|
||||
imgR.ExportToVtk("./read_and_saved.vtk");
|
||||
}
|
||||
|
||||
{
|
||||
VoxImage<TestVoxel> imgR(Vector3i(0,0,0));
|
||||
imgR.ImportFromVtk("./test_vox_image.vtk");
|
||||
imgR.ExportToVtk("./read_and_saved.vtk");
|
||||
}
|
||||
|
||||
{
|
||||
VoxImage<TestVoxel> img(Vector3i(4,4,4));
|
||||
img.InitVoxels({0,0});
|
||||
for (int i=0; i<4; i++) {
|
||||
for (int j=0; j<4; j++) {
|
||||
for (int k=0; k<4; k++) {
|
||||
img[Vector3i(i,j,k)] = {i+j+k,0};
|
||||
}
|
||||
}
|
||||
{
|
||||
VoxImage<TestVoxel> img(Vector3i(4, 4, 4));
|
||||
img.InitVoxels({0.f, 0});
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
for (int k = 0; k < 4; k++) {
|
||||
img[Vector3i(i, j, k)] = {static_cast<float>(i + j + k), 0};
|
||||
}
|
||||
img.ExportToVti("./vti_saved.vti",0,1);
|
||||
// img.ImportFromVtkXml("./test_vox_image.vti");
|
||||
}
|
||||
}
|
||||
img.ExportToVti("./vti_saved.vti", 0, 1);
|
||||
// img.ImportFromVtkXml("./test_vox_image.vti");
|
||||
}
|
||||
|
||||
{
|
||||
VoxImage<TestVoxel> img1(Vector3i(5, 5, 5));
|
||||
VoxImage<TestVoxel> img2;
|
||||
img2 = img1;
|
||||
TEST1(img1.GetDims() == img2.GetDims());
|
||||
}
|
||||
|
||||
{
|
||||
VoxImage<TestVoxel> img1(Vector3i(5,5,5));
|
||||
VoxImage<TestVoxel> img2;
|
||||
img2 = img1;
|
||||
TEST1( img1.GetDims() == img2.GetDims() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
END_TESTING
|
||||
END_TESTING
|
||||
}
|
||||
|
||||
@@ -48,6 +48,11 @@ int Vector4f0(Vector4f c) {
|
||||
|
||||
typedef VoxRaytracer Raytracer;
|
||||
|
||||
struct TestVoxel {
|
||||
float Value;
|
||||
int Count;
|
||||
};
|
||||
|
||||
int main() {
|
||||
BEGIN_TESTING(Math VoxRaytracer);
|
||||
|
||||
@@ -132,5 +137,41 @@ int main() {
|
||||
ray.PrintSelf(std::cout);
|
||||
}
|
||||
|
||||
#ifdef USE_CUDA
|
||||
{
|
||||
std::cout << "\n--- Testing CUDA Raytracer Accumulator ---\n";
|
||||
|
||||
VoxImage<TestVoxel> img_cuda(Vector3i(4, 4, 4));
|
||||
img_cuda.SetSpacing(Vector3f(2, 2, 2));
|
||||
img_cuda.SetPosition(Vector3f(-4, -4, -4));
|
||||
|
||||
Raytracer ray(img_cuda);
|
||||
|
||||
HLine3f line1;
|
||||
line1.origin << -3, -3, -3, 1;
|
||||
line1.direction << 1, 1, 1, 0;
|
||||
|
||||
HLine3f line2;
|
||||
line2.origin << -3, -3, 1, 1;
|
||||
line2.direction << 1, 1, -1, 0;
|
||||
|
||||
HLine3f lines[2] = {line1, line2};
|
||||
// Execute CUDA kernel wrapper over target VoxImage mapped internally into
|
||||
// VRAM
|
||||
ray.AccumulateLinesCUDA(lines, 2, img_cuda);
|
||||
|
||||
// Validate device synchronization returned data correctly pulling back to
|
||||
// host
|
||||
TEST1(img_cuda.Data().GetDevice() !=
|
||||
MemoryDevice::RAM); // Confirms VRAM executed
|
||||
|
||||
// Pull down checking values
|
||||
float l_val = img_cuda[img_cuda.Find(Vector4f(-3, -3, -3, 1))].Value;
|
||||
std::cout << "Accumulated Voxel test trace point length returned: " << l_val
|
||||
<< "\n";
|
||||
TEST1(l_val > 0.1f);
|
||||
}
|
||||
#endif
|
||||
|
||||
END_TESTING
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user