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}