Пример #1
0
void SmoothZoom(renderStruct *render, imageStruct *image, RenderMandelbrotPtr RenderMandelbrot,
                const double xReleasePos, const double yReleasePos,
                const double zoomFactor, const double itersFactor)
{
	// Determine new centre
	const double xCentreNew = (xReleasePos/(double)image->xRes*(image->xMax-image->xMin) + image->xMin);
	const double yCentreNew = (yReleasePos/(double)image->yRes*(image->yMax-image->yMin) + image->yMin);

	// Store old min, max values, determine new min, max values
	const double xMinOld = image->xMin;
	const double xMaxOld = image->xMax;
	const double yMinOld = image->yMin;
	const double yMaxOld = image->yMax;
	const double xMinNew = xCentreNew - (image->xMax-image->xMin)/2.0/zoomFactor;
	const double xMaxNew = xCentreNew + (image->xMax-image->xMin)/2.0/zoomFactor;
	const double yMinNew = yCentreNew - (image->yMax-image->yMin)/2.0/zoomFactor;
	const double yMaxNew = yCentreNew + (image->yMax-image->yMin)/2.0/zoomFactor;
	// Store old maxIters value
	const int maxItersOld = image->maxIters;


	// Zoom into new position in ZOOMSTEPS steps, interpolating between old and new boundaries.
	double time = GetWallTime();
	for (int i = 1; i <= image->zoomSteps; i++) {
		double t = INTERPFUNC((double)i/(double)image->zoomSteps);
		image->xMin = xMinOld + (xMinNew - xMinOld)*t;
		image->xMax = xMaxOld + (xMaxNew - xMaxOld)*t;
		image->yMin = yMinOld + (yMinNew - yMinOld)*t;
		image->yMax = yMaxOld + (yMaxNew - yMaxOld)*t;
		image->maxIters = maxItersOld + (itersFactor-1.0)*maxItersOld*t;

		// Re-render mandelbrot set and draw
		RenderMandelbrot(render, image);
		glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
		glfwSwapBuffers(render->window);
	}

	// Want zoom to take ~half a second, so if it is taking too much or too little time,
	// adjust image->zoomSteps to compensate.
	time = GetWallTime() - time;
	if (time > 0.75) {
		int newZoomSteps = (int)fmax(1.0, (0.5/time * image->zoomSteps));
		image->zoomSteps = newZoomSteps;
	}
	else if (time < 0.25) {
		int newZoomSteps = (int)fmin(INITIALZOOMSTEPS, (0.5/time * image->zoomSteps));
		image->zoomSteps = newZoomSteps;
	}
}
Пример #2
0
POV_LONG Timer::ElapsedProcessCPUTime () const
{
    if (mCPUTimeSupported)
        return GetProcessTime () - mProcessTimeStart;
    else
        return GetWallTime () - mWallTimeStart;
}
Пример #3
0
POV_LONG Timer::ElapsedThreadCPUTime () const
{
    if (mCPUTimeSupported)
        return GetThreadTime () - mThreadTimeStart;
    else
        return GetWallTime () - mWallTimeStart;
}
Пример #4
0
void Timer::Reset ()
{
    mWallTimeStart = GetWallTime ();
    if (mCPUTimeSupported)
    {
        mThreadTimeStart = GetThreadTime ();
        mProcessTimeStart = GetProcessTime ();
    }
}
Пример #5
0
void Timer::Stop() {
  int stop_sec, stop_ns;
  GetWallTime(stop_sec,  stop_ns);
  double seconds = (double)( stop_sec - start_sec_ );
  double nano = (double)( stop_ns - start_ns_ );
# ifdef TIMER
  total_ += ( seconds + (nano / 1000000000) );
# else
  total_ += ( seconds + (nano / 1000000) );
#endif
}
Пример #6
0
void RunBenchmark(renderStruct *render, imageStruct *image, RenderMandelbrotPtr RenderMandelbrot)
{
	double startTime = GetWallTime();
	int framesRendered = 0;

	// disable vsync
	glfwSwapInterval(0);

	while ( (framesRendered < 20) || (GetWallTime() - startTime < 5.0) ) {

		RenderMandelbrot(render, image);
		glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
		glfwSwapBuffers(render->window);
		framesRendered++;
	}

	// reenable vsync
	glfwSwapInterval(1);

	double fps = (double)framesRendered/(GetWallTime()-startTime);
	printf("       fps: %lf\n", fps);
}
Пример #7
0
POV_ULONG Timer::GetProcessTime () const
{
    POV_ULONG result;
#if defined(HAVE_DECL_RUSAGE_SELF) && HAVE_DECL_RUSAGE_SELF
    if (mProcessTimeUseGetrusageSelf)
        return (GetrusageMillisec(result, RUSAGE_SELF) ? result : 0);
#endif
#if defined(HAVE_DECL_CLOCK_PROCESS_CPUTIME_ID) && HAVE_DECL_CLOCK_PROCESS_CPUTIME_ID
    if (mProcessTimeUseClockGettimeProcess)
        return (ClockGettimeMillisec(result, CLOCK_PROCESS_CPUTIME_ID) ? result : 0);
#endif
    if (mProcessTimeUseFallback)
        return GetWallTime ();
    return 0;
}
Пример #8
0
unsigned POV_LONG vfeTimer::GetCPUTime (void) const
{
#ifdef HAVE_CLOCK_GETTIME
    struct timespec ts;
#if defined (__FreeBSD__)
    if (clock_gettime(m_ThreadTimeOnly ? CLOCK_THREAD_CPUTIME_ID : CLOCK_REALTIME, &ts) == 0)
#else
    if (clock_gettime(m_ThreadTimeOnly ? CLOCK_THREAD_CPUTIME_ID : CLOCK_PROCESS_CPUTIME_ID, &ts) == 0)
#endif
        return (unsigned POV_LONG) (1000)*ts.tv_sec + ts.tv_nsec/1000000;
#endif
#ifdef HAVE_GETRUSAGE
    struct rusage ru;
#if defined(__sun)
    if (getrusage(m_ThreadTimeOnly ? RUSAGE_LWP : RUSAGE_SELF, &ru) == 0)
#else
    if (getrusage(RUSAGE_SELF, &ru) == 0)
#endif
        return (unsigned POV_LONG) (1000)*(ru.ru_utime.tv_sec + ru.ru_stime.tv_sec)
               + (unsigned POV_LONG)(ru.ru_utime.tv_usec + ru.ru_stime.tv_usec)/1000;
#endif
    return GetWallTime();
}
Пример #9
0
POETCode* EvaluatePOET::parse_input(POETCode* input, POETCode* pattern)
{
   static double token_time = 0, prep_time=0, parse_time=0;
   static bool  first=true;

   bool dt = debug_time;
if (dt) {
 if (first) {
    register_timing(&token_time, "time spent in tokenizer:");
    register_timing(&prep_time, "time spent in parse preparation:");
    register_timing(&parse_time, "time spent in parsing and AST construction:");
 }
first=false;
}

   if (prep->get_entry().get_code() != 0) {
      double cur = (dt?GetWallTime():0);
      XformVar* prep_xform = dynamic_cast<XformVar*>(prep->get_entry().get_code());
      if (prep_xform == 0) INCORRECT_XVAR(prep);
      input = prep_xform->eval(input);
      if (dt) prep_time +=GetWallTime()-cur;
   }
   if (tokens->get_entry().get_code() != 0) {
      double cur = (dt?GetWallTime():0);
      ApplyTokenOperator op(tokens->get_entry().get_code());
      input = op.apply(input);
      if (dt) token_time +=GetWallTime()-cur;
   }
   input = eval_AST(input);
   if (pattern == 0) pattern = parseTarget->get_entry().get_code();
   if (pattern == 0) return input; 
   switch (pattern->get_enum())
    {
    case SRC_READ_INPUT: return input;
    default:
       try { 
          double cur = (dt?GetWallTime():0);
          POETCode* result = parse_AST(input, pattern);
          if (dt) parse_time +=GetWallTime()-cur;
            return result;
          }
       catch (ParseError err) { EXIT(err.message()); }
   }
}
Пример #10
0
int main(void)
{
	printf("\n"
	       "Controls:  - Left/Right Click to zoom in/out, centring on cursor position.\n"
	       "           - Left Click and Drag to pan.\n"
	       "           - r to reset view.\n"
	       "           - q,w to decrease, increase max iteration count\n"
	       "           - a,s to decrease, increase colour period\n"
	       "           - g to toggle Gaussian Blur after computation\n"
	       "           - b to run some benchmarks.\n"
	       "           - p to show a double-precision limited zoom.\n"
	       "           - h to save a high resolution image of the current view to current directory.\n"
	       "           - Esc to quit.\n\n");

	// Set render function, dependent on compile time flag. All have the same signature,
	// with all necessary variables defined inside the structs.
#ifdef WITHOPENCL
	RenderMandelbrotPtr RenderMandelbrot = &RenderMandelbrotOpenCL;
#elif defined(WITHAVX)
	RenderMandelbrotPtr RenderMandelbrot = &RenderMandelbrotAVXCPU;
	// AVX double prec vector width (4) must divide horizontal (x) resolution
	assert(XRESOLUTION % 4 == 0);
#elif defined(WITHGMP)
	RenderMandelbrotPtr RenderMandelbrot = &RenderMandelbrotGMPCPU;
#else
	RenderMandelbrotPtr RenderMandelbrot = &RenderMandelbrotCPU;
#endif


	// Define and initialize structs
	imageStruct image;
	renderStruct render;
	// Set image resolution
	image.xRes = XRESOLUTION;
	image.yRes = YRESOLUTION;
	// Initial values for boundaries, iteration count
	SetInitialValues(&image);
	// Update OpenGL texture on render. This is disabled when rendering high resolution images
	render.updateTex = 1;
	// Allocate host memory, used to set up OpenGL texture, even if we are using interop OpenCL
	image.pixels = malloc(image.xRes * image.yRes * sizeof *(image.pixels) *3);


	// OpenGL variables and setup
	render.window = NULL;
	GLuint vertexShader, fragmentShader, shaderProgram;
	GLuint vao, vbo, ebo, tex;
	SetUpOpenGL(&(render.window), image.xRes, image.yRes, &vertexShader, &fragmentShader, &shaderProgram, &vao, &vbo, &ebo, &tex);


#ifdef WITHOPENCL
	// OpenCL variables and setup
	cl_platform_id    *platform;
	cl_device_id      **device_id;
	cl_program        program;
	cl_int            err;
	render.globalSize = image.xRes * image.yRes;
	render.localSize = OPENCLLOCALSIZE;
	assert(render.globalSize % render.localSize == 0);

	// Initially set variable that controls interop of OpenGL and OpenCL to 0, set to 1 if
	// interop device found successfully
	render.glclInterop = 0;

	if (InitialiseCLEnvironment(&platform, &device_id, &program, &render) == EXIT_FAILURE) {
		printf("Error initialising OpenCL environment\n");
		return EXIT_FAILURE;
	}
	size_t sizeBytes = image.xRes * image.yRes * 3 * sizeof(float);
	render.pixelsDevice = clCreateBuffer(render.contextCL, CL_MEM_READ_WRITE, sizeBytes, NULL, &err);
	// if we aren't using interop, allocate another buffer on the device for output, on the pointer
	// for the texture
	if (render.glclInterop == 0) {
		render.pixelsTex = clCreateBuffer(render.contextCL, CL_MEM_READ_WRITE, sizeBytes, NULL, &err);
	}

	// finish texture initialization so that we can use with OpenCL if glclInterop
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.xRes, image.yRes, 0, GL_RGB, GL_FLOAT, image.pixels);
	// Configure image from OpenGL texture "tex"
	if (render.glclInterop) {
		render.pixelsTex = clCreateFromGLTexture(render.contextCL, CL_MEM_WRITE_ONLY, GL_TEXTURE_2D, 0, tex, &err);
		CheckOpenCLError(err, __LINE__);
	}


	// Create kernels
	render.renderMandelbrotKernel = clCreateKernel(program, "renderMandelbrotKernel", &err);
	CheckOpenCLError(err, __LINE__);
	render.gaussianBlurKernel = clCreateKernel(program, "gaussianBlurKernel", &err);
	CheckOpenCLError(err, __LINE__);
	render.gaussianBlurKernel2 = clCreateKernel(program, "gaussianBlurKernel2", &err);
	CheckOpenCLError(err, __LINE__);
