void GenerateData_3DImage_CompareToReference() { int upperThr = 255; int lowerThr = 60; int outsideVal = 0; int insideVal = 100; us::ServiceReference<OclResourceService> ref = GetModuleContext()->GetServiceReference<OclResourceService>(); OclResourceService* resources = GetModuleContext()->GetService<OclResourceService>(ref); resources->GetContext(); //todo why do i need to call this before GetMaximumImageSize()? if(resources->GetMaximumImageSize(2, CL_MEM_OBJECT_IMAGE3D) == 0) { //GPU device does not support 3D images. Skip this test. MITK_INFO << "Skipping test."; return; } try{ m_oclBinaryFilter->SetInput( m_Random3DImage ); m_oclBinaryFilter->SetUpperThreshold( upperThr ); m_oclBinaryFilter->SetLowerThreshold( lowerThr ); m_oclBinaryFilter->SetOutsideValue( outsideVal ); m_oclBinaryFilter->SetInsideValue( insideVal ); m_oclBinaryFilter->Update(); mitk::Image::Pointer outputImage = mitk::Image::New(); outputImage = m_oclBinaryFilter->GetOutput(); // reference computation //This is not optimal here, but since we use a random image //we cannot know the reference image at this point. typedef itk::Image< unsigned char, 3> ImageType; typedef itk::BinaryThresholdImageFilter< ImageType, ImageType > ThresholdFilterType; ImageType::Pointer itkInputImage = ImageType::New(); CastToItkImage( m_Random3DImage, itkInputImage ); ThresholdFilterType::Pointer refThrFilter = ThresholdFilterType::New(); refThrFilter->SetInput( itkInputImage ); refThrFilter->SetLowerThreshold( lowerThr ); refThrFilter->SetUpperThreshold( upperThr ); refThrFilter->SetOutsideValue( outsideVal ); refThrFilter->SetInsideValue( insideVal ); refThrFilter->Update(); mitk::Image::Pointer referenceImage = mitk::Image::New(); mitk::CastToMitkImage(refThrFilter->GetOutput(), referenceImage); MITK_ASSERT_EQUAL( referenceImage, outputImage, "OclBinaryThresholdFilter should be equal to regular itkBinaryThresholdImageFilter."); } catch(mitk::Exception &e) { std::string errorMessage = "Caught unexpected exception "; errorMessage.append(e.what()); CPPUNIT_FAIL(errorMessage.c_str()); } }
/** This function is testing the OclFilter class and the OpenCL resource service. To prevent segmentation faults a mutexed reference counter is implemented in the resource service. It tracks the number of opencl program references for the corresponding filter and delete only the opencl programm if the reference count reaches 0. Every new instance of a filter increases the reference count by 1. This test runs successfull if the 2 filters are initialized, run and deleted without any crash. */ int mitkOclReferenceCountTest( int /*argc*/, char* /*argv*/[] ) { MITK_TEST_BEGIN("mitkOclReferenceCountTest"); us::ServiceReference<OclResourceService> ref = GetModuleContext()->GetServiceReference<OclResourceService>(); OclResourceService* resources = GetModuleContext()->GetService<OclResourceService>(ref); resources->GetContext(); //todo why do i need to call this before GetMaximumImageSize()? if(resources->GetMaximumImageSize(2, CL_MEM_OBJECT_IMAGE3D) == 0) { //GPU device does not support 3D images. Skip this test. MITK_INFO << "Skipping test."; return 0; } mitk::Image::Pointer inputImage = mitk::ImageGenerator::GenerateRandomImage<unsigned char>(119, 204, 52, 1, // dimension 1.0f, 1.0f, 1.0f, // spacing 255, 0); // max, min int upperThr = 255; int lowerThr = 60; int outsideVal = 0; int insideVal = 100; mitk::OclBinaryThresholdImageFilter::Pointer oclFilter1 = mitk::OclBinaryThresholdImageFilter::New(); oclFilter1->SetInput( inputImage ); oclFilter1->SetUpperThreshold( upperThr ); oclFilter1->SetLowerThreshold( lowerThr ); oclFilter1->SetOutsideValue( outsideVal ); oclFilter1->SetInsideValue( insideVal ); oclFilter1->Update(); mitk::Image::Pointer outputImage1 = mitk::Image::New(); outputImage1 = oclFilter1->GetOutput(); mitk::OclBinaryThresholdImageFilter::Pointer oclFilter2 = mitk::OclBinaryThresholdImageFilter::New(); oclFilter2->SetInput( inputImage ); oclFilter2->SetUpperThreshold( upperThr ); oclFilter2->SetLowerThreshold( lowerThr ); oclFilter2->SetOutsideValue( outsideVal ); oclFilter2->SetInsideValue( insideVal ); oclFilter2->Update(); mitk::Image::Pointer outputImage2 = mitk::Image::New(); outputImage2 = oclFilter2->GetOutput(); // delete filters oclFilter1 = NULL; oclFilter2 = NULL; // this is only visible if the delete did not cause a segmentation fault // it is always true and successfull if the program reaches this state MITK_TEST_CONDITION_REQUIRED( true, "2 Filters deleted without a crash -> success "); MITK_TEST_END(); }
/** This function is testing the mitk::OclImage class. */ int mitkOclImageTest( int /*argc*/, char* /*argv*/[] ) { MITK_TEST_BEGIN("mitkOclImageTest"); us::ServiceReference<OclResourceService> ref = GetModuleContext()->GetServiceReference<OclResourceService>(); MITK_TEST_CONDITION_REQUIRED( ref != 0, "Got valid ServiceReference" ); OclResourceService* resources = GetModuleContext()->GetService<OclResourceService>(ref); MITK_TEST_CONDITION_REQUIRED( resources != NULL, "OpenCL Resource service available." ); cl_context gpuContext = resources->GetContext(); MITK_TEST_CONDITION_REQUIRED( gpuContext != NULL, "Got not-null OpenCL context."); cl_device_id gpuDevice = resources->GetCurrentDevice(); MITK_TEST_CONDITION_REQUIRED( gpuDevice != NULL, "Got not-null OpenCL device."); //create a random image mitk::Image::Pointer reference; //check if 3D images are supported by the device and initialize image accordingly if( resources->GetMaximumImageSize(2, CL_MEM_OBJECT_IMAGE3D) == 0 ) //2D required { //Create a random reference image reference = mitk::ImageGenerator::GenerateRandomImage<unsigned char>(119, 204, 0, 0, // dimension 1.0f, 1.0f, 1.0f, // spacing 255, 0); // max, min } else //3D ok { //Create a random reference image reference = mitk::ImageGenerator::GenerateRandomImage<unsigned char>(119, 204, 52, 1, // dimension 1.0f, 1.0f, 1.0f, // spacing 255, 0); // max, min } MITK_TEST_CONDITION_REQUIRED( reference.IsNotNull(), "Reference mitk::Image object instantiated."); mitk::OclImage::Pointer oclTestImage = mitk::OclImage::New(); oclTestImage->InitializeByMitkImage(reference); MITK_TEST_CONDITION_REQUIRED(oclTestImage.IsNotNull(), "oclImage object instantiated."); // test if oclImage correct initialized MITK_TEST_CONDITION( oclTestImage->GetMITKImage() == reference, "oclImage has the correct reference mitk::Image"); MITK_TEST_CONDITION( oclTestImage->GetDimension() == reference->GetDimension(), "Same dimensionality."); cl_int clErr = 0; cl_command_queue cmdQueue = clCreateCommandQueue( gpuContext, gpuDevice, 0 ,&clErr); MITK_TEST_CONDITION_REQUIRED( clErr == CL_SUCCESS, "A command queue was created."); // Allocate and copy image data to GPU try { oclTestImage->TransferDataToGPU(cmdQueue); MITK_TEST_CONDITION( oclTestImage->IsModified(0), "Modified flag for GPU correctly set."); // check if the created GPU object is valid cl_mem gpuImage = oclTestImage->GetGPUImage(cmdQueue); MITK_TEST_CONDITION_REQUIRED( gpuImage != NULL, "oclImage returned a valid GPU memory pointer"); size_t returned = 0; cl_image_format imgFmt; clErr = clGetImageInfo( gpuImage, CL_IMAGE_FORMAT, sizeof(cl_image_format), (void*) &imgFmt, &returned ); MITK_TEST_CONDITION( clErr == CL_SUCCESS, "oclImage has created a valid GPU image"); // test for dimensions size_t imagesize = 0; clErr = clGetImageInfo( gpuImage, CL_IMAGE_WIDTH, sizeof(size_t), (void*) &imagesize, &returned ); MITK_TEST_CONDITION( imagesize == static_cast<size_t>(oclTestImage->GetDimension(0)), "Image width corresponds" ); clErr = clGetImageInfo( gpuImage, CL_IMAGE_HEIGHT, sizeof(size_t), (void*) &imagesize, &returned ); MITK_TEST_CONDITION( imagesize == static_cast<size_t>(oclTestImage->GetDimension(1)), "Image height corresponds" ); clErr = clGetImageInfo( gpuImage, CL_IMAGE_DEPTH, sizeof(size_t), (void*) &imagesize, &returned ); MITK_TEST_CONDITION( imagesize == static_cast<size_t>(oclTestImage->GetDimension(2)), "Image depth corresponds" ); // clean up clReleaseCommandQueue( cmdQueue ); } catch(mitk::ImageTypeIsNotSupportedByGPU& e) { MITK_ERROR << "Caught exception: " << e.what(); //Image type is not supported -> skip test. } MITK_TEST_END(); }