001/** 002 * Copyright (c) 2011, The University of Southampton and the individual contributors. 003 * All rights reserved. 004 * 005 * Redistribution and use in source and binary forms, with or without modification, 006 * are permitted provided that the following conditions are met: 007 * 008 * * Redistributions of source code must retain the above copyright notice, 009 * this list of conditions and the following disclaimer. 010 * 011 * * Redistributions in binary form must reproduce the above copyright notice, 012 * this list of conditions and the following disclaimer in the documentation 013 * and/or other materials provided with the distribution. 014 * 015 * * Neither the name of the University of Southampton nor the names of its 016 * contributors may be used to endorse or promote products derived from this 017 * software without specific prior written permission. 018 * 019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 020 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 022 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 023 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 026 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 029 */ 030package org.openimaj.docs.tutorial.adv.advanced.parallel; 031 032import java.io.IOException; 033import java.util.ArrayList; 034import java.util.Iterator; 035import java.util.List; 036 037import org.openimaj.data.dataset.GroupedDataset; 038import org.openimaj.data.dataset.ListDataset; 039import org.openimaj.data.dataset.VFSGroupDataset; 040import org.openimaj.experiment.dataset.sampling.GroupSampler; 041import org.openimaj.image.DisplayUtilities; 042import org.openimaj.image.ImageUtilities; 043import org.openimaj.image.MBFImage; 044import org.openimaj.image.annotation.evaluation.datasets.Caltech101; 045import org.openimaj.image.colour.ColourSpace; 046import org.openimaj.image.colour.RGBColour; 047import org.openimaj.image.processing.resize.ResizeProcessor; 048import org.openimaj.time.Timer; 049import org.openimaj.util.function.Operation; 050import org.openimaj.util.parallel.Parallel; 051import org.openimaj.util.parallel.partition.RangePartitioner; 052 053/** 054 * OpenIMAJ Hello world! 055 * 056 */ 057public class App { 058 /** 059 * Main method 060 * 061 * @param args 062 * @throws IOException 063 */ 064 public static void main(String[] args) throws IOException { 065 // demonstrate for loop 066 Parallel.forIndex(0, 10, 1, new Operation<Integer>() { 067 @Override 068 public void perform(Integer i) { 069 System.out.println(i); 070 } 071 }); 072 073 // create dataset 074 final VFSGroupDataset<MBFImage> allImages = Caltech101.getImages(ImageUtilities.MBFIMAGE_READER); 075 final GroupedDataset<String, ListDataset<MBFImage>, MBFImage> images = GroupSampler.sample( 076 allImages, 8, false); 077 078 // The non-parallel version 079 final List<MBFImage> output = new ArrayList<MBFImage>(); 080 final ResizeProcessor resize = new ResizeProcessor(200); 081 final Timer t1 = Timer.timer(); 082 for (final ListDataset<MBFImage> clzImages : images.values()) { 083 final MBFImage current = new MBFImage(200, 200, ColourSpace.RGB); 084 085 for (final MBFImage i : clzImages) { 086 final MBFImage tmp = new MBFImage(200, 200, ColourSpace.RGB); 087 tmp.fill(RGBColour.WHITE); 088 089 final MBFImage small = i.process(resize).normalise(); 090 final int x = (200 - small.getWidth()) / 2; 091 final int y = (200 - small.getHeight()) / 2; 092 tmp.drawImage(small, x, y); 093 094 current.addInplace(tmp); 095 } 096 current.divideInplace((float) clzImages.size()); 097 output.add(current); 098 } 099 System.out.println("time " + t1.duration() + "ms"); 100 101 // first attempt at a parallel version 102 output.clear(); 103 final Timer t2 = Timer.timer(); 104 for (final ListDataset<MBFImage> clzImages : images.values()) { 105 final MBFImage current = new MBFImage(200, 200, ColourSpace.RGB); 106 107 Parallel.forEach(clzImages, new Operation<MBFImage>() { 108 @Override 109 public void perform(MBFImage i) { 110 final MBFImage tmp = new MBFImage(200, 200, ColourSpace.RGB); 111 tmp.fill(RGBColour.WHITE); 112 113 final MBFImage small = i.process(resize).normalise(); 114 final int x = (200 - small.getWidth()) / 2; 115 final int y = (200 - small.getHeight()) / 2; 116 tmp.drawImage(small, x, y); 117 118 synchronized (current) { 119 current.addInplace(tmp); 120 } 121 } 122 }); 123 current.divideInplace((float) clzImages.size()); 124 output.add(current); 125 } 126 System.out.println("time " + t2.duration() + "ms"); 127 128 // better parallel version 129 output.clear(); 130 final Timer t3 = Timer.timer(); 131 for (final ListDataset<MBFImage> clzImages : images.values()) { 132 final MBFImage current = new MBFImage(200, 200, ColourSpace.RGB); 133 134 Parallel.forEachPartitioned(new RangePartitioner<MBFImage>(clzImages), 135 new Operation<Iterator<MBFImage>>() { 136 @Override 137 public void perform(Iterator<MBFImage> im) { 138 final MBFImage tmpAccum = new MBFImage(200, 200, 3); 139 final MBFImage tmp = new MBFImage(200, 200, ColourSpace.RGB); 140 while (im.hasNext()) { 141 final MBFImage i = im.next(); 142 tmp.fill(RGBColour.WHITE); 143 144 final MBFImage small = i.process(resize).normalise(); 145 final int x = (200 - small.getWidth()) / 2; 146 final int y = (200 - small.getHeight()) / 2; 147 tmp.drawImage(small, x, y); 148 tmpAccum.addInplace(tmp); 149 } 150 synchronized (current) { 151 current.addInplace(tmpAccum); 152 } 153 } 154 }); 155 current.divideInplace((float) clzImages.size()); 156 output.add(current); 157 } 158 System.out.println("time " + t3.duration() + "ms"); 159 160 DisplayUtilities.display("Images", output); 161 } 162}