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; } }
POV_LONG Timer::ElapsedProcessCPUTime () const { if (mCPUTimeSupported) return GetProcessTime () - mProcessTimeStart; else return GetWallTime () - mWallTimeStart; }
POV_LONG Timer::ElapsedThreadCPUTime () const { if (mCPUTimeSupported) return GetThreadTime () - mThreadTimeStart; else return GetWallTime () - mWallTimeStart; }
void Timer::Reset () { mWallTimeStart = GetWallTime (); if (mCPUTimeSupported) { mThreadTimeStart = GetThreadTime (); mProcessTimeStart = GetProcessTime (); } }
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 }
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); }
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; }
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(); }
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()); } } }
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; }
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; }
void vfeTimer::Reset (void) { m_WallTimeStart = GetWallTime(); m_CPUTimeStart = GetCPUTime(); }
POV_LONG vfeTimer::ElapsedRealTime (void) const { return GetWallTime() - m_WallTimeStart; }
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); }
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; } }
POV_LONG Timer::ElapsedRealTime () const { return GetWallTime () - mWallTimeStart; }
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; }
void Timer::Reset () { mWallTimeStart = GetWallTime (); mProcessTimeStart = GetProcessTime (); mThreadTimeStart = GetThreadTime (); }
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); }