private synchronized void unload() { if (initialized) { if ((projectionVolume != null) && (!largeVolumeMode)) { commandQueue.putReadBuffer(volumePointer, true).finish(); volumePointer.getBuffer().rewind(); volumePointer.getBuffer().get(h_volume); volumePointer.getBuffer().rewind(); int width = projectionVolume.getSize()[0]; int height = projectionVolume.getSize()[1]; if (this.useVOImap) { for (int k = 0; k < projectionVolume.getSize()[2]; k++) { for (int j = 0; j < height; j++) { for (int i = 0; i < width; i++) { float value = h_volume[(((height * k) + j) * width) + i]; if (voiMap[i][j][k]) { projectionVolume.setAtIndex(i, j, k, value); } else { projectionVolume.setAtIndex(i, j, k, 0); } } } } } else { for (int k = 0; k < projectionVolume.getSize()[2]; k++) { for (int j = 0; j < height; j++) { for (int i = 0; i < width; i++) { float value = h_volume[(((height * k) + j) * width) + i]; projectionVolume.setAtIndex(i, j, k, value); } } } } } else { System.out.println("Check ProjectionVolume. It seems null."); } h_volume = null; // free memory on device commandQueue.release(); if (projectionTex != null) projectionTex.release(); if (projectionMatrix != null) projectionMatrix.release(); if (volStride != null) volStride.release(); if (projectionArray != null) projectionArray.release(); if (volumePointer != null) volumePointer.release(); kernelFunction.release(); program.release(); // destory context context.release(); commandQueue = null; projectionArray = null; projectionMatrix = null; projectionTex = null; volStride = null; volumePointer = null; kernelFunction = null; program = null; context = null; initialized = false; } }
public void OpenCLRun(double[] motionfield) { try { while (projectionsAvailable.size() > 0) { Thread.sleep(CONRAD.INVERSE_SPEEDUP); if (showStatus) { float status = (float) (1.0 / projections.size()); if (largeVolumeMode) { IJ.showStatus("Streaming Projections to OpenCL Buffer"); } else { IJ.showStatus("Backprojecting with OpenCL"); } IJ.showProgress(status); } if (!largeVolumeMode) { workOnProjectionData(motionfield); } else { checkProjectionData(); } } // System.out.println("large Volume " + largeVolumeMode); if (largeVolumeMode) { // we have collected all projections. // now we can reconstruct subvolumes and stich them together. int reconDimensionZ = getGeometry().getReconDimensionZ(); double voxelSpacingX = getGeometry().getVoxelSpacingX(); double voxelSpacingY = getGeometry().getVoxelSpacingY(); double voxelSpacingZ = getGeometry().getVoxelSpacingZ(); useVOImap = false; initialize(projections.get(0)); double originalOffsetZ = offsetZ; double originalReconDimZ = reconDimensionZ; reconDimensionZ = subVolumeZ; int maxProjectionNumber = projections.size(); float all = nSteps * maxProjectionNumber * 2; for (int n = 0; n < nSteps; n++) { // For each subvolume // set all to 0; Arrays.fill(h_volume, 0); volumePointer.getBuffer().rewind(); volumePointer.getBuffer().put(h_volume); volumePointer.getBuffer().rewind(); commandQueue.putWriteBuffer(volumePointer, true).finish(); offsetZ = originalOffsetZ - (reconDimensionZ * voxelSpacingZ * n); for (int p = 0; p < maxProjectionNumber; p++) { // For all projections float currentStep = (n * maxProjectionNumber * 2) + p; if (showStatus) { IJ.showStatus("Backprojecting with OpenCL"); IJ.showProgress(currentStep / all); } // System.out.println("Current: " + p); float respoffset = (float) Math.round(motionfield[p] / voxelSpacingZ); try { projectSingleProjection(p, reconDimensionZ, respoffset); } catch (Exception e) { System.out.println("Backprojection of projection " + p + " was not successful."); e.printStackTrace(); } } // Gather volume commandQueue.putReadBuffer(volumePointer, true).finish(); volumePointer.getBuffer().rewind(); volumePointer.getBuffer().get(h_volume); volumePointer.getBuffer().rewind(); // move data to ImagePlus; if (projectionVolume != null) { for (int k = 0; k < reconDimensionZ; k++) { int index = (n * subVolumeZ) + k; if (showStatus) { float currentStep = (n * maxProjectionNumber * 2) + maxProjectionNumber + k; IJ.showStatus("Fetching Volume from OpenCL"); IJ.showProgress(currentStep / all); } if (index < originalReconDimZ) { for (int j = 0; j < projectionVolume.getSize()[1]; j++) { for (int i = 0; i < projectionVolume.getSize()[0]; i++) { float value = h_volume[ (((projectionVolume.getSize()[1] * k) + j) * projectionVolume.getSize()[0]) + i]; double[][] voxel = new double[4][1]; voxel[0][0] = (voxelSpacingX * i) - offsetX; voxel[1][0] = (voxelSpacingY * j) - offsetY; voxel[2][0] = (voxelSpacingZ * index) - originalOffsetZ; // exception for the case "interestedInVolume == null" and largeVolume is // enabled if (interestedInVolume == null) { projectionVolume.setAtIndex(i, j, index, value); } else { if (interestedInVolume.contains(voxel[0][0], voxel[1][0], voxel[2][0])) { projectionVolume.setAtIndex(i, j, index, value); } else { projectionVolume.setAtIndex(i, j, index, 0); } } } } } } } } } } catch (InterruptedException e) { e.printStackTrace(); } if (showStatus) IJ.showProgress(1.0); unload(); if (debug) System.out.println("Unloaded"); }
public Grid2D openCLBackprojection( OpenCLGrid2D filteredSinogramm, int widthPhantom, int heightPhantom, int worksize, float detectorSpacing, int numberOfPixel, int numberProjections, float scanAngle, double[] spacing, double[] origin) { // create context CLContext context = OpenCLUtil.getStaticContext(); // select device CLDevice device = context.getMaxFlopsDevice(); // define local and global sizes double spacingAngle = (double) (scanAngle / numberProjections); double originDetector = -(detectorSpacing * numberOfPixel) / 2.0; int imageSize = widthPhantom * heightPhantom; int localWorkSize = Math.min(device.getMaxWorkGroupSize(), worksize); int globalWorkSizeW = OpenCLUtil.roundUp( localWorkSize, widthPhantom); // rounded up to the nearest multiple of localWorkSize int globalWorkSizeH = OpenCLUtil.roundUp(localWorkSize, heightPhantom); // load sources, create and build programm try { this.program = context.createProgram(this.getClass().getResourceAsStream("exercise4.cl")).build(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); System.exit(-1); } // create image from input grid // CLImageFormat format = new CLImageFormat(ChannelOrder.INTENSITY, ChannelType.FLOAT); // create output image CLBuffer<FloatBuffer> output = context.createFloatBuffer(imageSize, Mem.WRITE_ONLY); if (kernel == null) { kernel = program.createCLKernel("parallelBackProjection"); } // createCommandQueue CLCommandQueue queue = device.createCommandQueue(); filteredSinogramm.getDelegate().prepareForDeviceOperation(); // put memory on the graphics card kernel .putArg(filteredSinogramm.getDelegate().getCLBuffer()) .putArg(output) .putArg(numberProjections) .putArg(numberOfPixel) .putArg(scanAngle) .putArg(widthPhantom) .putArg(heightPhantom) .putArg(spacing[0]) .putArg(spacing[1]) .putArg(origin[0]) .putArg(origin[1]) .putArg(detectorSpacing) .putArg(spacingAngle) .putArg(originDetector) .putArg(0.d); kernel.rewind(); queue .put2DRangeKernel( kernel, 0, 0, globalWorkSizeW, globalWorkSizeH, localWorkSize, localWorkSize) .putBarrier() .finish(); // put memory from graphic card to host queue.putReadBuffer(output, true).finish(); output.getBuffer().rewind(); for (int i = 0; i < image.getSize()[1]; ++i) { for (int j = 0; j < image.getSize()[0]; j++) { image.setAtIndex(j, i, output.getBuffer().get()); } } output.release(); queue.release(); return image; }