void RisingFactorialCache::Init(int num_already, double hyper) { num_already_ = num_already; hyper_ = hyper; SetInitialValues(); }
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; }
void ArrangementProbNumeratorCache::Init(int num_tables_already, double discount, double concentration) { num_tables_already_ = num_tables_already; discount_ = discount; concentration_ = concentration; SetInitialValues(); }
int main(int argc,char ** argv) { PetscErrorCode ierr; char pfdata_file[PETSC_MAX_PATH_LEN]="datafiles/case9.m"; PFDATA *pfdata; PetscInt numEdges=0,numVertices=0; int *edges = NULL; PetscInt i; DM networkdm; PetscInt componentkey[4]; UserCtx User; PetscLogStage stage1,stage2; PetscMPIInt size; PetscInt eStart, eEnd, vStart, vEnd,j; PetscInt genj,loadj; Vec X,F; Mat J; SNES snes; PetscInitialize(&argc,&argv,"pfoptions",help); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);CHKERRQ(ierr); /* Create an empty network object */ ierr = DMNetworkCreate(PETSC_COMM_WORLD,&networkdm);CHKERRQ(ierr); /* Register the components in the network */ ierr = DMNetworkRegisterComponent(networkdm,"branchstruct",sizeof(struct _p_EDGEDATA),&componentkey[0]);CHKERRQ(ierr); ierr = DMNetworkRegisterComponent(networkdm,"busstruct",sizeof(struct _p_VERTEXDATA),&componentkey[1]);CHKERRQ(ierr); ierr = DMNetworkRegisterComponent(networkdm,"genstruct",sizeof(struct _p_GEN),&componentkey[2]);CHKERRQ(ierr); ierr = DMNetworkRegisterComponent(networkdm,"loadstruct",sizeof(struct _p_LOAD),&componentkey[3]);CHKERRQ(ierr); ierr = PetscLogStageRegister("Read Data",&stage1);CHKERRQ(ierr); PetscLogStagePush(stage1); /* READ THE DATA */ if (!rank) { /* READ DATA */ /* Only rank 0 reads the data */ ierr = PetscOptionsGetString(NULL,NULL,"-pfdata",pfdata_file,PETSC_MAX_PATH_LEN-1,NULL);CHKERRQ(ierr); ierr = PetscNew(&pfdata);CHKERRQ(ierr); ierr = PFReadMatPowerData(pfdata,pfdata_file);CHKERRQ(ierr); User.Sbase = pfdata->sbase; numEdges = pfdata->nbranch; numVertices = pfdata->nbus; ierr = PetscMalloc(2*numEdges*sizeof(int),&edges);CHKERRQ(ierr); ierr = GetListofEdges(pfdata->nbranch,pfdata->branch,edges);CHKERRQ(ierr); } PetscLogStagePop(); ierr = MPI_Barrier(PETSC_COMM_WORLD);CHKERRQ(ierr); ierr = PetscLogStageRegister("Create network",&stage2);CHKERRQ(ierr); PetscLogStagePush(stage2); /* Set number of nodes/edges */ ierr = DMNetworkSetSizes(networkdm,numVertices,numEdges,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); /* Add edge connectivity */ ierr = DMNetworkSetEdgeList(networkdm,edges);CHKERRQ(ierr); /* Set up the network layout */ ierr = DMNetworkLayoutSetUp(networkdm);CHKERRQ(ierr); if (!rank) { ierr = PetscFree(edges);CHKERRQ(ierr); } /* Add network components */ genj=0; loadj=0; ierr = DMNetworkGetEdgeRange(networkdm,&eStart,&eEnd);CHKERRQ(ierr); for (i = eStart; i < eEnd; i++) { ierr = DMNetworkAddComponent(networkdm,i,componentkey[0],&pfdata->branch[i-eStart]);CHKERRQ(ierr); } ierr = DMNetworkGetVertexRange(networkdm,&vStart,&vEnd);CHKERRQ(ierr); for (i = vStart; i < vEnd; i++) { ierr = DMNetworkAddComponent(networkdm,i,componentkey[1],&pfdata->bus[i-vStart]);CHKERRQ(ierr); if (pfdata->bus[i-vStart].ngen) { for (j = 0; j < pfdata->bus[i-vStart].ngen; j++) { ierr = DMNetworkAddComponent(networkdm,i,componentkey[2],&pfdata->gen[genj++]);CHKERRQ(ierr); } } if (pfdata->bus[i-vStart].nload) { for (j=0; j < pfdata->bus[i-vStart].nload; j++) { ierr = DMNetworkAddComponent(networkdm,i,componentkey[3],&pfdata->load[loadj++]);CHKERRQ(ierr); } } /* Add number of variables */ ierr = DMNetworkAddNumVariables(networkdm,i,2);CHKERRQ(ierr); } /* Set up DM for use */ ierr = DMSetUp(networkdm);CHKERRQ(ierr); if (!rank) { ierr = PetscFree(pfdata->bus);CHKERRQ(ierr); ierr = PetscFree(pfdata->gen);CHKERRQ(ierr); ierr = PetscFree(pfdata->branch);CHKERRQ(ierr); ierr = PetscFree(pfdata->load);CHKERRQ(ierr); ierr = PetscFree(pfdata);CHKERRQ(ierr); } ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); if (size > 1) { DM distnetworkdm; /* Network partitioning and distribution of data */ ierr = DMNetworkDistribute(networkdm,0,&distnetworkdm);CHKERRQ(ierr); ierr = DMDestroy(&networkdm);CHKERRQ(ierr); networkdm = distnetworkdm; } PetscLogStagePop(); ierr = DMNetworkGetEdgeRange(networkdm,&eStart,&eEnd);CHKERRQ(ierr); ierr = DMNetworkGetVertexRange(networkdm,&vStart,&vEnd);CHKERRQ(ierr); #if 0 PetscInt numComponents; EDGEDATA edge; PetscInt offset,key,kk; DMNetworkComponentGenericDataType *arr; VERTEXDATA bus; GEN gen; LOAD load; for (i = eStart; i < eEnd; i++) { ierr = DMNetworkGetComponentDataArray(networkdm,&arr);CHKERRQ(ierr); ierr = DMNetworkGetComponentTypeOffset(networkdm,i,0,&key,&offset);CHKERRQ(ierr); edge = (EDGEDATA)(arr+offset); ierr = DMNetworkGetNumComponents(networkdm,i,&numComponents);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_SELF,"Rank %d ncomps = %d Line %d ---- %d\n",rank,numComponents,edge->internal_i,edge->internal_j);CHKERRQ(ierr); } for (i = vStart; i < vEnd; i++) { ierr = DMNetworkGetComponentDataArray(networkdm,&arr);CHKERRQ(ierr); ierr = DMNetworkGetNumComponents(networkdm,i,&numComponents);CHKERRQ(ierr); for (kk=0; kk < numComponents; kk++) { ierr = DMNetworkGetComponentTypeOffset(networkdm,i,kk,&key,&offset);CHKERRQ(ierr); if (key == 1) { bus = (VERTEXDATA)(arr+offset); ierr = PetscPrintf(PETSC_COMM_SELF,"Rank %d ncomps = %d Bus %d\n",rank,numComponents,bus->internal_i);CHKERRQ(ierr); } else if (key == 2) { gen = (GEN)(arr+offset); ierr = PetscPrintf(PETSC_COMM_SELF,"Rank %d Gen pg = %f qg = %f\n",rank,gen->pg,gen->qg);CHKERRQ(ierr); } else if (key == 3) { load = (LOAD)(arr+offset); ierr = PetscPrintf(PETSC_COMM_SELF,"Rank %d Load pl = %f ql = %f\n",rank,load->pl,load->ql);CHKERRQ(ierr); } } } #endif /* Broadcast Sbase to all processors */ ierr = MPI_Bcast(&User.Sbase,1,MPIU_SCALAR,0,PETSC_COMM_WORLD);CHKERRQ(ierr); ierr = DMCreateGlobalVector(networkdm,&X);CHKERRQ(ierr); ierr = VecDuplicate(X,&F);CHKERRQ(ierr); ierr = DMCreateMatrix(networkdm,&J);CHKERRQ(ierr); ierr = MatSetOption(J,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); ierr = SetInitialValues(networkdm,X,&User);CHKERRQ(ierr); /* HOOK UP SOLVER */ ierr = SNESCreate(PETSC_COMM_WORLD,&snes);CHKERRQ(ierr); ierr = SNESSetDM(snes,networkdm);CHKERRQ(ierr); ierr = SNESSetFunction(snes,F,FormFunction,&User);CHKERRQ(ierr); ierr = SNESSetJacobian(snes,J,J,FormJacobian,&User);CHKERRQ(ierr); ierr = SNESSetFromOptions(snes);CHKERRQ(ierr); ierr = SNESSolve(snes,NULL,X);CHKERRQ(ierr); ierr = VecDestroy(&X);CHKERRQ(ierr); ierr = VecDestroy(&F);CHKERRQ(ierr); ierr = MatDestroy(&J);CHKERRQ(ierr); ierr = SNESDestroy(&snes);CHKERRQ(ierr); ierr = DMDestroy(&networkdm);CHKERRQ(ierr); PetscFinalize(); return 0; }