#endif


	// Start main loop: Update until we encounter user input. Look for Esc key (quit), left and right mount
	// buttons (zoom in on cursor position, zoom out on cursor position), "r" -- reset back to initial coords,
	// "b" -- run some benchmarks, "p" -- display a double precision limited zoom.
	// Re-render the Mandelbrot set as and when we need, in the user input conditionals.

	// Initial render:
	RenderMandelbrot(&render, &image);

	while (!glfwWindowShouldClose(render.window)) {

		// draw
		glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
		// Swap buffers
		glfwSwapBuffers(render.window);


		// USER INPUT TESTS.
		// Continuous render, poll for input:
		//glfwPollEvents();
		// Render only on update, wait for input:
		glfwWaitEvents();


		// if user presses Esc, close window to leave loop
		if (glfwGetKey(render.window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
		    glfwSetWindowShouldClose(render.window, GL_TRUE);
		}


		// if user left-clicks in window, zoom in, centring on cursor position
		// if click and drag, simply re-position centre without zooming
		else if (glfwGetMouseButton(render.window, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS) {

			// Get Press cursor location
			double xPressPos, yPressPos, xReleasePos, yReleasePos;
			int shift = 0;
			glfwGetCursorPos(render.window, &xPressPos, &yPressPos);

			// Wait for mousebutton release, re-rendering as mouse moves
			while (glfwGetMouseButton(render.window, GLFW_MOUSE_BUTTON_LEFT) != GLFW_RELEASE) {

				glfwGetCursorPos(render.window, &xReleasePos, &yReleasePos);

				if (fabs(xReleasePos-xPressPos) > DRAGPIXELS || fabs(yReleasePos-yPressPos) > DRAGPIXELS) {
					// Set shift variable. Don't zoom after button release if this is 1
					shift = 1;
					// Determine shift in mandelbrot coords
					double xShift = (xReleasePos-xPressPos)/(double)image.xRes*(image.xMax-image.xMin);
					double yShift = (yReleasePos-yPressPos)/(double)image.yRes*(image.yMax-image.yMin);

					// Add shift to boundaries
					image.xMin = image.xMin - xShift;
					image.xMax = image.xMax - xShift;
					image.yMin = image.yMin - yShift;
					image.yMax = image.yMax - yShift;

					// Update "current" (press) position
					xPressPos = xReleasePos;
					yPressPos = yReleasePos;

					// Re-render and draw
					RenderMandelbrot(&render, &image);
					glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
					glfwSwapBuffers(render.window);
				}
				glfwPollEvents();
			}

			// else, zoom in smoothly over ZOOMSTEPS frames
			if (!shift) {
				SmoothZoom(&render, &image, RenderMandelbrot, xReleasePos, yReleasePos, ZOOMFACTOR, ITERSFACTOR);
			}
		}


		// if user right-clicks in window, zoom out, centring on cursor position
		else if (glfwGetMouseButton(render.window, GLFW_MOUSE_BUTTON_RIGHT) == GLFW_PRESS) {
			while (glfwGetMouseButton(render.window, GLFW_MOUSE_BUTTON_RIGHT) != GLFW_RELEASE) {
				glfwPollEvents();
			}

			// Get cursor position, in *screen coordinates*
			double xReleasePos, yReleasePos;
			glfwGetCursorPos(render.window, &xReleasePos, &yReleasePos);

			// Zooming out, so use 1/FACTORs.
			SmoothZoom(&render, &image, RenderMandelbrot, xReleasePos, yReleasePos, 1.0/ZOOMFACTOR, 1.0/ITERSFACTOR);
		}


		// if user presses "r", reset view
		else if (glfwGetKey(render.window, GLFW_KEY_R) == GLFW_PRESS) {
			while (glfwGetKey(render.window, GLFW_KEY_R) != GLFW_RELEASE) {
				glfwPollEvents();
			}
			printf("Resetting...\n");
			SetInitialValues(&image);
			RenderMandelbrot(&render, &image);
		}


		// if user presses "g", toggle gaussian blur
		else if (glfwGetKey(render.window, GLFW_KEY_G) == GLFW_PRESS) {
			while (glfwGetKey(render.window, GLFW_KEY_G) != GLFW_RELEASE) {
				glfwPollEvents();
			}
			if (image.gaussianBlur == 1) {
				printf("Toggling Gaussian Blur Off...\n");
				image.gaussianBlur = 0;
			}
			else {
				printf("Toggling Gaussian Blur On...\n");
				image.gaussianBlur = 1;
			}
			RenderMandelbrot(&render, &image);
		}


		// if user presses "q", decrease max iteration count
		else if (glfwGetKey(render.window, GLFW_KEY_Q) == GLFW_PRESS) {
			while (glfwGetKey(render.window, GLFW_KEY_Q) != GLFW_RELEASE) {
				glfwPollEvents();
			}
			printf("Decreasing max iteration count from %d to %d\n", image.maxIters, (int)(image.maxIters/ITERSFACTOR));
			image.maxIters /= ITERSFACTOR;
			RenderMandelbrot(&render, &image);
		}
		// if user presses "w", increase max iteration count
		else if (glfwGetKey(render.window, GLFW_KEY_W) == GLFW_PRESS) {
			while (glfwGetKey(render.window, GLFW_KEY_W) != GLFW_RELEASE) {
				glfwPollEvents();
			}
			printf("Increasing max iteration count from %d to %d\n", image.maxIters, (int)(image.maxIters*ITERSFACTOR));
			image.maxIters *= ITERSFACTOR;
			RenderMandelbrot(&render, &image);
		}


		// if user presses "a", decrease colour period
		else if (glfwGetKey(render.window, GLFW_KEY_A) == GLFW_PRESS) {
			while (glfwGetKey(render.window, GLFW_KEY_A) != GLFW_RELEASE) {
				glfwPollEvents();
			}
			printf("Decreasing colour period from %.0lf to %.0lf\n", image.colourPeriod, fmax(32, image.colourPeriod-32));
			image.colourPeriod = fmax(32, image.colourPeriod-32);
			RenderMandelbrot(&render, &image);
		}
		// if user presses "s", increase colour period
		else if (glfwGetKey(render.window, GLFW_KEY_S) == GLFW_PRESS) {
			while (glfwGetKey(render.window, GLFW_KEY_S) != GLFW_RELEASE) {
				glfwPollEvents();
			}
			printf("Increasing colour period from %.0lf to %.0lf\n", image.colourPeriod, image.colourPeriod+32);
			image.colourPeriod += 32;
			RenderMandelbrot(&render, &image);
		}


		// if user presses "b", run some benchmarks.
		else if (glfwGetKey(render.window, GLFW_KEY_B) == GLFW_PRESS) {
			while (glfwGetKey(render.window, GLFW_KEY_B) != GLFW_RELEASE) {
				glfwPollEvents();
			}

			printf("Running Benchmarks...\n");

			printf("Whole fractal:\n");
			SetInitialValues(&image);
			RunBenchmark(&render, &image, RenderMandelbrot);

			printf("Early Bail-out:\n");
			image.xMin = -0.8153143016681144;
			image.xMax = -0.6839170011300622;
			image.yMin = -0.0365167077914237;
			image.yMax =  0.0373942737612310;
			image.maxIters = 112;
			RunBenchmark(&render, &image, RenderMandelbrot);

			printf("Spiral:\n");
			image.xMin = -0.8673755781976442;
			image.xMax = -0.8673711898931797;
			image.yMin = -0.2156059883952151;
			image.yMax = -0.2156035199739536;
			image.maxIters = 1757;
			RunBenchmark(&render, &image, RenderMandelbrot);

			printf("Highly zoomed:\n");
			image.xMin = -0.8712903154956539;
			image.xMax = -0.8712903108993595;
			image.yMin = -0.2293516610223087;
			image.yMax = -0.2293516584368930;
			image.maxIters = 10750;
			RunBenchmark(&render, &image, RenderMandelbrot);

			printf("Complete.\n");
		// Re-render with original coords
			SetInitialValues(&image);
			RenderMandelbrot(&render, &image);
		}


		// if user presses "p", zoom in, such that the double precision algorithm looks pixellated
		else if (glfwGetKey(render.window, GLFW_KEY_P) == GLFW_PRESS) {
			while (glfwGetKey(render.window, GLFW_KEY_P) != GLFW_RELEASE) {
				glfwPollEvents();
			}
			printf("Precision test...\n");
			image.xMin = -1.25334325335487362;
			image.xMax = -1.25334325335481678;
			image.yMin = -0.34446232396119353;
			image.yMax = -0.34446232396116155;
			image.maxIters = 1389952;
			RenderMandelbrot(&render, &image);
		}


		// if user presses "h", render a high resolution version of the current view, and
		// save it to disk as an image
		else if (glfwGetKey(render.window, GLFW_KEY_H) == GLFW_PRESS) {
			while (glfwGetKey(render.window, GLFW_KEY_H) != GLFW_RELEASE) {
				glfwPollEvents();
			}
			double startTime = GetWallTime();
			printf("Saving high resolution (%d x %d) image...\n",
			       image.xRes*HIGHRESOLUTIONMULTIPLIER, image.yRes*HIGHRESOLUTIONMULTIPLIER);
			HighResolutionRender(&render, &image, RenderMandelbrot);
			printf("   --- done. Total time: %lfs\n", GetWallTime()-startTime);
		}
	}



	// clean up
#ifdef WITHOPENCL
	CleanUpCLEnvironment(&platform, &device_id, &(render.contextCL), &(render.queue), &program);
#endif

	glDeleteProgram(shaderProgram);
	glDeleteShader(fragmentShader);
	glDeleteShader(vertexShader);
	glDeleteBuffers(1, &ebo);
	glDeleteBuffers(1, &vbo);
	glDeleteVertexArrays(1, &vao);

	// Close OpenGL window and terminate GLFW
	glfwDestroyWindow(render.window);
	glfwTerminate();

	// Free dynamically allocated memory
	free(image.pixels);
	return 0;
}
Пример #11
0
int main(int argc, char ** argv)
{
    //-----------------------
    // Input pointers
    
    float           *h_Volume = NULL;

	//--------------

    void*           allMemoryPointers[500];
	for (int i = 0; i < 500; i++)
	{
		allMemoryPointers[i] = NULL;
	}
    
	nifti_image*	allNiftiImages[500];
	for (int i = 0; i < 500; i++)
	{
		allNiftiImages[i] = NULL;
	}

    int             numberOfMemoryPointers = 0;
	int				numberOfNiftiImages = 0;

	size_t			allocatedHostMemory = 0;

	//--------------
  
    // Default parameters
    const char*     FILENAME_EXTENSION = "_roi";
    bool            PRINT = true;
	bool			VERBOS = false;
    
    size_t          DATA_W, DATA_H, DATA_D, DATA_T;
    float           VOXEL_SIZE_X, VOXEL_SIZE_Y, VOXEL_SIZE_Z;

	bool			CHANGE_OUTPUT_FILENAME = false;

	// Settings
	float			RADIUS = 5.0f;	
	float			RADIUSV = 5.0f;	

	float			XCOORDINATE = 0.0f;
	float			YCOORDINATE = 0.0f;
	float			ZCOORDINATE = 0.0f;

	float			XCOORDINATEV = 0.0f;
	float			YCOORDINATEV = 0.0f;
	float			ZCOORDINATEV = 0.0f;
	
	bool			MMRADIUS = false;
	bool			VOXELSRADIUS = false;

	bool			MMCOORDINATE = false;
	bool			VOXELSCOORDINATE = false;

    //-----------------------
    // Output parameters
    
    const char      *outputFilename;
       
    //---------------------
    
    /* Input arguments */
    FILE *fp = NULL; 
    
    // No inputs, so print help text
    if (argc == 1)
    {        
        printf("Usage:\n\n");
        printf("MakeROI input.nii [options]\n\n");
        printf("Options:\n\n");
        printf(" -coordinate      Center of ROI (x,y,z), in mm  \n");
        printf(" -coordinatev     Center of ROI (x,y,z), in voxels  \n");
        printf(" -radius          Radius of ROI, in millimeters \n");
        printf(" -radiusv         Radius of ROI, in voxels \n");
		printf(" -output      	  Set filename of nifti file  \n");
        printf("\n\n");
        
        return EXIT_SUCCESS;
    }
    // Try to open file
    else if (argc > 1)
    {        
        fp = fopen(argv[1],"r");
        if (fp == NULL)
        {            
            printf("Could not open file %s !\n",argv[1]);
            return EXIT_FAILURE;
        }
        fclose(fp);        
    }
    
    // Loop over additional inputs
    int i = 2;
    while (i < argc)
    {
        char *input = argv[i];
        char *p;
        if (strcmp(input,"-coordinate") == 0)
        {
			if ( (i+1) >= argc  )
			{
			    printf("Unable to read first value after -coordinate !\n");
                return EXIT_FAILURE;
			}

			if ( (i+2) >= argc  )
			{
			    printf("Unable to read second value after -coordinate !\n");
                return EXIT_FAILURE;
			}

			if ( (i+3) >= argc  )
			{
			    printf("Unable to read third value after -coordinate !\n");
                return EXIT_FAILURE;
			}
            
			MMCOORDINATE = true;
            XCOORDINATE = (float)strtod(argv[i+1], &p);
			YCOORDINATE = (float)strtod(argv[i+2], &p);
			ZCOORDINATE = (float)strtod(argv[i+3], &p);
            
            i += 4;
        }        
        else if (strcmp(input,"-coordinatev") == 0)
        {
			if ( (i+1) >= argc  )
			{
			    printf("Unable to read first value after -coordinatev !\n");
                return EXIT_FAILURE;
			}

			if ( (i+2) >= argc  )
			{
			    printf("Unable to read second value after -coordinatev !\n");
                return EXIT_FAILURE;
			}

			if ( (i+3) >= argc  )
			{
			    printf("Unable to read third value after -coordinatev !\n");
                return EXIT_FAILURE;
			}
            
			VOXELSCOORDINATE = true;
            XCOORDINATEV = (float)strtod(argv[i+1], &p);
			YCOORDINATEV = (float)strtod(argv[i+2], &p);
			ZCOORDINATEV = (float)strtod(argv[i+3], &p);
            
            i += 4;
        }        
        else if (strcmp(input,"-radius") == 0)
        {
			if ( (i+1) >= argc  )
			{
			    printf("Unable to read value after -radius !\n");
                return EXIT_FAILURE;
			}
            
            RADIUS = (float)strtod(argv[i+1], &p);
			MMRADIUS = true;
            
			if (!isspace(*p) && *p != 0)
		    {
		        printf("Radius must be a float! You provided %s \n",argv[i+1]);
				return EXIT_FAILURE;
		    }
  			else if ( RADIUS <= 0.0f )
            {
                printf("Radius must be > 0.0 !\n");
                return EXIT_FAILURE;
            }
            i += 2;
        } 
        else if (strcmp(input,"-radiusv") == 0)
        {
			if ( (i+1) >= argc  )
			{
			    printf("Unable to read value after -radiusv !\n");
                return EXIT_FAILURE;
			}
            
            RADIUSV = (float)strtod(argv[i+1], &p);
			VOXELSRADIUS = true;
            
  			if ( RADIUSV <= 0.0f )
            {
                printf("Radius must be > 0 !\n");
                return EXIT_FAILURE;
            }
            i += 2;
        }        
        else if (strcmp(input,"-output") == 0)
        {
			CHANGE_OUTPUT_FILENAME = true;

			if ( (i+1) >= argc  )
			{
			    printf("Unable to read name after -output !\n");
                return EXIT_FAILURE;
			}

            outputFilename = argv[i+1];
            i += 2;
        }
        else
        {
            printf("Unrecognized option! %s \n",argv[i]);
            return EXIT_FAILURE;
        }                
    }
    
    double startTime = GetWallTime();

    if (!MMCOORDINATE && !VOXELSCOORDINATE)
    {
        printf("Have to define center in mm or in voxels!\n");
        return EXIT_FAILURE;
    }
    if (MMCOORDINATE && VOXELSCOORDINATE)
    {
        printf("Cannot define center in both mm and in voxels!\n");
        return EXIT_FAILURE;
    }


    if (!MMRADIUS && !VOXELSRADIUS)
    {
        printf("Have to define radius in mm or in voxels!\n");
        return EXIT_FAILURE;
    }
    if (MMRADIUS && VOXELSRADIUS)
    {
        printf("Cannot define radius in both mm and in voxels!\n");
        return EXIT_FAILURE;
    }

	// ---------------------
    // Read data
	// ---------------------
    nifti_image *inputData = nifti_image_read(argv[1],1);
    
    if (inputData == NULL)
    {
        printf("Could not open nifti file!\n");
        return EXIT_FAILURE;
    }
    allNiftiImages[numberOfNiftiImages] = inputData;
	numberOfNiftiImages++;

	double endTime = GetWallTime();

	if (VERBOS)
 	{
		printf("It took %f seconds to read the nifti file\n",(float)(endTime - startTime));
	}

    // Get data dimensions
    DATA_W = inputData->nx;
    DATA_H = inputData->ny;
    DATA_D = inputData->nz;
    DATA_T = inputData->nt;

	XCOORDINATE = (float)DATA_W - XCOORDINATE - 1.0f;
	YCOORDINATE = (float)DATA_H - YCOORDINATE - 1.0f;

	if (VOXELSCOORDINATE)
	{
		//XCOORDINATEV = (float)DATA_W - XCOORDINATE - 1.0f;
		//YCOORDINATEV = (float)DATA_H - YCOORDINATE - 1.0f;
		//ZCOORDINATE -= 1.0f;
	}

    // Get voxel sizes
    VOXEL_SIZE_X = inputData->dx;
    VOXEL_SIZE_Y = inputData->dy;
    VOXEL_SIZE_Z = inputData->dz;
    	
    // Calculate size, in bytes
    size_t DATA_SIZE = DATA_W * DATA_H * DATA_D * sizeof(float);
    size_t VOLUME_SIZE = DATA_W * DATA_H * DATA_D * sizeof(float);
    
    // Print some info
    if (PRINT)
    {
        printf("Authored by K.A. Eklund \n");
        printf("Data size: %zu x %zu x %zu \n",  DATA_W, DATA_H, DATA_D);
        printf("Voxel size: %f x %f x %f mm \n", VOXEL_SIZE_X, VOXEL_SIZE_Y, VOXEL_SIZE_Z);   
    } 
   
    // ------------------------------------------------
    
    // Allocate memory on the host
    
	startTime = GetWallTime();

	AllocateMemory(h_Volume, DATA_SIZE, allMemoryPointers, numberOfMemoryPointers, allNiftiImages, numberOfNiftiImages, allocatedHostMemory, "INPUT_DATA");

	endTime = GetWallTime();
    
	if (VERBOS)
 	{
		printf("It took %f seconds to allocate memory\n",(float)(endTime - startTime));
	}

	startTime = GetWallTime();

    // Convert data to floats
    if ( inputData->datatype == DT_SIGNED_SHORT )
    {
        short int *p = (short int*)inputData->data;
    
        for (size_t i = 0; i < DATA_W * DATA_H * DATA_D; i++)
        {
            h_Volume[i] = (float)p[i];
        }
    }
    else if ( inputData->datatype == DT_UINT8 )
    {
        unsigned char *p = (unsigned char*)inputData->data;
    
        for (size_t i = 0; i < DATA_W * DATA_H * DATA_D; i++)
        {
            h_Volume[i] = (float)p[i];
        }
    }
    else if ( inputData->datatype == DT_UINT16 )
    {
        unsigned short int *p = (unsigned short int*)inputData->data;
    
        for (size_t i = 0; i < DATA_W * DATA_H * DATA_D; i++)
        {
            h_Volume[i] = (float)p[i];
        }
    }
	// Correct data type, just copy the pointer
	else if ( inputData->datatype == DT_FLOAT )
    {
        float *p = (float*)inputData->data;
    
        for (size_t i = 0; i < DATA_W * DATA_H * DATA_D; i++)
        {
            h_Volume[i] = p[i];
        }
    }
    else
    {
        printf("Unknown data type in input data, aborting!\n");
        FreeAllMemory(allMemoryPointers,numberOfMemoryPointers);
        FreeAllNiftiImages(allNiftiImages,numberOfNiftiImages);
        return EXIT_FAILURE;
    }

	endTime = GetWallTime();

	if (VERBOS)
 	{
		printf("It took %f seconds to convert data to floats\n",(float)(endTime - startTime));
	}

    //------------------------

	if (MMRADIUS)
	{
		for (int x = 0; x < DATA_W; x++)
		{
			for (int y = 0; y < DATA_H; y++)
			{
				for (int z = 0; z < DATA_D; z++)
				{
					float distance = sqrt( ((float) x - XCOORDINATE)*((float) x - XCOORDINATE)*VOXEL_SIZE_X*VOXEL_SIZE_X + ((float) y - YCOORDINATE)*((float) y - YCOORDINATE)*VOXEL_SIZE_Y*VOXEL_SIZE_Y + ((float) z - ZCOORDINATE)*((float) z - ZCOORDINATE)*VOXEL_SIZE_Z*VOXEL_SIZE_Z   );
					if ( distance <= RADIUS )
					{
						h_Volume[x + y * DATA_W + z * DATA_W * DATA_H] = 1.0f;
					}
					else
					{
						h_Volume[x + y * DATA_W + z * DATA_W * DATA_H] = 0.0f;
					}
				}
			}
		}
	}
	else if (VOXELSRADIUS)
	{
		for (int x = 0; x < DATA_W; x++)
		{
			for (int y = 0; y < DATA_H; y++)
			{
				for (int z = 0; z < DATA_D; z++)
				{
					float distance = sqrt( ((float) x - XCOORDINATE)*((float) x - XCOORDINATE) + ((float) y - YCOORDINATE)*((float) y - YCOORDINATE) + ((float) z - ZCOORDINATE)*((float) z - ZCOORDINATE) );
					if ( distance <= RADIUSV )
					{
						h_Volume[x + y * DATA_W + z * DATA_W * DATA_H] = 1.0f;
					}
					else
					{
						h_Volume[x + y * DATA_W + z * DATA_W * DATA_H] = 0.0f;
					}
				}
			}
		}
	}



    //------------------------
         
    // Write results to file            

    nifti_image *outputNifti = nifti_copy_nim_info(inputData);
    outputNifti->nt = 1;	
    outputNifti->dim[0] = 3;
    outputNifti->dim[4] = 1;
    outputNifti->nvox = DATA_W * DATA_H * DATA_D;
    allNiftiImages[numberOfNiftiImages] = outputNifti;
	numberOfNiftiImages++;

    startTime = GetWallTime();

	if (!CHANGE_OUTPUT_FILENAME)
	{
	    WriteNifti(outputNifti,h_Volume,FILENAME_EXTENSION,ADD_FILENAME,DONT_CHECK_EXISTING_FILE);
	}
	else
	{
		nifti_set_filenames(outputNifti, outputFilename, 0, 1);
		WriteNifti(outputNifti,h_Volume,"",DONT_ADD_FILENAME,DONT_CHECK_EXISTING_FILE);
	}

	endTime = GetWallTime();

	if (VERBOS)
 	{
		printf("It took %f seconds to write the nifti file\n",(float)(endTime - startTime));
	}
    
    // Free all memory
    FreeAllMemory(allMemoryPointers,numberOfMemoryPointers);            
    FreeAllNiftiImages(allNiftiImages,numberOfNiftiImages);
    
    return EXIT_SUCCESS;
}
Пример #12
0
void vfeTimer::Reset (void)
{
    m_WallTimeStart = GetWallTime();
    m_CPUTimeStart = GetCPUTime();
}
Пример #13
0
POV_LONG vfeTimer::ElapsedRealTime (void) const
{
    return GetWallTime() - m_WallTimeStart;
}
Пример #14
0
int main(int argc, char ** argv)
{
    //-----------------------
    // Input pointers
    
    float           *h_fMRI_Volumes = NULL;
    
    void*			allMemoryPointers[500];
    int             numberOfMemoryPointers = 0;

	nifti_image*	allNiftiImages[500];
    int             numberOfNiftiImages = 0;

    // Default parameters
    int             OPENCL_PLATFORM = 0;
    int             OPENCL_DEVICE = 0;
    bool            DEBUG = false;
    const char*     FILENAME_EXTENSION = "_stc";
    bool            PRINT = true;
	bool			VERBOS = false;
    
    int             DATA_W, DATA_H, DATA_D, DATA_T;
    float           EPI_VOXEL_SIZE_X, EPI_VOXEL_SIZE_Y, EPI_VOXEL_SIZE_Z;
	float			TR;
	int				SLICE_ORDER = 0;    

    //-----------------------
    // Output parameters
    
    const char      *outputFilename;
    
    float           *h_Slice_Timing_Corrected_fMRI_Volumes = NULL;
    
    //---------------------
    
    /* Input arguments */
    FILE *fp = NULL; 
    
    // No inputs, so print help text
    if (argc == 1)
    {        
        printf("Usage:\n\n");
        printf("SliceTimingCorrection input.nii [options]\n\n");
        printf("Options:\n\n");
        printf(" -platform        The OpenCL platform to use (default 0) \n");
        printf(" -device          The OpenCL device to use for the specificed platform (default 0) \n");
        printf(" -slicepattern    The sampling pattern used during scanning, 0 = sequential 1-N (bottom-up), 1 = sequential N-1 (top-down), 2 = alternating 1-N, 3 = alternating N-1 (default 0) \n");        
        printf(" -output          Set output filename (default input_stc.nii) \n");
        printf(" -quiet           Don't print anything to the terminal (default false) \n");
        printf(" -verbose         Print extra stuff (default false) \n");
        printf("\n\n");
        
        return EXIT_SUCCESS;
    }
    // Try to open file
    else if (argc > 1)
    {        
        fp = fopen(argv[1],"r");
        if (fp == NULL)
        {            
            printf("Could not open file %s !\n",argv[1]);
            return EXIT_FAILURE;
        }
        fclose(fp);        
    }
    
    // Loop over additional inputs
    int i = 2;
    while (i < argc)
    {
        char *input = argv[i];
        char *p;
        if (strcmp(input,"-platform") == 0)
        {
			if ( (i+1) >= argc  )
			{
			    printf("Unable to read value after -platform !\n");
                return EXIT_FAILURE;
			}

            OPENCL_PLATFORM = (int)strtol(argv[i+1], &p, 10);

			if (!isspace(*p) && *p != 0)
		    {
		        printf("OpenCL platform must be an integer! You provided %s \n",argv[i+1]);
				return EXIT_FAILURE;
		    }
            else if (OPENCL_PLATFORM < 0)
            {
                printf("OpenCL platform must be >= 0!\n");
                return EXIT_FAILURE;
            }
            i += 2;
        }
        else if (strcmp(input,"-device") == 0)
        {
			if ( (i+1) >= argc  )
			{
			    printf("Unable to read value after -device !\n");
                return EXIT_FAILURE;
			}

            OPENCL_DEVICE = (int)strtol(argv[i+1], &p, 10);

			if (!isspace(*p) && *p != 0)
		    {
		        printf("OpenCL device must be an integer! You provided %s \n",argv[i+1]);
				return EXIT_FAILURE;
		    }
            else if (OPENCL_DEVICE < 0)
            {
                printf("OpenCL device must be >= 0!\n");
                return EXIT_FAILURE;
            }
            i += 2;
        }
        else if (strcmp(input,"-slicepattern") == 0)
        {
			if ( (i+1) >= argc  )
			{
			    printf("Unable to read value after -slicepattern !\n");
                return EXIT_FAILURE;
			}

            SLICE_ORDER = (int)strtol(argv[i+1], &p, 10);

			if (!isspace(*p) && *p != 0)
		    {
		        printf("Slice pattern must be an integer! You provided %s \n",argv[i+1]);
				return EXIT_FAILURE;
		    }
            else if (SLICE_ORDER < 0)
            {
                printf("Slice pattern must be a positive number!\n");
                return EXIT_FAILURE;
            }
            else if ( (SLICE_ORDER != 0) && (SLICE_ORDER != 1) && (SLICE_ORDER != 2) && (SLICE_ORDER != 3) )
            {
                printf("Slice pattern must be 0, 1, 2 or 3!\n");
                return EXIT_FAILURE;
            }
            i += 2;
        }
        else if (strcmp(input,"-debug") == 0)
        {
            DEBUG = true;
            i += 1;
        }
        else if (strcmp(input,"-quiet") == 0)
        {
            PRINT = false;
            i += 1;
        }
        else if (strcmp(input,"-verbose") == 0)
        {
            VERBOS = true;
            i += 1;
        }
        else if (strcmp(input,"-output") == 0)
        {
			if ( (i+1) >= argc  )
			{
			    printf("Unable to read name after -output !\n");
                return EXIT_FAILURE;
			}

            outputFilename = argv[i+1];
            i += 2;
        }
        else
        {
            printf("Unrecognized option! %s \n",argv[i]);
            return EXIT_FAILURE;
        }                
    }
    
    double startTime = GetWallTime();

    // Read data
    nifti_image *inputData = nifti_image_read(argv[1],1);
    
    if (inputData == NULL)
    {
        printf("Could not open nifti file!\n");
        return EXIT_FAILURE;
    }
    allNiftiImages[numberOfNiftiImages] = inputData;
	numberOfNiftiImages++;

	double endTime = GetWallTime();

	if (VERBOS)
 	{
		printf("It took %f seconds to read the nifti file\n",(float)(endTime - startTime));
	}

    // Get data dimensions from input data
    DATA_W = inputData->nx;
    DATA_H = inputData->ny;
    DATA_D = inputData->nz;
    DATA_T = inputData->nt;

    // Get voxel sizes from input data
    EPI_VOXEL_SIZE_X = inputData->dx;
    EPI_VOXEL_SIZE_Y = inputData->dy;
    EPI_VOXEL_SIZE_Z = inputData->dz;
    
    // Get repetition time from input data
    TR = inputData->dt;                           

	

    // Calculate size, in bytes
    int DATA_SIZE = DATA_W * DATA_H * DATA_D * DATA_T * sizeof(float);
    int VOLUME_SIZE = DATA_W * DATA_H * DATA_D * sizeof(float);
    
    // Print some info
    if (PRINT)
    {
        printf("Authored by K.A. Eklund \n");
        printf("Data size: %i x %i x %i x %i \n",  DATA_W, DATA_H, DATA_D, DATA_T);
        printf("Voxel size: %f x %f x %f mm \n", EPI_VOXEL_SIZE_X, EPI_VOXEL_SIZE_Y, EPI_VOXEL_SIZE_Z);    
        printf("TR: %f s \n", TR);
    } 
    
    // ------------------------------------------------
    
    // Allocate memory on the host
    
	startTime = GetWallTime();

	AllocateMemory(h_fMRI_Volumes, DATA_SIZE, allMemoryPointers, numberOfMemoryPointers, allNiftiImages, numberOfNiftiImages, "INPUT_DATA");
	AllocateMemory(h_Slice_Timing_Corrected_fMRI_Volumes, DATA_SIZE, allMemoryPointers, numberOfMemoryPointers, allNiftiImages, numberOfNiftiImages, "SLICE_TIMING_CORRECTED_DATA");
    
	endTime = GetWallTime();
    
	if (VERBOS)
 	{
		printf("It took %f seconds to allocate memory\n",(float)(endTime - startTime));
	}

	startTime = GetWallTime();

    // Convert data to floats
    if ( inputData->datatype == DT_SIGNED_SHORT )
    {
        short int *p = (short int*)inputData->data;
    
        for (int i = 0; i < DATA_W * DATA_H * DATA_D * DATA_T; i++)
        {
            h_fMRI_Volumes[i] = (float)p[i];
        }
    }
	else if ( inputData->datatype == DT_FLOAT )
    {
        float *p = (float*)inputData->data;
    
        for (int i = 0; i < DATA_W * DATA_H * DATA_D * DATA_T; i++)
        {
            h_fMRI_Volumes[i] = p[i];
        }
    }
    else
    {
        printf("Unknown data type in input data, aborting!\n");
        FreeAllMemory(allMemoryPointers,numberOfMemoryPointers);
        FreeAllNiftiImages(allNiftiImages,numberOfNiftiImages);
        return EXIT_FAILURE;
    }
    
	endTime = GetWallTime();

	if (VERBOS)
 	{
		printf("It took %f seconds to convert data to floats\n",(float)(endTime - startTime));
	}

    //------------------------
    
	startTime = GetWallTime();

	// Initialize BROCCOLI
    BROCCOLI_LIB BROCCOLI(OPENCL_PLATFORM,OPENCL_DEVICE,2); // 2 = Bash wrapper

	endTime = GetWallTime();

	if (VERBOS)
 	{
		printf("It took %f seconds to initiate BROCCOLI\n",(float)(endTime - startTime));
	}
    
    // Something went wrong...
    if (!BROCCOLI.GetOpenCLInitiated())
    {              
        printf("Initialization error is \"%s\" \n",BROCCOLI.GetOpenCLInitializationError());
		printf("OpenCL error is \"%s\" \n",BROCCOLI.GetOpenCLError());

        // Print create kernel errors
        int* createKernelErrors = BROCCOLI.GetOpenCLCreateKernelErrors();
        for (int i = 0; i < BROCCOLI.GetNumberOfOpenCLKernels(); i++)
        {
            if (createKernelErrors[i] != 0)
            {
                printf("Create kernel error for kernel '%s' is '%s' \n",BROCCOLI.GetOpenCLKernelName(i),BROCCOLI.GetOpenCLErrorMessage(createKernelErrors[i]));
            }
        }                
        
        // Print build info to file    
        fp = fopen("buildinfo.txt","w");
        if (fp == NULL)
        {     
            printf("Could not open buildinfo.txt! \n");
        }
        if (BROCCOLI.GetOpenCLBuildInfoChar() != NULL)
        {
            int error = fputs(BROCCOLI.GetOpenCLBuildInfoChar(),fp);
            if (error == EOF)
            {
                printf("Could not write to buildinfo.txt! \n");
            }
        }
        fclose(fp);
                
        printf("OpenCL initialization failed, aborting! \nSee buildinfo.txt for output of OpenCL compilation!\n");      
        FreeAllMemory(allMemoryPointers,numberOfMemoryPointers);
        FreeAllNiftiImages(allNiftiImages,numberOfNiftiImages);
        return EXIT_FAILURE;
    }
    // Initialization OK
    else
    {
        // Set all necessary pointers and values
        BROCCOLI.SetInputfMRIVolumes(h_fMRI_Volumes);
        
        BROCCOLI.SetEPIWidth(DATA_W);
        BROCCOLI.SetEPIHeight(DATA_H);
        BROCCOLI.SetEPIDepth(DATA_D);
        BROCCOLI.SetEPITimepoints(DATA_T);  
        BROCCOLI.SetEPITR(TR);  
        BROCCOLI.SetEPISliceOrder(SLICE_ORDER);  
                     
        BROCCOLI.SetOutputSliceTimingCorrectedfMRIVolumes(h_Slice_Timing_Corrected_fMRI_Volumes);      
             
        // Run the actual slice timing correction
		startTime = GetWallTime();        
		BROCCOLI.PerformSliceTimingCorrectionWrapper();        
		endTime = GetWallTime();

		if (VERBOS)
	 	{
			printf("\nIt took %f seconds to run the slice timing correction\n",(float)(endTime - startTime));
		}    

        // Print create buffer errors
        int* createBufferErrors = BROCCOLI.GetOpenCLCreateBufferErrors();
        for (int i = 0; i < BROCCOLI.GetNumberOfOpenCLKernels(); i++)
        {
            if (createBufferErrors[i] != 0)
            {
                printf("Create buffer error %i is %d \n",i,BROCCOLI.GetOpenCLErrorMessage(createBufferErrors[i]));
            }
        }
        
        // Print create kernel errors
        int* createKernelErrors = BROCCOLI.GetOpenCLCreateKernelErrors();
        for (int i = 0; i < BROCCOLI.GetNumberOfOpenCLKernels(); i++)
        {
            if (createKernelErrors[i] != 0)
            {
                printf("Create kernel error for kernel '%s' is '%s' \n",BROCCOLI.GetOpenCLKernelName(i),BROCCOLI.GetOpenCLErrorMessage(createKernelErrors[i]));
            }
        } 

        // Print run kernel errors
        int* runKernelErrors = BROCCOLI.GetOpenCLRunKernelErrors();
        for (int i = 0; i < BROCCOLI.GetNumberOfOpenCLKernels(); i++)
        {
            if (runKernelErrors[i] != 0)
            {
                printf("Run kernel error for kernel '%s' is '%s' \n",BROCCOLI.GetOpenCLKernelName(i),BROCCOLI.GetOpenCLErrorMessage(runKernelErrors[i]));
            }
        } 
    }
        
    // Write slice timing corrected data to file            
    startTime = GetWallTime();

	/*
    // Create new nifti image
	nifti_image *outputNifti = nifti_copy_nim_info(inputData);      
	allNiftiImages[numberOfNiftiImages] = outputNifti;
	numberOfNiftiImages++;   
     
    // Copy information from input data    	
	if (!CHANGE_OUTPUT_NAME)
	{
    	nifti_set_filenames(outputNifti, inputData->fname, 0, 1);    
	}
	else
	{
		nifti_set_filenames(outputNifti, outputFilename, 0, 1);    
	}
	*/

    WriteNifti(inputData,h_Slice_Timing_Corrected_fMRI_Volumes,FILENAME_EXTENSION,ADD_FILENAME,DONT_CHECK_EXISTING_FILE);


	endTime = GetWallTime();

	if (VERBOS)
 	{
		printf("It took %f seconds to write the nifti file\n",(float)(endTime - startTime));
	}
    
    // Free all memory
    FreeAllMemory(allMemoryPointers,numberOfMemoryPointers);            
    FreeAllNiftiImages(allNiftiImages,numberOfNiftiImages);
    
    return EXIT_SUCCESS;
}
int main(int argc, char **argv) 
{
  
  /* arrays for storing results of multiple timings */
  double __timer_diff[MT];
  
  /* induction variable for Multiple timing */
  int __pt_MT_ivar;
  
  double __timer_min,__timer_avg,__timer_max;
  
  /* induction variable for multiple invocations in a single timing */
  int __pt_NREP_ivar;
  
  /* variables to support cache flushing */
  double* __pt_flush_buffer;
  double __pt_flush_bufferVal;
  
  /* variable for computing MFLOPS */
  double __pt_flops;
  
  /* induction variables */
  int __pt_i0, __pt_i1, __pt_i2;
  
  /*variables to store starting and ending of timing */
  double __timer_begin, __timer_end; 
  
  /* Declaring parameters of the routine */
  int M;
  int N;
  double alpha;
  double* X;
  int incX;
  double* Y;
  int incY;
  double* A;
  int lda;
  double* X_buf;
  int X_size, X_rep; 
  double* Y_buf;
  int Y_size, Y_rep; 
  double* A_buf;
  int A_size, A_rep; 
  
  /* parameter initializations */
  srand(RANDSEED);
  M = MS;
  N = NS;
  lda = M;
  incY = 1;
  incX = 1;
  alpha = 1;
  X_size=M; 
  X_rep=CacheSZ / X_size + 1; 
  X_buf = calloc(X_size*X_rep, sizeof(double));
  Y_size=N; 
  Y_rep=CacheSZ / Y_size + 1; 
  Y_buf = calloc(Y_size*Y_rep, sizeof(double));
  A_size=M*N; 
  A_rep=CacheSZ / A_size + 1; 
  A_buf = calloc(A_size*A_rep, sizeof(double));
  #define DO_FLUSH 1
  __pt_flush_buffer = malloc(CacheSZ * sizeof(double));
  
  for(__pt_i0=0; __pt_i0 < CacheSZ; ++__pt_i0) {
    __pt_flush_buffer[__pt_i0] = ((__pt_i0 % 3) == 2) ? -1 : __pt_i0 % 2;
  }
  
  /* Multiple Timings */
  for (__pt_MT_ivar=0; __pt_MT_ivar<MT; ++__pt_MT_ivar) {
    srand(RANDSEED);
    for (__pt_i0=0; __pt_i0<X_size *X_rep; ++__pt_i0)
    {
      X_buf[__pt_i0] = rand();; 
    }
    X = X_buf;
    for (__pt_i0=0; __pt_i0<Y_size *Y_rep; ++__pt_i0)
    {
      Y_buf[__pt_i0] = rand();; 
    }
    Y = Y_buf;
    for (__pt_i0=0; __pt_i0<A_size *A_rep; ++__pt_i0)
    {
      A_buf[__pt_i0] = rand();; 
    }
    A = A_buf;
    /* code to flush the cache */
    __pt_flush_bufferVal = 0;
    for (__pt_i0=0; __pt_i0 < CacheSZ; ++__pt_i0)
      __pt_flush_bufferVal += __pt_flush_buffer[__pt_i0];
    assert(__pt_flush_bufferVal < 10);
    
    /* Timer start */
    __timer_begin = GetWallTime();
    /* Timing loop */
    for (__pt_NREP_ivar=0; __pt_NREP_ivar<NREP; ++__pt_NREP_ivar) {
      ATL_dger1_a1_x1_yX (M,N,alpha,X,incX,Y,incY,A,lda);
      if (__pt_i0 < X_rep-1)
        X += X_size;
      else X = X_buf;
      if (__pt_i0 < Y_rep-1)
        Y += Y_size;
      else Y = Y_buf;
      if (__pt_i0 < A_rep-1)
        A += A_size;
      else A = A_buf;
    }
    /* Timer end */
    __timer_end = GetWallTime();
    /* result of a single timing */
    __timer_diff[__pt_MT_ivar] = (__timer_end-__timer_begin)/NREP;
  }
  /* flops of computation */
  __pt_flops = 2*M*N;
  /* Compute minimum of multiple timings */
  __timer_min=__timer_diff[0];
  __timer_max=__timer_diff[0];
  __timer_avg=__timer_diff[0];
  for (__pt_MT_ivar=1; __pt_MT_ivar<MT; ++__pt_MT_ivar)
  {
    if (__timer_min > __timer_diff[__pt_MT_ivar])
        __timer_min = __timer_diff[__pt_MT_ivar];
    if (__timer_max < __timer_diff[__pt_MT_ivar])
        __timer_max = __timer_diff[__pt_MT_ivar];
    __timer_avg += __timer_diff[__pt_MT_ivar];
  }
  __timer_avg /= MT;
  
  
  /* output timing results */
  for (__pt_MT_ivar=0; __pt_MT_ivar < MT; ++__pt_MT_ivar)
  {
    printf("time in seconds [%d]:  %.15f\n", __pt_MT_ivar, __timer_diff[__pt_MT_ivar]);
  
  }
  printf("Minimum time in seconds:  %.15f\n", __timer_min);
  printf("Maximum time in seconds:  %.15f\n", __timer_max);
  printf("Average time in seconds:  %.15f\n", __timer_avg);
  printf("Maximum MFLOPS: %.15f\n", __pt_flops/__timer_min/1000000); 
  printf("Minimum MFLOPS: %.15f\n", __pt_flops/__timer_max/1000000); 
  printf("Average MFLOPS: %.15f\n", __pt_flops/__timer_avg/1000000); 
  printf("Configuration\n"
         "-------------\n");
  printf("CPU MHZ: 2160\n");
  printf("Cache Size: %d\n", CS);
  #ifdef DO_FLUSH
  printf("Cache Flush Method: generic\n");
  #else
  printf("Cache Flush Method: none\n");
  #endif
  printf("ARCH: generic\n");
  printf("nrep: %d\n", NREP);
  printf("mt: %d\n", MT);
  printf("Random Seed: %d\n", RANDSEED);
  return(0);
}
Пример #16
0
int main(int argc, char **argv)
{
    //-----------------------
    // Input
    
    float           *h_First_Level_Results, *h_Mask; 

    unsigned short int        *h_Permutation_Matrix;
	float			*h_Sign_Matrix;
    
    float           *h_X_GLM, *h_xtxxt_GLM, *h_Contrasts, *h_ctxtxc_GLM;  
                  
    //-----------------------
    // Output
    
    int             *h_Cluster_Indices, *h_Cluster_Indices_Out;
    float           *h_Permutation_Distribution;
    float           *h_Beta_Volumes, *h_Residuals, *h_Residual_Variances, *h_Statistical_Maps, *h_P_Values;        
    float           *h_Permuted_First_Level_Results;

	//--------------

    void*           allMemoryPointers[500];
	for (int i = 0; i < 500; i++)
	{
		allMemoryPointers[i] = NULL;
	}
    
	nifti_image*	allNiftiImages[500];
	for (int i = 0; i < 500; i++)
	{
		allNiftiImages[i] = NULL;
	}

    int             numberOfMemoryPointers = 0;
	int				numberOfNiftiImages = 0;

	size_t			allocatedHostMemory = 0;

	//--------------
    
    // Default parameters
        
    int             OPENCL_PLATFORM = 0;
    int             OPENCL_DEVICE = 0;
    bool            DEBUG = false;
    bool            PRINT = true;
	bool			VERBOS = false;
   	bool			CHANGE_OUTPUT_NAME = false;    
                   
    int             NUMBER_OF_GLM_REGRESSORS = 1;
	int				NUMBER_OF_CONTRASTS = 1; 
    float           CLUSTER_DEFINING_THRESHOLD = 2.5f;
	int				NUMBER_OF_PERMUTATIONS = 10000;
	float			SIGNIFICANCE_LEVEL = 0.05f;
	int				TEST_STATISTICS = 0;
	int				INFERENCE_MODE = 1;
	bool			MASK = false;
	const char*		MASK_NAME;
	const char*		DESIGN_FILE;        
	const char*		CONTRASTS_FILE;
	const char* 	PERMUTATION_INPUT_FILE;
	const char* 	PERMUTATION_VALUES_FILE;
	const char* 	PERMUTATION_VECTORS_FILE;

	bool FOUND_DESIGN = false;
	bool FOUND_CONTRASTS = false;
	bool ANALYZE_GROUP_MEAN = false;
	bool USE_PERMUTATION_FILE = false;
	bool WRITE_PERMUTATION_VALUES = false;
	bool WRITE_PERMUTATION_VECTORS = false;
	bool DO_ALL_PERMUTATIONS = false;

	const char*		outputFilename;

    // Size parameters
    int             DATA_W, DATA_H, DATA_D, NUMBER_OF_SUBJECTS;
        
    //---------------------    
    
    /* Input arguments */
    FILE *fp = NULL; 
    
    // No inputs, so print help text
    if (argc == 1)
    {   
		printf("\nThe function performs permutation testing for group analyses.\n\n");     
        printf("General usage:\n\n");
        printf("RandomiseGroupLevel volumes.nii -design design.mat -contrasts design.con [options]\n\n");
        printf("Testing a group mean:\n\n");
        printf("RandomiseGroupLevel volumes.nii -groupmean [options]\n\n");
        printf("Options:\n\n");
        printf(" -platform                  The OpenCL platform to use (default 0) \n");
        printf(" -device                    The OpenCL device to use for the specificed platform (default 0) \n");
        printf(" -design                    The design matrix to apply in each permutation \n");
        printf(" -contrasts                 The contrast vector(s) to apply to the estimated beta values \n");
	    printf(" -groupmean                 Test for group mean, using sign flipping (design and contrast not needed) \n");
        printf(" -mask                      A mask that defines which voxels to permute (default none) \n");
        printf(" -permutations              Number of permutations to use (default 10,000) \n");
        //printf(" -teststatistics            Test statistics to use, 0 = GLM t-test, 1 = GLM F-test, 2 = CCA, 3 = Searchlight (default 0) \n");
        printf(" -inferencemode             Inference mode to use, 0 = voxel, 1 = cluster extent, 2 = cluster mass, 3 = TFCE (default 1) \n");
        printf(" -cdt                       Cluster defining threshold for cluster inference (default 2.5) \n");
        printf(" -significance              The significance level to calculate the threshold for (default 0.05) \n");		
		printf(" -output                    Set output filename (default volumes_perm_tvalues.nii and volumes_perm_pvalues.nii) \n");
		printf(" -writepermutationvalues    Write all the permutation values to a text file \n");
		printf(" -writepermutations         Write all the random permutations (or sign flips) to a text file \n");
		printf(" -permutationfile           Use a specific permutation file or sign flipping file (e.g. from FSL) \n");
        printf(" -quiet                     Don't print anything to the terminal (default false) \n");
        printf(" -verbose                   Print extra stuff (default false) \n");
        printf("\n\n");
        
        return EXIT_SUCCESS;
    }
    // Try to open file
    else if (argc > 1)
    {        
        fp = fopen(argv[1],"r");
        if (fp == NULL)
        {
            printf("Could not open file %s !\n",argv[1]);
            return EXIT_FAILURE;
        }
        fclose(fp);             
    }
    
    // Loop over additional inputs

    int i = 2;
    while (i < argc)
    {
        char *input = argv[i];
        char *p;
        if (strcmp(input,"-platform") == 0)
        {
			if ( (i+1) >= argc  )
			{
			    printf("Unable to read value after -platform !\n");
                return EXIT_FAILURE;
			}

            OPENCL_PLATFORM = (int)strtol(argv[i+1], &p, 10);

			if (!isspace(*p) && *p != 0)
		    {
		        printf("OpenCL platform must be an integer! You provided %s \n",argv[i+1]);
				return EXIT_FAILURE;
		    }
            else if (OPENCL_PLATFORM < 0)
            {
                printf("OpenCL platform must be >= 0!\n");
                return EXIT_FAILURE;
            }
            i += 2;
        }
        else if (strcmp(input,"-device") == 0)
        {
			if ( (i+1) >= argc  )
			{
			    printf("Unable to read value after -device !\n");
                return EXIT_FAILURE;
			}

            OPENCL_DEVICE = (int)strtol(argv[i+1], &p, 10);

			if (!isspace(*p) && *p != 0)
		    {
		        printf("OpenCL device must be an integer! You provided %s \n",argv[i+1]);
				return EXIT_FAILURE;
		    }
            else if (OPENCL_DEVICE < 0)
            {
                printf("OpenCL device must be >= 0!\n");
                return EXIT_FAILURE;
            }
            i += 2;
        }
        else if (strcmp(input,"-design") == 0)
        {
			if ( (i+1) >= argc  )
			{
			    printf("Unable to read value after -design !\n");
                return EXIT_FAILURE;
			}

            DESIGN_FILE = argv[i+1];
			FOUND_DESIGN = true;
            i += 2;
        }
        else if (strcmp(input,"-contrasts") == 0)
        {
			if ( (i+1) >= argc  )
			{
			    printf("Unable to read value after -contrasts !\n");
                return EXIT_FAILURE;
			}

            CONTRASTS_FILE = argv[i+1];
			FOUND_CONTRASTS = true;
            i += 2;
        }
        else if (strcmp(input,"-groupmean") == 0)
        {
			ANALYZE_GROUP_MEAN = true;
			FOUND_DESIGN = true;
			FOUND_CONTRASTS = true;
            i += 1;
        }
        else if (strcmp(input,"-permutations") == 0)
        {
			if ( (i+1) >= argc  )
			{
			    printf("Unable to read value after -permutations !\n");
                return EXIT_FAILURE;
			}

            NUMBER_OF_PERMUTATIONS = (int)strtol(argv[i+1], &p, 10);

			if (!isspace(*p) && *p != 0)
		    {
		        printf("Number of permutations must be an integer! You provided %s \n",argv[i+1]);
				return EXIT_FAILURE;
		    }
            else if (NUMBER_OF_PERMUTATIONS <= 0)
            {
                printf("Number of permutations must be > 0!\n");
                return EXIT_FAILURE;
            }
            i += 2;
        }
        else if (strcmp(input,"-inferencemode") == 0)
        {
			if ( (i+1) >= argc  )
			{
			    printf("Unable to read value after -inferencemode !\n");
                return EXIT_FAILURE;
			}

            INFERENCE_MODE = (int)strtol(argv[i+1], &p, 10);

			if (!isspace(*p) && *p != 0)
		    {
		        printf("Inference mode must be an integer! You provided %s \n",argv[i+1]);
				return EXIT_FAILURE;
		    }
            else if ( (INFERENCE_MODE != 0) && (INFERENCE_MODE != 1) && (INFERENCE_MODE != 2) && (INFERENCE_MODE != 3) )
            {
                printf("Inference mode must be 0, 1, 2 or 3 !\n");
                return EXIT_FAILURE;
            }
            i += 2;

			if (INFERENCE_MODE == 3)
			{
				printf("TFCE is currently turned off!\n");
    	        return EXIT_FAILURE;
			}
        }
        else if (strcmp(input,"-cdt") == 0)
        {
			if ( (i+1) >= argc  )
			{
			    printf("Unable to read value after -cdt !\n");
                return EXIT_FAILURE;
			}

            CLUSTER_DEFINING_THRESHOLD = (float)strtod(argv[i+1], &p);

			if (!isspace(*p) && *p != 0)
		    {
		        printf("Cluster defining threshold must be a float! You provided %s \n",argv[i+1]);
				return EXIT_FAILURE;
		    }
            i += 2;
        }
        else if (strcmp(input,"-significance") == 0)
        {
			if ( (i+1) >= argc  )
			{
			    printf("Unable to read value after -significance !\n");
                return EXIT_FAILURE;
			}

            SIGNIFICANCE_LEVEL = (float)strtod(argv[i+1], &p);

			if (!isspace(*p) && *p != 0)
		    {
		        printf("Significance level must be a float! You provided %s \n",argv[i+1]);
				return EXIT_FAILURE;
		    }
			if ( (SIGNIFICANCE_LEVEL <= 0.0f) || (SIGNIFICANCE_LEVEL >= 1.0f) )
		    {
				float zero = 0.0f;
				float one = 1.0f;
		        printf("Significance level must be between %f and %f ! You provided %f \n",zero,one,SIGNIFICANCE_LEVEL);
				return EXIT_FAILURE;
		    }
            i += 2;
        }
		else if (strcmp(input,"-mask") == 0)
        {
			if ( (i+1) >= argc  )
			{
			    printf("Unable to read name after -mask !\n");
                return EXIT_FAILURE;
			}

			MASK = true;
            MASK_NAME = argv[i+1];
            i += 2;
        }
        else if (strcmp(input,"-debug") == 0)
        {
            DEBUG = true;
            i += 1;
        }
        else if (strcmp(input,"-quiet") == 0)
        {
            PRINT = false;
            i += 1;
        }
        else if (strcmp(input,"-verbose") == 0)
        {
            VERBOS = true;
            i += 1;
        }
        else if (strcmp(input,"-output") == 0)
        {
			if ( (i+1) >= argc  )
			{
			    printf("Unable to read name after -output !\n");
                return EXIT_FAILURE;
			}

			CHANGE_OUTPUT_NAME = true;
            outputFilename = argv[i+1];
            i += 2;
        }
        else if (strcmp(input,"-writepermutationvalues") == 0)
        {
			if ( (i+1) >= argc  )
			{
			    printf("Unable to read name after -writepermutationvalues !\n");
                return EXIT_FAILURE;
			}

			WRITE_PERMUTATION_VALUES = true;
            PERMUTATION_VALUES_FILE = argv[i+1];
            i += 2;
        }
        else if (strcmp(input,"-writepermutations") == 0)
        {
			if ( (i+1) >= argc  )
			{
			    printf("Unable to read name after -writepermutations !\n");
                return EXIT_FAILURE;
			}

			WRITE_PERMUTATION_VECTORS = true;
            PERMUTATION_VECTORS_FILE = argv[i+1];
            i += 2;
        }
        else if (strcmp(input,"-permutationfile") == 0)
        {
			if ( (i+1) >= argc  )
			{
			    printf("Unable to read name after -permutationfile !\n");
                return EXIT_FAILURE;
			}

			USE_PERMUTATION_FILE = true;
            PERMUTATION_INPUT_FILE = argv[i+1];
            i += 2;
        }
        else
        {
            printf("Unrecognized option! %s \n",argv[i]);
            return EXIT_FAILURE;
        }                
    }

	if (!FOUND_DESIGN)
	{
    	printf("No design file detected, aborting! \n");
        return EXIT_FAILURE;
	}

	if (!FOUND_CONTRASTS)
	{
    	printf("No contrasts file detected, aborting! \n");
        return EXIT_FAILURE;
	}

	// Check if BROCCOLI_DIR variable is set
	if (getenv("BROCCOLI_DIR") == NULL)
	{
        printf("The environment variable BROCCOLI_DIR is not set!\n");
        return EXIT_FAILURE;
	}

	//CLUSTER_DEFINING_THRESHOLD = 2.3f;

	double startTime = GetWallTime();
    
    // Read data

    nifti_image *inputData = nifti_image_read(argv[1],1);
    
    if (inputData == NULL)
    {
        printf("Could not open volumes!\n");
        return EXIT_FAILURE;
    }
	allNiftiImages[numberOfNiftiImages] = inputData;
	numberOfNiftiImages++;
    
	nifti_image *inputMask;
	if (MASK)
	{
	    inputMask = nifti_image_read(MASK_NAME,1);
    
	    if (inputMask == NULL)
	    {
        	printf("Could not open mask volume!\n");
	        return EXIT_FAILURE;
	    }
		allNiftiImages[numberOfNiftiImages] = inputMask;
		numberOfNiftiImages++;
	}
	else
	{
       	printf("Warning: No mask being used, doing permutations for all voxels.\n");
	}
    	
	double endTime = GetWallTime();

	if (VERBOS)
 	{
		printf("It took %f seconds to read the nifti file(s)\n",(float)(endTime - startTime));
	}

    // Get data dimensions from input data
   	DATA_W = inputData->nx;
    DATA_H = inputData->ny;
    DATA_D = inputData->nz;    
    NUMBER_OF_SUBJECTS = inputData->nt;    

	// Check if there is more than one volume
	if (NUMBER_OF_SUBJECTS <= 1)
	{
		printf("Input data is a single volume, nothing to permute! \n");
		FreeAllNiftiImages(allNiftiImages,numberOfNiftiImages);
		return EXIT_FAILURE;	
	}

	

	// Check if requested number of permutations is larger than number of possible sign flips, for group mean only
	if (ANALYZE_GROUP_MEAN)
	{
		// Calculate maximum number of sign flips
		unsigned long int SIGN_FLIPS = (unsigned long int)pow(2.0, (double)NUMBER_OF_SUBJECTS);
		if ((unsigned long int)NUMBER_OF_PERMUTATIONS > SIGN_FLIPS)
		{
			printf("Warning: Number of possible sign flips for group mean is %lu, but %i permutations were requested. Lowering number of permutations to number of possible sign flips. \n",SIGN_FLIPS,NUMBER_OF_PERMUTATIONS);
			NUMBER_OF_PERMUTATIONS = (int)SIGN_FLIPS;
			DO_ALL_PERMUTATIONS = true;
		}
		else if ((unsigned long int)NUMBER_OF_PERMUTATIONS == SIGN_FLIPS)
		{
			DO_ALL_PERMUTATIONS = true;
		}
	}
	// Check if requested number of permutations is larger than number of possible permutations
	else
	{
		unsigned long int MAX_PERMS = factorial(NUMBER_OF_SUBJECTS);
		if ((unsigned long int)NUMBER_OF_PERMUTATIONS > MAX_PERMS)
		{
			printf("Warning: Number of possible permutations for your design is %lu, but %i permutations were requested. Lowering number of permutations to number of possible permutations. \n",MAX_PERMS,NUMBER_OF_PERMUTATIONS);
			NUMBER_OF_PERMUTATIONS = (int)MAX_PERMS;
			DO_ALL_PERMUTATIONS = true;
		}
		else if ((unsigned long int)NUMBER_OF_PERMUTATIONS == MAX_PERMS)
		{
			DO_ALL_PERMUTATIONS = true;
		}
	}
    	
	// Check if mask volume has the same dimensions as the data
	if (MASK)
	{
		int TEMP_DATA_W = inputMask->nx;
		int TEMP_DATA_H = inputMask->ny;
		int TEMP_DATA_D = inputMask->nz;

		if ( (TEMP_DATA_W != DATA_W) || (TEMP_DATA_H != DATA_H) || (TEMP_DATA_D != DATA_D) )
		{
			printf("Input data has the dimensions %i x %i x %i, while the mask volume has the dimensions %i x %i x %i. Aborting! \n",DATA_W,DATA_H,DATA_D,TEMP_DATA_W,TEMP_DATA_H,TEMP_DATA_D);
			FreeAllNiftiImages(allNiftiImages,numberOfNiftiImages);
			return EXIT_FAILURE;
		}
	}
    
    // ------------------------------------------------
    
	// Read number of regressors and number of subjects from design matrix file

	std::ifstream design;
	std::ifstream contrasts;

	if (!ANALYZE_GROUP_MEAN)
	{
	    design.open(DESIGN_FILE); 

		if (!design.good())
		{
			design.close();
			printf("Unable to open design file %s. Aborting! \n",DESIGN_FILE);
			FreeAllNiftiImages(allNiftiImages,numberOfNiftiImages);
			return EXIT_FAILURE;
		}

		// Get number of regressors
		std::string tempString;
		int tempNumber;
		design >> tempString; // NumRegressors as string
		std::string NR("NumRegressors");
		if (tempString.compare(NR) != 0)
		{
			design.close();
			printf("First element of the design file should be the string 'NumRegressors', but it is %s. Aborting! \n",tempString.c_str());
			FreeAllNiftiImages(allNiftiImages,numberOfNiftiImages);
			return EXIT_FAILURE;
		}
		design >> NUMBER_OF_GLM_REGRESSORS;
	
		if (NUMBER_OF_GLM_REGRESSORS <= 0)
		{
			design.close();
			printf("Number of regressors must be > 0 ! You provided %i regressors in the design file. Aborting! \n",NUMBER_OF_GLM_REGRESSORS);
			FreeAllNiftiImages(allNiftiImages,numberOfNiftiImages);
			return EXIT_FAILURE;
		}
		else if (NUMBER_OF_GLM_REGRESSORS > 25)
		{
			design.close();
			printf("Number of regressors must be <= 25 ! You provided %i regressors in the design file. Aborting! \n",NUMBER_OF_GLM_REGRESSORS);
			FreeAllNiftiImages(allNiftiImages,numberOfNiftiImages);
			return EXIT_FAILURE;
		}

		// Get number of subjects
		design >> tempString; // NumSubjects as string
		std::string NS("NumSubjects");
		if (tempString.compare(NS) != 0)
		{
			design.close();
			printf("Third element of the design file should be the string 'NumSubjects', but it is %s. Aborting! \n",tempString.c_str());
			FreeAllNiftiImages(allNiftiImages,numberOfNiftiImages);
			return EXIT_FAILURE;
		}
		design >> tempNumber;

		if (tempNumber <= 0)
		{
			design.close();
			printf("Number of subjects must be > 0 ! You provided %i in the design file. Aborting! \n",tempNumber);
			FreeAllNiftiImages(allNiftiImages,numberOfNiftiImages);
			return EXIT_FAILURE;
		}
	
		// Check for consistency
		if ( tempNumber != NUMBER_OF_SUBJECTS )
		{
			design.close();
			printf("Input data contains %i volumes, while the design file says %i subjects. Aborting! \n",NUMBER_OF_SUBJECTS,tempNumber);
			FreeAllNiftiImages(allNiftiImages,numberOfNiftiImages);
			return EXIT_FAILURE;
		}
		
	    // ------------------------------------------------
  
		// Read number of regressors and number of contrasts from contrasts file

	    contrasts.open(CONTRASTS_FILE); 

		if (!contrasts.good())
		{
			contrasts.close();
			printf("Unable to open contrasts file %s. Aborting! \n",CONTRASTS_FILE);
			FreeAllNiftiImages(allNiftiImages,numberOfNiftiImages);
			return EXIT_FAILURE;
		}

		// Get number of regressors and number of subjects
		contrasts >> tempString; // NumRegressors as string	
		if (tempString.compare(NR) != 0)
		{
			contrasts.close();
			printf("First element of the contrasts file should be the string 'NumRegressors', but it is %s. Aborting! \n",tempString.c_str());
			FreeAllNiftiImages(allNiftiImages,numberOfNiftiImages);
			return EXIT_FAILURE;
		}
		contrasts >> tempNumber;
	
		// Check for consistency
		if ( tempNumber != NUMBER_OF_GLM_REGRESSORS )
		{
			contrasts.close();
			printf("Design file says that number of regressors is %i, while contrast file says there are %i regressors. Aborting! \n",NUMBER_OF_GLM_REGRESSORS,tempNumber);
			FreeAllNiftiImages(allNiftiImages,numberOfNiftiImages);
			return EXIT_FAILURE;
		}

		contrasts >> tempString; // NumContrasts as string
		std::string NC("NumContrasts");
		if (tempString.compare(NC) != 0)
		{
			contrasts.close();
			printf("Third element of the contrasts file should be the string 'NumContrasts', but it is %s. Aborting! \n",tempString.c_str());
			FreeAllNiftiImages(allNiftiImages,numberOfNiftiImages);
			return EXIT_FAILURE;
		}
		contrasts >> NUMBER_OF_CONTRASTS;
	
		if (NUMBER_OF_CONTRASTS <= 0)
		{
			contrasts.close();
			printf("Number of contrasts must be > 0 ! You provided %i in the contrasts file. Aborting! \n",NUMBER_OF_CONTRASTS);
			FreeAllNiftiImages(allNiftiImages,numberOfNiftiImages);
			return EXIT_FAILURE;
		}
	}
Пример #17
0
POV_LONG Timer::ElapsedRealTime () const
{
    return GetWallTime () - mWallTimeStart;
}
Пример #18
0
int main(int argc, char ** argv)
{
    //-----------------------
    // Input pointers
    
    float           *h_fMRI_Volumes = NULL;
    float           *h_Quadrature_Filter_1_Real = NULL;
    float           *h_Quadrature_Filter_2_Real = NULL;
    float           *h_Quadrature_Filter_3_Real = NULL;
    float           *h_Quadrature_Filter_1_Imag = NULL;
    float           *h_Quadrature_Filter_2_Imag = NULL;
    float           *h_Quadrature_Filter_3_Imag = NULL;
    
    void*			allMemoryPointers[500];
    int             numberOfMemoryPointers = 0;

	nifti_image*	allNiftiImages[500];
    int             numberOfNiftiImages = 0;

    // Default parameters
    int             MOTION_CORRECTION_FILTER_SIZE = 7; 
    int             NUMBER_OF_ITERATIONS_FOR_MOTION_CORRECTION = 5;
    int             OPENCL_PLATFORM = 0;
    int             OPENCL_DEVICE = 0;
    int             NUMBER_OF_MOTION_CORRECTION_PARAMETERS = 6;    
    bool            DEBUG = false;
    const char*     FILENAME_EXTENSION = "_mc";
    bool            PRINT = true;
	bool			VERBOS = false;
    
    int             DATA_W, DATA_H, DATA_D, DATA_T;
    float           EPI_VOXEL_SIZE_X, EPI_VOXEL_SIZE_Y, EPI_VOXEL_SIZE_Z;
    
    //-----------------------
    // Output parameters
    
    const char      *outputFilename;
    
    float           *h_Quadrature_Filter_Response_1_Real = NULL;
    float           *h_Quadrature_Filter_Response_1_Imag = NULL;
    float           *h_Quadrature_Filter_Response_2_Real = NULL;
    float           *h_Quadrature_Filter_Response_2_Imag = NULL;
    float           *h_Quadrature_Filter_Response_3_Real = NULL;
    float           *h_Quadrature_Filter_Response_3_Imag = NULL;  
    float           *h_Phase_Differences = NULL;
    float           *h_Phase_Certainties = NULL;
    float           *h_Phase_Gradients = NULL;
    float           *h_Motion_Corrected_fMRI_Volumes = NULL;
    float           *h_Motion_Parameters = NULL;
    
    //---------------------
    
    
    /* Input arguments */
    FILE *fp = NULL; 
    
    // No inputs, so print help text
    if (argc == 1)
    {        
        printf("Usage:\n\n");
        printf("MotionCorrection input.nii [options]\n\n");
        printf("Options:\n\n");
        printf(" -platform   The OpenCL platform to use (default 0) \n");
        printf(" -device     The OpenCL device to use for the specificed platform (default 0) \n");
        printf(" -iterations Number of iterations for the motion correction algorithm (default 5) \n");        
        printf(" -output     Set output filename (default input_mc.nii) \n");
        printf(" -quiet      Don't print anything to the terminal (default false) \n");
        printf(" -verbose    Print extra stuff (default false) \n");
        printf(" -debug      Get additional debug information (default false) \n");
        printf("\n\n");
        
        return EXIT_SUCCESS;
    }
    // Try to open file
    else if (argc > 1)
    {        
        fp = fopen(argv[1],"r");
        if (fp == NULL)
        {            
            printf("Could not open file %s !\n",argv[1]);
            return EXIT_FAILURE;
        }
        fclose(fp);        
    }
    
    // Loop over additional inputs
    int i = 2;
    while (i < argc)
    {
        char *input = argv[i];
        char *p;
        if (strcmp(input,"-platform") == 0)
        {
			if ( (i+1) >= argc  )
			{
			    printf("Unable to read value after -platform !\n");
                return EXIT_FAILURE;
			}

            OPENCL_PLATFORM = (int)strtol(argv[i+1], &p, 10);

			if (!isspace(*p) && *p != 0)
		    {
		        printf("OpenCL platform must be an integer! You provided %s \n",argv[i+1]);
				return EXIT_FAILURE;
		    }
            else if (OPENCL_PLATFORM < 0)
            {
                printf("OpenCL platform must be >= 0!\n");
                return EXIT_FAILURE;
            }
            i += 2;
        }
        else if (strcmp(input,"-device") == 0)
        {
			if ( (i+1) >= argc  )
			{
			    printf("Unable to read value after -device !\n");
                return EXIT_FAILURE;
			}

            OPENCL_DEVICE = (int)strtol(argv[i+1], &p, 10);

			if (!isspace(*p) && *p != 0)
		    {
		        printf("OpenCL device must be an integer! You provided %s \n",argv[i+1]);
				return EXIT_FAILURE;
		    }
            else if (OPENCL_DEVICE < 0)
            {
                printf("OpenCL device must be >= 0!\n");
                return EXIT_FAILURE;
            }
            i += 2;
        }
        else if (strcmp(input,"-iterations") == 0)
        {
			if ( (i+1) >= argc  )
			{
			    printf("Unable to read value after -iterations !\n");
                return EXIT_FAILURE;
			}

            NUMBER_OF_ITERATIONS_FOR_MOTION_CORRECTION = (int)strtol(argv[i+1], &p, 10);

			if (!isspace(*p) && *p != 0)
		    {
		        printf("Number of iterations must be an integer! You provided %s \n",argv[i+1]);
				return EXIT_FAILURE;
		    }
            else if (NUMBER_OF_ITERATIONS_FOR_MOTION_CORRECTION <= 0)
            {
                printf("Number of iterations must be a positive number!\n");
                return EXIT_FAILURE;
            }
            i += 2;
        }
        else if (strcmp(input,"-debug") == 0)
        {
            DEBUG = true;
            i += 1;
        }
        else if (strcmp(input,"-quiet") == 0)
        {
            PRINT = false;
            i += 1;
        }
        else if (strcmp(input,"-verbose") == 0)
        {
            VERBOS = true;
            i += 1;
        }
        else if (strcmp(input,"-output") == 0)
        {
			if ( (i+1) >= argc  )
			{
			    printf("Unable to read name after -output !\n");
                return EXIT_FAILURE;
			}

            outputFilename = argv[i+1];
            i += 2;
        }
        else
        {
            printf("Unrecognized option! %s \n",argv[i]);
            return EXIT_FAILURE;
        }                
    }
    
    double startTime = GetWallTime();

    // Read data
    nifti_image *inputData = nifti_image_read(argv[1],1);
    
    if (inputData == NULL)
    {
        printf("Could not open nifti file!\n");
        return EXIT_FAILURE;
    }
    allNiftiImages[numberOfNiftiImages] = inputData;
	numberOfNiftiImages++;

	double endTime = GetWallTime();

	if (VERBOS)
 	{
		printf("It took %f seconds to read the nifti file\n",(float)(endTime - startTime));
	}

    // Get data dimensions from input data
    DATA_W = inputData->nx;
    DATA_H = inputData->ny;
    DATA_D = inputData->nz;
    DATA_T = inputData->nt;
    
    // Get voxel sizes from input data
    EPI_VOXEL_SIZE_X = inputData->dx;
    EPI_VOXEL_SIZE_Y = inputData->dy;
    EPI_VOXEL_SIZE_Z = inputData->dz;
                               
    // Calculate size, in bytes
    int DATA_SIZE = DATA_W * DATA_H * DATA_D * DATA_T * sizeof(float);
    int MOTION_PARAMETERS_SIZE = NUMBER_OF_MOTION_CORRECTION_PARAMETERS * DATA_T * sizeof(float);
    int FILTER_SIZE = MOTION_CORRECTION_FILTER_SIZE * MOTION_CORRECTION_FILTER_SIZE * MOTION_CORRECTION_FILTER_SIZE * sizeof(float);
    int VOLUME_SIZE = DATA_W * DATA_H * DATA_D * sizeof(float);
    
    // Print some info
    if (PRINT)
    {
        printf("Authored by K.A. Eklund \n");
        printf("Data size: %i x %i x %i x %i \n",  DATA_W, DATA_H, DATA_D, DATA_T);
        printf("Voxel size: %f x %f x %f mm \n", EPI_VOXEL_SIZE_X, EPI_VOXEL_SIZE_Y, EPI_VOXEL_SIZE_Z);    
        printf("Number of iterations for motion correction: %i \n",  NUMBER_OF_ITERATIONS_FOR_MOTION_CORRECTION);
    } 
    
    // ------------------------------------------------
    
    // Allocate memory on the host
    
	startTime = GetWallTime();

	AllocateMemory(h_fMRI_Volumes, DATA_SIZE, allMemoryPointers, numberOfMemoryPointers, allNiftiImages, numberOfNiftiImages, "INPUT_DATA");
	AllocateMemory(h_Motion_Corrected_fMRI_Volumes, DATA_SIZE, allMemoryPointers, numberOfMemoryPointers, allNiftiImages, numberOfNiftiImages, "MOTION_CORRECTED_DATA");
	AllocateMemory(h_Quadrature_Filter_1_Real, FILTER_SIZE, allMemoryPointers, numberOfMemoryPointers, allNiftiImages, numberOfNiftiImages, "QUADRATURE_FILTER_1_REAL");    
  	AllocateMemory(h_Quadrature_Filter_1_Imag, FILTER_SIZE, allMemoryPointers, numberOfMemoryPointers, allNiftiImages, numberOfNiftiImages, "QUADRATURE_FILTER_1_IMAG");    
	AllocateMemory(h_Quadrature_Filter_2_Real, FILTER_SIZE, allMemoryPointers, numberOfMemoryPointers, allNiftiImages, numberOfNiftiImages, "QUADRATURE_FILTER_2_REAL");    
  	AllocateMemory(h_Quadrature_Filter_2_Imag, FILTER_SIZE, allMemoryPointers, numberOfMemoryPointers, allNiftiImages, numberOfNiftiImages, "QUADRATURE_FILTER_2_IMAG");    
	AllocateMemory(h_Quadrature_Filter_3_Real, FILTER_SIZE, allMemoryPointers, numberOfMemoryPointers, allNiftiImages, numberOfNiftiImages, "QUADRATURE_FILTER_3_REAL");    
  	AllocateMemory(h_Quadrature_Filter_3_Imag, FILTER_SIZE, allMemoryPointers, numberOfMemoryPointers, allNiftiImages, numberOfNiftiImages, "QUADRATURE_FILTER_3_IMAG");    
	AllocateMemory(h_Motion_Parameters, MOTION_PARAMETERS_SIZE, allMemoryPointers, numberOfMemoryPointers, allNiftiImages, numberOfNiftiImages, "MOTION_PARAMETERS");       
    
    if (DEBUG)
    {    
		AllocateMemory(h_Quadrature_Filter_Response_1_Real, VOLUME_SIZE, allMemoryPointers, numberOfMemoryPointers, allNiftiImages, numberOfNiftiImages, "QUADRATURE_FILTER_RESPONSE_1_REAL");
		AllocateMemory(h_Quadrature_Filter_Response_1_Imag, VOLUME_SIZE, allMemoryPointers, numberOfMemoryPointers, allNiftiImages, numberOfNiftiImages, "QUADRATURE_FILTER_RESPONSE_1_IMAG");        
		AllocateMemory(h_Quadrature_Filter_Response_2_Real, VOLUME_SIZE, allMemoryPointers, numberOfMemoryPointers, allNiftiImages, numberOfNiftiImages, "QUADRATURE_FILTER_RESPONSE_2_REAL");
		AllocateMemory(h_Quadrature_Filter_Response_2_Imag, VOLUME_SIZE, allMemoryPointers, numberOfMemoryPointers, allNiftiImages, numberOfNiftiImages, "QUADRATURE_FILTER_RESPONSE_2_IMAG");        
		AllocateMemory(h_Quadrature_Filter_Response_3_Real, VOLUME_SIZE, allMemoryPointers, numberOfMemoryPointers, allNiftiImages, numberOfNiftiImages, "QUADRATURE_FILTER_RESPONSE_3_REAL");
		AllocateMemory(h_Quadrature_Filter_Response_3_Imag, VOLUME_SIZE, allMemoryPointers, numberOfMemoryPointers, allNiftiImages, numberOfNiftiImages, "QUADRATURE_FILTER_RESPONSE_3_IMAG");        
		AllocateMemory(h_Phase_Differences, VOLUME_SIZE, allMemoryPointers, numberOfMemoryPointers, allNiftiImages, numberOfNiftiImages, "PHASE_DIFFERENCES");        
		AllocateMemory(h_Phase_Certainties, VOLUME_SIZE, allMemoryPointers, numberOfMemoryPointers, allNiftiImages, numberOfNiftiImages, "PHASE_CERTAINTIES");        
		AllocateMemory(h_Phase_Gradients, VOLUME_SIZE, allMemoryPointers, numberOfMemoryPointers, allNiftiImages, numberOfNiftiImages, "PHASE_GRADIENTS");        
    }
    
	endTime = GetWallTime();
    
	if (VERBOS)
 	{
		printf("It took %f seconds to allocate memory\n",(float)(endTime - startTime));
	}

	startTime = GetWallTime();

    // Convert data to floats
    if ( inputData->datatype == DT_SIGNED_SHORT )
    {
        short int *p = (short int*)inputData->data;
    
        for (int i = 0; i < DATA_W * DATA_H * DATA_D * DATA_T; i++)
        {
            h_fMRI_Volumes[i] = (float)p[i];
        }
    }
	else if ( inputData->datatype == DT_FLOAT )
    {
        float *p = (float*)inputData->data;
    
        for (int i = 0; i < DATA_W * DATA_H * DATA_D * DATA_T; i++)
        {
            h_fMRI_Volumes[i] = p[i];
        }
    }
    else
    {
        printf("Unknown data type in input data, aborting!\n");
        FreeAllMemory(allMemoryPointers,numberOfMemoryPointers);
        FreeAllNiftiImages(allNiftiImages,numberOfNiftiImages);
        return EXIT_FAILURE;
    }
    
	endTime = GetWallTime();

	if (VERBOS)
 	{
		printf("It took %f seconds to convert data to floats\n",(float)(endTime - startTime));
	}

	startTime = GetWallTime();

    // Read quadrature filters, three real valued and three imaginary valued

	/*
	std::string path = Getexepath();
	path.erase(path.end()-16, path.end()); // 16 is the number of characters in 'MotionCorrection'
	std::string filter1RealName = path;
	std::string filter1ImagName = path;
	std::string filter2RealName = path;
	std::string filter2ImagName = path;
	std::string filter3RealName = path;
	std::string filter3ImagName = path;
	*/

	std::string filter1RealName;
	std::string filter1ImagName;
	std::string filter2RealName;
	std::string filter2ImagName;
	std::string filter3RealName;
	std::string filter3ImagName;

	filter1RealName.append("filter1_real_linear_registration.bin");
	filter1ImagName.append("filter1_imag_linear_registration.bin");
	filter2RealName.append("filter2_real_linear_registration.bin");
	filter2ImagName.append("filter2_imag_linear_registration.bin");
	filter3RealName.append("filter3_real_linear_registration.bin");
	filter3ImagName.append("filter3_imag_linear_registration.bin");

	ReadBinaryFile(h_Quadrature_Filter_1_Real,MOTION_CORRECTION_FILTER_SIZE*MOTION_CORRECTION_FILTER_SIZE*MOTION_CORRECTION_FILTER_SIZE,filter1RealName.c_str(),allMemoryPointers,numberOfMemoryPointers,allNiftiImages,numberOfNiftiImages); 
	ReadBinaryFile(h_Quadrature_Filter_1_Imag,MOTION_CORRECTION_FILTER_SIZE*MOTION_CORRECTION_FILTER_SIZE*MOTION_CORRECTION_FILTER_SIZE,filter1ImagName.c_str(),allMemoryPointers,numberOfMemoryPointers,allNiftiImages,numberOfNiftiImages); 
	ReadBinaryFile(h_Quadrature_Filter_2_Real,MOTION_CORRECTION_FILTER_SIZE*MOTION_CORRECTION_FILTER_SIZE*MOTION_CORRECTION_FILTER_SIZE,filter2RealName.c_str(),allMemoryPointers,numberOfMemoryPointers,allNiftiImages,numberOfNiftiImages); 
	ReadBinaryFile(h_Quadrature_Filter_2_Imag,MOTION_CORRECTION_FILTER_SIZE*MOTION_CORRECTION_FILTER_SIZE*MOTION_CORRECTION_FILTER_SIZE,filter2ImagName.c_str(),allMemoryPointers,numberOfMemoryPointers,allNiftiImages,numberOfNiftiImages); 
	ReadBinaryFile(h_Quadrature_Filter_3_Real,MOTION_CORRECTION_FILTER_SIZE*MOTION_CORRECTION_FILTER_SIZE*MOTION_CORRECTION_FILTER_SIZE,filter3RealName.c_str(),allMemoryPointers,numberOfMemoryPointers,allNiftiImages,numberOfNiftiImages); 
	ReadBinaryFile(h_Quadrature_Filter_3_Imag,MOTION_CORRECTION_FILTER_SIZE*MOTION_CORRECTION_FILTER_SIZE*MOTION_CORRECTION_FILTER_SIZE,filter3ImagName.c_str(),allMemoryPointers,numberOfMemoryPointers,allNiftiImages,numberOfNiftiImages);     
    
	endTime = GetWallTime();

	if (VERBOS)
 	{
		printf("It took %f seconds to read all binary files\n",(float)(endTime - startTime));
	}    

    //------------------------
    
	startTime = GetWallTime();

	// Initialize BROCCOLI
    BROCCOLI_LIB BROCCOLI(OPENCL_PLATFORM,OPENCL_DEVICE,2); // 2 = Bash wrapper

	endTime = GetWallTime();

	if (VERBOS)
 	{
		printf("It took %f seconds to initiate BROCCOLI\n",(float)(endTime - startTime));
	}
    
    // Something went wrong...
    if (!BROCCOLI.GetOpenCLInitiated())
    {              
        printf("Initialization error is \"%s\" \n",BROCCOLI.GetOpenCLInitializationError());
		printf("OpenCL error is \"%s\" \n",BROCCOLI.GetOpenCLError());

        // Print create kernel errors
        int* createKernelErrors = BROCCOLI.GetOpenCLCreateKernelErrors();
        for (int i = 0; i < BROCCOLI.GetNumberOfOpenCLKernels(); i++)
        {
            if (createKernelErrors[i] != 0)
            {
                printf("Create kernel error %i is %d \n",i,BROCCOLI.GetOpenCLErrorMessage(createKernelErrors[i]));
            }
        }                
        
        // Print build info to file    
        fp = fopen("buildinfo.txt","w");
        if (fp == NULL)
        {     
            printf("Could not open buildinfo.txt! \n");
        }
        if (BROCCOLI.GetOpenCLBuildInfoChar() != NULL)
        {
            int error = fputs(BROCCOLI.GetOpenCLBuildInfoChar(),fp);
            if (error == EOF)
            {
                printf("Could not write to buildinfo.txt! \n");
            }
        }
        fclose(fp);
                
        printf("OpenCL initialization failed, aborting! \nSee buildinfo.txt for output of OpenCL compilation!\n");      
        FreeAllMemory(allMemoryPointers,numberOfMemoryPointers);
        FreeAllNiftiImages(allNiftiImages,numberOfNiftiImages);
        return EXIT_FAILURE;
    }
    // Initialization OK
    else
    {
        // Set all necessary pointers and values
        BROCCOLI.SetInputfMRIVolumes(h_fMRI_Volumes);
        
        BROCCOLI.SetEPIWidth(DATA_W);
        BROCCOLI.SetEPIHeight(DATA_H);
        BROCCOLI.SetEPIDepth(DATA_D);
        BROCCOLI.SetEPITimepoints(DATA_T);   
        
        BROCCOLI.SetEPIVoxelSizeX(EPI_VOXEL_SIZE_X);
        BROCCOLI.SetEPIVoxelSizeY(EPI_VOXEL_SIZE_Y);
        BROCCOLI.SetEPIVoxelSizeZ(EPI_VOXEL_SIZE_Z);        
        
        BROCCOLI.SetImageRegistrationFilterSize(MOTION_CORRECTION_FILTER_SIZE);
        BROCCOLI.SetLinearImageRegistrationFilters(h_Quadrature_Filter_1_Real, h_Quadrature_Filter_1_Imag, h_Quadrature_Filter_2_Real, h_Quadrature_Filter_2_Imag, h_Quadrature_Filter_3_Real, h_Quadrature_Filter_3_Imag);
        BROCCOLI.SetNumberOfIterationsForMotionCorrection(NUMBER_OF_ITERATIONS_FOR_MOTION_CORRECTION);
        
        BROCCOLI.SetOutputMotionCorrectedfMRIVolumes(h_Motion_Corrected_fMRI_Volumes);
        BROCCOLI.SetOutputMotionParameters(h_Motion_Parameters);
      
        if (DEBUG)
        {
			BROCCOLI.SetDebug(true);
            //BROCCOLI.SetOutputQuadratureFilterResponses(h_Quadrature_Filter_Response_1_Real, h_Quadrature_Filter_Response_1_Imag, h_Quadrature_Filter_Response_2_Real, h_Quadrature_Filter_Response_2_Imag, h_Quadrature_Filter_Response_3_Real, h_Quadrature_Filter_Response_3_Imag);
            BROCCOLI.SetOutputPhaseDifferences(h_Phase_Differences);
            BROCCOLI.SetOutputPhaseCertainties(h_Phase_Certainties);
            BROCCOLI.SetOutputPhaseGradients(h_Phase_Gradients);
        }
             
        // Run the actual motion correction
		startTime = GetWallTime();        
		BROCCOLI.PerformMotionCorrectionWrapper();        
		endTime = GetWallTime();

		if (VERBOS)
	 	{
			printf("\nIt took %f seconds to run the motion correction\n",(float)(endTime - startTime));
		}    

        // Print create buffer errors
        int* createBufferErrors = BROCCOLI.GetOpenCLCreateBufferErrors();
        for (int i = 0; i < BROCCOLI.GetNumberOfOpenCLKernels(); i++)
        {
            if (createBufferErrors[i] != 0)
            {
                printf("Create buffer error %i is %d \n",i,BROCCOLI.GetOpenCLErrorMessage(createBufferErrors[i]));
            }
        }
        
        // Print run kernel errors
        int* runKernelErrors = BROCCOLI.GetOpenCLRunKernelErrors();
        for (int i = 0; i < BROCCOLI.GetNumberOfOpenCLKernels(); i++)
        {
            if (runKernelErrors[i] != 0)
            {
                printf("Run kernel error %i is %d \n",i,BROCCOLI.GetOpenCLErrorMessage(runKernelErrors[i]));
            }
        } 
    }
    
        
    // Find max displacement
    float maxDisplacement = 0.0f;
    int maxVolume = 0;
    for (int t = 1; t < DATA_T; t++)
    {        
        float displacement = fabs(h_Motion_Parameters[t + 0*DATA_T]) + fabs(h_Motion_Parameters[t + 1*DATA_T]) + fabs(h_Motion_Parameters[t + 2*DATA_T]) + fabs(h_Motion_Parameters[t + 3*DATA_T]) + fabs(h_Motion_Parameters[t + 4*DATA_T]) + fabs(h_Motion_Parameters[t + 5*DATA_T]);
        
        if (displacement > maxDisplacement)
        {
            maxDisplacement = displacement;
            maxVolume = t;
        }
    }

    if (PRINT)
    {
        printf("Max displacement = %f (mm) at volume %i \n",maxDisplacement,maxVolume);
    }
            
    // Print motion parameters to file
    std::ofstream motion;
    motion.open("motion.1D");      
    if ( motion.good() )
    {
        //motion.setf(ios::scientific);
        motion.precision(6);
        for (int t = 0; t < DATA_T; t++)
        {
            //printf("X translation for timepoint %i is %f\n",t+1,h_Motion_Parameters[t + DATA_T]);
            //motion << h_Motion_Parameters[t + 0*DATA_T] << std::setw(2) << " " << h_Motion_Parameters[t + 1*DATA_T] << std::setw(2) << " " << h_Motion_Parameters[t + 2*DATA_T] << std::setw(2) << " " << h_Motion_Parameters[t + 3*DATA_T] << std::setw(2) << " " << h_Motion_Parameters[t + 4*DATA_T] << std::setw(2) << " " << h_Motion_Parameters[t + 5*DATA_T] << std::endl;
            motion << h_Motion_Parameters[t + 4*DATA_T] << std::setw(2) << " " << -h_Motion_Parameters[t + 3*DATA_T] << std::setw(2) << " " << h_Motion_Parameters[t + 5*DATA_T] << std::setw(2) << " " << -h_Motion_Parameters[t + 2*DATA_T] << std::setw(2) << " " << -h_Motion_Parameters[t + 0*DATA_T] << std::setw(2) << " " << -h_Motion_Parameters[t + 1*DATA_T] << std::endl;
        }
        motion.close();
    }
    else
    {
        printf("Could not open motion.1D for writing!\n");
    }
        
    // Write motion corrected data to file            
    startTime = GetWallTime();

    WriteNifti(inputData,h_Motion_Corrected_fMRI_Volumes,FILENAME_EXTENSION,ADD_FILENAME,DONT_CHECK_EXISTING_FILE);
    
    if (DEBUG)
    {
        WriteNifti(inputData,h_Phase_Differences,"_phase_differences",ADD_FILENAME,DONT_CHECK_EXISTING_FILE);
        WriteNifti(inputData,h_Phase_Gradients,"_phase_gradients",ADD_FILENAME,DONT_CHECK_EXISTING_FILE);
        WriteNifti(inputData,h_Phase_Certainties,"_phase_certainties",ADD_FILENAME,DONT_CHECK_EXISTING_FILE);
        WriteNifti(inputData,h_Quadrature_Filter_Response_1_Real,"_quadrature_filter_responses_1_real",ADD_FILENAME,DONT_CHECK_EXISTING_FILE);
        WriteNifti(inputData,h_Quadrature_Filter_Response_1_Imag,"_quadrature_filter_responses_1_imag",ADD_FILENAME,DONT_CHECK_EXISTING_FILE);
        WriteNifti(inputData,h_Quadrature_Filter_Response_2_Real,"_quadrature_filter_responses_2_real",ADD_FILENAME,DONT_CHECK_EXISTING_FILE);
        WriteNifti(inputData,h_Quadrature_Filter_Response_2_Imag,"_quadrature_filter_responses_2_imag",ADD_FILENAME,DONT_CHECK_EXISTING_FILE);
        WriteNifti(inputData,h_Quadrature_Filter_Response_3_Real,"_quadrature_filter_responses_3_real",ADD_FILENAME,DONT_CHECK_EXISTING_FILE);
        WriteNifti(inputData,h_Quadrature_Filter_Response_3_Imag,"_quadrature_filter_responses_3_imag",ADD_FILENAME,DONT_CHECK_EXISTING_FILE);        
    }

	endTime = GetWallTime();

	if (VERBOS)
 	{
		printf("It took %f seconds to write the nifti file\n",(float)(endTime - startTime));
	}
    
    // Free all memory
    FreeAllMemory(allMemoryPointers,numberOfMemoryPointers);            
    FreeAllNiftiImages(allNiftiImages,numberOfNiftiImages);
    
    return EXIT_SUCCESS;
}
Пример #19
0
void Timer::Reset ()
{
    mWallTimeStart    = GetWallTime ();
    mProcessTimeStart = GetProcessTime ();
    mThreadTimeStart  = GetThreadTime ();
}
Пример #20
0
int main(int argc, char ** argv)
{
    //-----------------------
    // Input pointers

    float           *h_fMRI_Volumes = NULL;
    float           *h_Certainty = NULL;

    //--------------

    void*           allMemoryPointers[500];
    for (int i = 0; i < 500; i++)
    {
        allMemoryPointers[i] = NULL;
    }

    nifti_image*	allNiftiImages[500];
    for (int i = 0; i < 500; i++)
    {
        allNiftiImages[i] = NULL;
    }

    int             numberOfMemoryPointers = 0;
    int				numberOfNiftiImages = 0;

    size_t			allocatedHostMemory = 0;

    //--------------

    // Default parameters
    int             OPENCL_PLATFORM = 0;
    int             OPENCL_DEVICE = 0;
    bool            DEBUG = false;
    const char*     FILENAME_EXTENSION = "_sm";
    bool            PRINT = true;
    bool			VERBOS = false;

    size_t          DATA_W, DATA_H, DATA_D, DATA_T;
    float           EPI_VOXEL_SIZE_X, EPI_VOXEL_SIZE_Y, EPI_VOXEL_SIZE_Z;

    bool			CHANGE_OUTPUT_FILENAME = false;

    // Settings

    float           EPI_SMOOTHING_AMOUNT = 6.0f;
    bool			MASK = false;
    bool			AUTO_MASK = false;
    const char*		MASK_NAME;

    //-----------------------
    // Output parameters

    const char      *outputFilename;

    //---------------------

    /* Input arguments */
    FILE *fp = NULL;

    // No inputs, so print help text
    if (argc == 1)
    {
        printf("Usage:\n\n");
        printf("Smoothing input.nii [options]\n\n");
        printf("Options:\n\n");
        printf(" -platform        The OpenCL platform to use (default 0) \n");
        printf(" -device          The OpenCL device to use for the specificed platform (default 0) \n");
        printf(" -fwhm            Amount of smoothing to apply (in mm, default 6 mm) \n");
        printf(" -mask            Perform smoothing inside mask (normalized convolution) \n");
        printf(" -automask        Generate a mask and perform smoothing inside mask (normalized convolution) \n");
        printf(" -output          Set output filename (default input_sm.nii) \n");
        printf(" -quiet           Don't print anything to the terminal (default false) \n");
        printf(" -verbose         Print extra stuff (default false) \n");
        printf("\n\n");

        return EXIT_SUCCESS;
    }
    // Try to open file
    else if (argc > 1)
    {
        fp = fopen(argv[1],"r");
        if (fp == NULL)
        {
            printf("Could not open file %s !\n",argv[1]);
            return EXIT_FAILURE;
        }
        fclose(fp);
    }

    // Loop over additional inputs
    int i = 2;
    while (i < argc)
    {
        char *input = argv[i];
        char *p;
        if (strcmp(input,"-platform") == 0)
        {
            if ( (i+1) >= argc  )
            {
                printf("Unable to read value after -platform !\n");
                return EXIT_FAILURE;
            }

            OPENCL_PLATFORM = (int)strtol(argv[i+1], &p, 10);

            if (!isspace(*p) && *p != 0)
            {
                printf("OpenCL platform must be an integer! You provided %s \n",argv[i+1]);
                return EXIT_FAILURE;
            }
            else if (OPENCL_PLATFORM < 0)
            {
                printf("OpenCL platform must be >= 0!\n");
                return EXIT_FAILURE;
            }
            i += 2;
        }
        else if (strcmp(input,"-device") == 0)
        {
            if ( (i+1) >= argc  )
            {
                printf("Unable to read value after -device !\n");
                return EXIT_FAILURE;
            }

            OPENCL_DEVICE = (int)strtol(argv[i+1], &p, 10);

            if (!isspace(*p) && *p != 0)
            {
                printf("OpenCL device must be an integer! You provided %s \n",argv[i+1]);
                return EXIT_FAILURE;
            }
            else if (OPENCL_DEVICE < 0)
            {
                printf("OpenCL device must be >= 0!\n");
                return EXIT_FAILURE;
            }
            i += 2;
        }
        else if (strcmp(input,"-fwhm") == 0)
        {
            if ( (i+1) >= argc  )
            {
                printf("Unable to read value after -fwhm !\n");
                return EXIT_FAILURE;
            }

            EPI_SMOOTHING_AMOUNT = (float)strtod(argv[i+1], &p);

            if (!isspace(*p) && *p != 0)
            {
                printf("Smoothing must be a float! You provided %s \n",argv[i+1]);
                return EXIT_FAILURE;
            }
            else if ( EPI_SMOOTHING_AMOUNT <= 0.0f )
            {
                printf("Smoothing must be > 0.0 !\n");
                return EXIT_FAILURE;
            }
            i += 2;
        }
        else if (strcmp(input,"-mask") == 0)
        {
            if ( (i+1) >= argc  )
            {
                printf("Unable to read name after -mask !\n");
                return EXIT_FAILURE;
            }

            MASK = true;
            MASK_NAME = argv[i+1];
            i += 2;
        }
        else if (strcmp(input,"-automask") == 0)
        {
            AUTO_MASK = true;
            i += 1;
        }
        else if (strcmp(input,"-debug") == 0)
        {
            DEBUG = true;
            i += 1;
        }
        else if (strcmp(input,"-quiet") == 0)
        {
            PRINT = false;
            i += 1;
        }
        else if (strcmp(input,"-verbose") == 0)
        {
            VERBOS = true;
            i += 1;
        }
        else if (strcmp(input,"-output") == 0)
        {
            CHANGE_OUTPUT_FILENAME = true;

            if ( (i+1) >= argc  )
            {
                printf("Unable to read name after -output !\n");
                return EXIT_FAILURE;
            }

            outputFilename = argv[i+1];
            i += 2;
        }
        else
        {
            printf("Unrecognized option! %s \n",argv[i]);
            return EXIT_FAILURE;
        }
    }

    // Check if BROCCOLI_DIR variable is set
    if (getenv("BROCCOLI_DIR") == NULL)
    {
        printf("The environment variable BROCCOLI_DIR is not set!\n");
        return EXIT_FAILURE;
    }

    double startTime = GetWallTime();

    // ---------------------
    // Read data
    // ---------------------
    nifti_image *inputData = nifti_image_read(argv[1],1);

    if (inputData == NULL)
    {
        printf("Could not open nifti file!\n");
        return EXIT_FAILURE;
    }
    allNiftiImages[numberOfNiftiImages] = inputData;
    numberOfNiftiImages++;

    // -----------------------
    // Read mask
    // -----------------------

    nifti_image *inputMask;
    if (MASK)
    {
        inputMask = nifti_image_read(MASK_NAME,1);
        if (inputMask == NULL)
        {
            printf("Could not open mask volume!\n");
            FreeAllNiftiImages(allNiftiImages,numberOfNiftiImages);
            return EXIT_FAILURE;
        }
        allNiftiImages[numberOfNiftiImages] = inputMask;
        numberOfNiftiImages++;
    }

    double endTime = GetWallTime();

    if (VERBOS)
    {
        printf("It took %f seconds to read the nifti file\n",(float)(endTime - startTime));
    }

    // Get data dimensions
    DATA_W = inputData->nx;
    DATA_H = inputData->ny;
    DATA_D = inputData->nz;
    DATA_T = inputData->nt;

    // Check if mask volume has the same dimensions as the data
    if (MASK)
    {
        size_t TEMP_DATA_W = inputMask->nx;
        size_t TEMP_DATA_H = inputMask->ny;
        size_t TEMP_DATA_D = inputMask->nz;

        if ( (TEMP_DATA_W != DATA_W) || (TEMP_DATA_H != DATA_H) || (TEMP_DATA_D != DATA_D) )
        {
            printf("Input data has the dimensions %zu x %zu x %zu, while the mask volume has the dimensions %zu x %zu x %zu. Aborting! \n",DATA_W,DATA_H,DATA_D,TEMP_DATA_W,TEMP_DATA_H,TEMP_DATA_D);
            FreeAllNiftiImages(allNiftiImages,numberOfNiftiImages);
            return EXIT_FAILURE;
        }
    }

    // Get voxel sizes
    EPI_VOXEL_SIZE_X = inputData->dx;
    EPI_VOXEL_SIZE_Y = inputData->dy;
    EPI_VOXEL_SIZE_Z = inputData->dz;

    // Calculate size, in bytes
    size_t DATA_SIZE = DATA_W * DATA_H * DATA_D * DATA_T * sizeof(float);
    size_t VOLUME_SIZE = DATA_W * DATA_H * DATA_D * sizeof(float);

    // Print some info
    if (PRINT)
    {
        printf("Authored by K.A. Eklund \n");
        printf("Data size: %zu x %zu x %zu x %zu \n",  DATA_W, DATA_H, DATA_D, DATA_T);
        printf("Voxel size: %f x %f x %f mm \n", EPI_VOXEL_SIZE_X, EPI_VOXEL_SIZE_Y, EPI_VOXEL_SIZE_Z);
        printf("Smoothing filter size: %f mm \n", EPI_SMOOTHING_AMOUNT);
    }

    // ------------------------------------------------

    // Allocate memory on the host

    startTime = GetWallTime();

    // If the data is in float format, we can just copy the pointer
    if ( inputData->datatype != DT_FLOAT )
    {
        AllocateMemory(h_fMRI_Volumes, DATA_SIZE, allMemoryPointers, numberOfMemoryPointers, allNiftiImages, numberOfNiftiImages, allocatedHostMemory, "INPUT_DATA");
    }
    else
    {
        allocatedHostMemory += DATA_SIZE;
    }
    AllocateMemory(h_Certainty, VOLUME_SIZE, allMemoryPointers, numberOfMemoryPointers, allNiftiImages, numberOfNiftiImages, allocatedHostMemory, "CERTAINTY");

    endTime = GetWallTime();

    if (VERBOS)
    {
        printf("It took %f seconds to allocate memory\n",(float)(endTime - startTime));
    }

    startTime = GetWallTime();

    // Convert data to floats
    if ( inputData->datatype == DT_SIGNED_SHORT )
    {
        short int *p = (short int*)inputData->data;

        for (size_t i = 0; i < DATA_W * DATA_H * DATA_D * DATA_T; i++)
        {
            h_fMRI_Volumes[i] = (float)p[i];
        }
    }
    else if ( inputData->datatype == DT_UINT8 )
    {
        unsigned char *p = (unsigned char*)inputData->data;

        for (size_t i = 0; i < DATA_W * DATA_H * DATA_D * DATA_T; i++)
        {
            h_fMRI_Volumes[i] = (float)p[i];
        }
    }
    else if ( inputData->datatype == DT_UINT16 )
    {
        unsigned short int *p = (unsigned short int*)inputData->data;

        for (size_t i = 0; i < DATA_W * DATA_H * DATA_D * DATA_T; i++)
        {
            h_fMRI_Volumes[i] = (float)p[i];
        }
    }
    // Correct data type, just copy the pointer
    else if ( inputData->datatype == DT_FLOAT )
    {
        h_fMRI_Volumes = (float*)inputData->data;

        // Save the pointer in the pointer list
        allMemoryPointers[numberOfMemoryPointers] = (void*)h_fMRI_Volumes;
        numberOfMemoryPointers++;

        //float *p = (float*)inputData->data;

        //for (size_t i = 0; i < DATA_W * DATA_H * DATA_D * DATA_T; i++)
        //{
        //    h_fMRI_Volumes[i] = p[i];
        //}
    }
    else
    {
        printf("Unknown data type in input data, aborting!\n");
        FreeAllMemory(allMemoryPointers,numberOfMemoryPointers);
        FreeAllNiftiImages(allNiftiImages,numberOfNiftiImages);
        return EXIT_FAILURE;
    }

    // Free input fMRI data, it has been converted to floats
    if ( inputData->datatype != DT_FLOAT )
    {
        free(inputData->data);
        inputData->data = NULL;
    }
    // Pointer has been copied to h_fMRI_Volumes and pointer list, so set the input data pointer to NULL
    else
    {
        inputData->data = NULL;
    }

    // Mask is provided by user
    if (MASK)
    {
        if ( inputMask->datatype == DT_SIGNED_SHORT )
        {
            short int *p = (short int*)inputMask->data;

            for (size_t i = 0; i < DATA_W * DATA_H * DATA_D; i++)
            {
                h_Certainty[i] = (float)p[i];
            }
        }
        else if ( inputMask->datatype == DT_UINT16 )
        {
            unsigned short int *p = (unsigned short int*)inputMask->data;

            for (size_t i = 0; i < DATA_W * DATA_H * DATA_D; i++)
            {
                h_Certainty[i] = (float)p[i];
            }
        }
        else if ( inputMask->datatype == DT_FLOAT )
        {
            float *p = (float*)inputMask->data;

            for (size_t i = 0; i < DATA_W * DATA_H * DATA_D; i++)
            {
                h_Certainty[i] = p[i];
            }
        }
        else if ( inputMask->datatype == DT_UINT8 )
        {
            unsigned char *p = (unsigned char*)inputMask->data;

            for (size_t i = 0; i < DATA_W * DATA_H * DATA_D; i++)
            {
                h_Certainty[i] = (float)p[i];
            }
        }
        else
        {
            printf("Unknown data type in mask volume, aborting!\n");
            FreeAllMemory(allMemoryPointers,numberOfMemoryPointers);
            FreeAllNiftiImages(allNiftiImages,numberOfNiftiImages);
            return EXIT_FAILURE;
        }
    }
    // Mask is NOT provided by user, set all mask voxels to 1
    else
    {
        for (size_t i = 0; i < DATA_W * DATA_H * DATA_D; i++)
        {
            h_Certainty[i] = 1.0f;
        }
    }

    endTime = GetWallTime();

    if (VERBOS)
    {
        printf("It took %f seconds to convert data to floats\n",(float)(endTime - startTime));
    }

    //------------------------

    startTime = GetWallTime();

    // Initialize BROCCOLI
    BROCCOLI_LIB BROCCOLI(OPENCL_PLATFORM,OPENCL_DEVICE,2,VERBOS); // 2 = Bash wrapper

    endTime = GetWallTime();

    if (VERBOS)
    {
        printf("It took %f seconds to initiate BROCCOLI\n",(float)(endTime - startTime));
    }

    // Print build info to file (always)
    std::vector<std::string> buildInfo = BROCCOLI.GetOpenCLBuildInfo();
    std::vector<std::string> kernelFileNames = BROCCOLI.GetKernelFileNames();

    std::string buildInfoPath;
    buildInfoPath.append(getenv("BROCCOLI_DIR"));
    buildInfoPath.append("compiled/Kernels/");

    for (int k = 0; k < BROCCOLI.GetNumberOfKernelFiles(); k++)
    {
        std::string temp = buildInfoPath;
        temp.append("buildInfo_");
        temp.append(BROCCOLI.GetOpenCLPlatformName());
        temp.append("_");
        temp.append(BROCCOLI.GetOpenCLDeviceName());
        temp.append("_");
        std::string name = kernelFileNames[k];
        // Remove "kernel" and ".cpp" from kernel filename
        name = name.substr(0,name.size()-4);
        name = name.substr(6,name.size());
        temp.append(name);
        temp.append(".txt");
        fp = fopen(temp.c_str(),"w");
        if (fp == NULL)
        {
            printf("Could not open %s for writing ! \n",temp.c_str());
        }
        else
        {
            if (buildInfo[k].c_str() != NULL)
            {
                int error = fputs(buildInfo[k].c_str(),fp);
                if (error == EOF)
                {
                    printf("Could not write to %s ! \n",temp.c_str());
                }
            }
            fclose(fp);
        }
    }

    // Something went wrong...
    if (!BROCCOLI.GetOpenCLInitiated())
    {
        printf("Initialization error is \"%s\" \n",BROCCOLI.GetOpenCLInitializationError().c_str());
        printf("OpenCL error is \"%s\" \n",BROCCOLI.GetOpenCLError());

        // Print create kernel errors
        int* createKernelErrors = BROCCOLI.GetOpenCLCreateKernelErrors();
        for (int i = 0; i < BROCCOLI.GetNumberOfOpenCLKernels(); i++)
        {
            if (createKernelErrors[i] != 0)
            {
                printf("Create kernel error for kernel '%s' is '%s' \n",BROCCOLI.GetOpenCLKernelName(i),BROCCOLI.GetOpenCLErrorMessage(createKernelErrors[i]));
            }
        }

        printf("OpenCL initialization failed, aborting! \nSee buildInfo* for output of OpenCL compilation!\n");
        FreeAllMemory(allMemoryPointers,numberOfMemoryPointers);
        FreeAllNiftiImages(allNiftiImages,numberOfNiftiImages);
        return EXIT_FAILURE;
    }
    // Initialization OK
    else
    {
        // Set all necessary pointers and values
        BROCCOLI.SetInputfMRIVolumes(h_fMRI_Volumes);
        BROCCOLI.SetAutoMask(AUTO_MASK);
        BROCCOLI.SetInputCertainty(h_Certainty);

        BROCCOLI.SetEPISmoothingAmount(EPI_SMOOTHING_AMOUNT);
        BROCCOLI.SetAllocatedHostMemory(allocatedHostMemory);

        BROCCOLI.SetEPIWidth(DATA_W);
        BROCCOLI.SetEPIHeight(DATA_H);
        BROCCOLI.SetEPIDepth(DATA_D);
        BROCCOLI.SetEPITimepoints(DATA_T);

        BROCCOLI.SetEPIVoxelSizeX(EPI_VOXEL_SIZE_X);
        BROCCOLI.SetEPIVoxelSizeY(EPI_VOXEL_SIZE_Y);
        BROCCOLI.SetEPIVoxelSizeZ(EPI_VOXEL_SIZE_Z);

        // Run the actual slice timing correction
        startTime = GetWallTime();
        BROCCOLI.PerformSmoothingNormalizedHostWrapper();
        endTime = GetWallTime();

        if (VERBOS)
        {
            printf("\nIt took %f seconds to run the smoothing\n",(float)(endTime - startTime));
        }

        // Print create buffer errors
        int* createBufferErrors = BROCCOLI.GetOpenCLCreateBufferErrors();
        for (int i = 0; i < BROCCOLI.GetNumberOfOpenCLKernels(); i++)
        {
            if (createBufferErrors[i] != 0)
            {
                printf("Create buffer error %i is %s \n",i,BROCCOLI.GetOpenCLErrorMessage(createBufferErrors[i]));
            }
        }

        // Print create kernel errors
        int* createKernelErrors = BROCCOLI.GetOpenCLCreateKernelErrors();
        for (int i = 0; i < BROCCOLI.GetNumberOfOpenCLKernels(); i++)
        {
            if (createKernelErrors[i] != 0)
            {
                printf("Create kernel error for kernel '%s' is '%s' \n",BROCCOLI.GetOpenCLKernelName(i),BROCCOLI.GetOpenCLErrorMessage(createKernelErrors[i]));
            }
        }

        // Print run kernel errors
        int* runKernelErrors = BROCCOLI.GetOpenCLRunKernelErrors();
        for (int i = 0; i < BROCCOLI.GetNumberOfOpenCLKernels(); i++)
        {
            if (runKernelErrors[i] != 0)
            {
                printf("Run kernel error for kernel '%s' is '%s' \n",BROCCOLI.GetOpenCLKernelName(i),BROCCOLI.GetOpenCLErrorMessage(runKernelErrors[i]));
            }
        }
    }

    // Write results to file
    startTime = GetWallTime();

    if (!CHANGE_OUTPUT_FILENAME)
    {
        WriteNifti(inputData,h_fMRI_Volumes,FILENAME_EXTENSION,ADD_FILENAME,DONT_CHECK_EXISTING_FILE);
    }
    else
    {
        nifti_set_filenames(inputData, outputFilename, 0, 1);
        WriteNifti(inputData,h_fMRI_Volumes,"",DONT_ADD_FILENAME,DONT_CHECK_EXISTING_FILE);
    }

    if (AUTO_MASK)
    {
        nifti_image *outputNiftifMRISingleVolume = nifti_copy_nim_info(inputData);
        outputNiftifMRISingleVolume->nt = 1;
        outputNiftifMRISingleVolume->dim[0] = 3;
        outputNiftifMRISingleVolume->dim[4] = 1;
        outputNiftifMRISingleVolume->nvox = DATA_W * DATA_H * DATA_D;
        allNiftiImages[numberOfNiftiImages] = outputNiftifMRISingleVolume;
        numberOfNiftiImages++;

        if (!CHANGE_OUTPUT_FILENAME)
        {
            WriteNifti(outputNiftifMRISingleVolume,h_Certainty,"_mask",ADD_FILENAME,DONT_CHECK_EXISTING_FILE);
        }
        else
        {
            nifti_set_filenames(outputNiftifMRISingleVolume, outputFilename, 0, 1);
            WriteNifti(outputNiftifMRISingleVolume,h_Certainty,"_mask",ADD_FILENAME,DONT_CHECK_EXISTING_FILE);
        }
    }

    endTime = GetWallTime();

    if (VERBOS)
    {
        printf("It took %f seconds to write the nifti file\n",(float)(endTime - startTime));
    }

    // Free all memory
    FreeAllMemory(allMemoryPointers,numberOfMemoryPointers);
    FreeAllNiftiImages(allNiftiImages,numberOfNiftiImages);

    return EXIT_SUCCESS;
}
int main(int argc, char **argv) 
{
  
  /* arrays for storing results of multiple timings */
  double __timer_diff[MT];
  
  /* induction variable for Multiple timing */
  int __pt_MT_ivar;
  
  double __timer_min,__timer_avg,__timer_max;
  
  /* induction variable for multiple invocations in a single timing */
  int __pt_NREP_ivar;
  
  /* variables to support cache flushing */
  double* __pt_flush_buffer;
  double __pt_flush_bufferVal;
  
  /* variable for computing MFLOPS */
  double __pt_flops;
  
  /* induction variables */
  int __pt_i0, __pt_i1, __pt_i2;
  
  /*variables to store starting and ending of timing */
  double __timer_begin, __timer_end; 
  
  /* Declaring parameters of the routine */
  int M;
  int N;
  int K;
  double alpha;
  double* A;
  int lda;
  double* B;
  int ldb;
  double beta;
  double* C;
  int ldc;
  double* A_buf;
  int A_size, A_rep; 
  double* B_buf;
  int B_size, B_rep; 
  double* C_buf;
  int C_size, C_rep; 
  
  /* parameter initializations */
  srand(RANDSEED);
  M = MS;
  N = NS;
  K = KS;
  lda = MS;
  ldb = KS;
  ldc = MS;
  alpha = 1;
  beta = 1;
  A_size=16*((15+M*K)/16); 
  A_rep=CacheSZ / A_size + 1; 
  A_buf = calloc(A_size*A_rep, sizeof(double));
  B_size=16*((15+K*N)/16); 
  B_rep=CacheSZ / B_size + 1; 
  B_buf = calloc(B_size*B_rep, sizeof(double));
  C_size=16*((15+M*N)/16); 
  C_rep=CacheSZ / C_size + 1; 
  C_buf = calloc(C_size*C_rep, sizeof(double));
  #define DO_FLUSH 1
  __pt_flush_buffer = malloc(CacheSZ * sizeof(double));
  
  for(__pt_i0=0; __pt_i0 < CacheSZ; ++__pt_i0) {
    __pt_flush_buffer[__pt_i0] = ((__pt_i0 % 3) == 2) ? -1 : __pt_i0 % 2;
  }
  
  /* Multiple Timings */
  for (__pt_MT_ivar=0; __pt_MT_ivar<MT; ++__pt_MT_ivar) {
    srand(RANDSEED);
    for (__pt_i0=0; __pt_i0<A_size *A_rep; ++__pt_i0)
    {
      A_buf[__pt_i0] = rand();; 
    }
    A = A_buf;
    for (__pt_i0=0; __pt_i0<B_size *B_rep; ++__pt_i0)
    {
      B_buf[__pt_i0] = rand();; 
    }
    B = B_buf;
    for (__pt_i0=0; __pt_i0<C_size *C_rep; ++__pt_i0)
    {
      C_buf[__pt_i0] = rand();; 
    }
    C = C_buf;
    /* code to flush the cache */
    __pt_flush_bufferVal = 0;
    for (__pt_i0=0; __pt_i0 < CacheSZ; ++__pt_i0)
      __pt_flush_bufferVal += __pt_flush_buffer[__pt_i0];
    assert(__pt_flush_bufferVal < 10);
    
    /* Timer start */
    __timer_begin = GetWallTime();
    /* Timing loop */
    for (__pt_NREP_ivar=0; __pt_NREP_ivar<NREP; ++__pt_NREP_ivar) {
      ATL_USERMM (M,N,K,alpha,A,lda,B,ldb,beta,C,ldc);
      if (__pt_i0 < A_rep-1)
        A += A_size;
      else A = A_buf;
      if (__pt_i0 < B_rep-1)
        B += B_size;
      else B = B_buf;
      if (__pt_i0 < C_rep-1)
        C += C_size;
      else C = C_buf;
    }
    /* Timer end */
    __timer_end = GetWallTime();
    /* result of a single timing */
    __timer_diff[__pt_MT_ivar] = (__timer_end-__timer_begin)/NREP;
  }
  /* flops of computation */
  __pt_flops = 2*M*N*K+M*N;
  /* Compute minimum of multiple timings */
  __timer_min=__timer_diff[0];
  __timer_max=__timer_diff[0];
  __timer_avg=__timer_diff[0];
  for (__pt_MT_ivar=1; __pt_MT_ivar<MT; ++__pt_MT_ivar)
  {
    if (__timer_min > __timer_diff[__pt_MT_ivar])
        __timer_min = __timer_diff[__pt_MT_ivar];
    if (__timer_max < __timer_diff[__pt_MT_ivar])
        __timer_max = __timer_diff[__pt_MT_ivar];
    __timer_avg += __timer_diff[__pt_MT_ivar];
  }
  __timer_avg /= MT;
  
  
  /* output timing results */
  for (__pt_MT_ivar=0; __pt_MT_ivar < MT; ++__pt_MT_ivar)
  {
    printf("time in seconds [%d]:  %.15f\n", __pt_MT_ivar, __timer_diff[__pt_MT_ivar]);
  
  }
  printf("Minimum time in seconds:  %.15f\n", __timer_min);
  printf("Maximum time in seconds:  %.15f\n", __timer_max);
  printf("Average time in seconds:  %.15f\n", __timer_avg);
  printf("Maximum MFLOPS: %.15f\n", __pt_flops/__timer_min/1000000); 
  printf("Minimum MFLOPS: %.15f\n", __pt_flops/__timer_max/1000000); 
  printf("Average MFLOPS: %.15f\n", __pt_flops/__timer_avg/1000000); 
  printf("Configuration\n"
         "-------------\n");
  printf("CPU MHZ: 2160\n");
  printf("Cache Size: %d\n", CS);
  #ifdef DO_FLUSH
  printf("Cache Flush Method: generic\n");
  #else
  printf("Cache Flush Method: none\n");
  #endif
  printf("ARCH: generic\n");
  printf("nrep: %d\n", NREP);
  printf("mt: %d\n", MT);
  printf("Random Seed: %d\n", RANDSEED);
  return(0);
}