commit cd663edf130f2edab7170fa0f2ab29d0be0cec94
parent 4969f5005a914bba9f19e820063ea64147028259
Author: Fabian Wermelinger <fabianw@mavt.ethz.ch>
Date: Thu, 28 Apr 2016 16:43:14 +0200
implemented polaroidCameraMPI application
Diffstat:
9 files changed, 187 insertions(+), 152 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,6 +1,6 @@
include ./Makefile.config
-CC = g++
+CC = mpic++
HDR = $(wildcard src/*.h)
SRC = $(wildcard src/*.cpp)
@@ -15,27 +15,19 @@ APPPOBJ = ${APPSRC:.cpp=.o}
polaroidCamera: third_party Polaroid $(APPOBJ)
- $(CC) $(CPPFLAGS) $(INC) -o bin/polaroidCamera $(APPSRC) $(LIB) -lpng -lPolaroid
+ $(CC) $(CPPFLAGS) $(INC) -o bin/polaroidCamera $(APPSRC) -lPolaroid $(LIB) -lpng -lz
Polaroid: third_party $(HDR) $(OBJ)
ar rcs lib/libPolaroid.a $(OBJ)
+ ranlib lib/libPolaroid.a
third_party: FORCE
$(MAKE) -C third_party all
FORCE:
-# schlierenCamera: all schlierenCamera.cpp
-# $(CC) $(CPPFLAGS) $(INC) -o schlierenCamera schlierenCamera.cpp $(OBJ) $(LIB) -lz -lpng -lhdf5 -lWaveletCompressor
-
-# hsvCamera: all hsvCamera.cpp
-# $(CC) $(CPPFLAGS) $(INC) -o hsvCamera hsvCamera.cpp $(OBJ) $(LIB) -lz -lpng -lhdf5 -lWaveletCompressor
-
-# test: all
-# (cd test; make all)
-
%.o: %.cpp
- g++ $(CPPFLAGS) $(INC) -c $< -o $@
+ $(CC) $(CPPFLAGS) $(INC) -c $< -o $@
clean:
find . -iname "*~" -exec rm -f {} \;
diff --git a/Makefile.config b/Makefile.config
@@ -1,7 +1,7 @@
config ?= release
bs ?= 16
align ?= 16
-omp ?= 1
+omp ?= 0
hdf ?= 1
cubismz ?= 1
prec ?= float
@@ -41,5 +41,4 @@ else
CPPFLAGS += -O3 -DNDEBUG
endif
-LIB += -lm -lz -ldl
CPPFLAGS += -Wall -Wextra -Wno-deprecated -D_ALIGNBYTES_=$(align) -D_BLOCKSIZE_=$(bs)
diff --git a/apps/OrganizerMPI.cpp b/apps/OrganizerMPI.cpp
@@ -0,0 +1,64 @@
+// File : OrganizerMPI.cpp
+// Date : Thu Apr 28 10:59:03 2016
+// Author : Fabian Wermelinger
+// Description: MPI Organizer Implementation
+// Copyright 2016 ETH Zurich. All Rights Reserved.
+#include <string>
+#include <iostream>
+#include <cstdio>
+#include <cstdlib>
+#include "OrganizerMPI.h"
+
+using namespace std;
+
+OrganizerMPI::OrganizerMPI(const int argc, char ** const argv) : m_nscenes(0), m_scenes(nullptr), m_argc(1)
+{
+ m_isroot = (rank() == 0) ? true : false;
+
+ // get scenes
+ bool bfoundScenes = false;
+ for (int i=1; i < argc; ++i)
+ {
+ const string key(argv[i]);
+ if (key == "-scenes")
+ {
+ m_scenes = (argv + (i+1));
+ m_nscenes = argc - (i+1);
+ bfoundScenes = true;
+ break;
+ }
+ ++m_argc;
+ }
+ if (!bfoundScenes)
+ {
+ // Define input scenes (=input files) at the end of the argument list
+ // by using the option "-scenes". You can use globbing here if there
+ // are many scenes.
+ if (m_isroot)
+ {
+ cerr << "ERROR: No input scenes given. Abort..." << endl;
+ cerr << " : (Note: -scenes must be the last argument, followed by [list of] input files)" << endl;
+ }
+ abort();
+ }
+}
+
+vector<char*> OrganizerMPI::split_work() const
+{
+ const int myrank = rank();
+ const int nranks = size();
+ const int myshare = m_nscenes/nranks;
+ const int rem = m_nscenes - nranks * myshare;
+ vector<char*> myscenes(0);
+ if (m_nscenes <= nranks)
+ {
+ if (myrank < m_nscenes) myscenes.push_back(m_scenes[myrank]);
+ return myscenes;
+ }
+
+ for (int i=0; i < myshare; ++i) // try to distribute work equally
+ myscenes.push_back(m_scenes[i*nranks + myrank]);
+ if (myrank < rem)
+ myscenes.push_back(m_scenes[myshare*nranks + myrank]);
+ return myscenes;
+}
diff --git a/apps/OrganizerMPI.h b/apps/OrganizerMPI.h
@@ -0,0 +1,43 @@
+// File : OrganizerMPI.h
+// Date : Thu Apr 28 09:53:58 2016
+// Author : Fabian Wermelinger
+// Description: MPI Organizer
+// Copyright 2016 ETH Zurich. All Rights Reserved.
+#ifndef ORGANIZERMPI_H_8HFBYG90
+#define ORGANIZERMPI_H_8HFBYG90
+
+#include <vector>
+#include <mpi.h>
+
+class OrganizerMPI
+{
+private:
+ int m_nscenes;
+ char** m_scenes;
+ int m_argc;
+ bool m_isroot;
+
+public:
+ OrganizerMPI(const int argc, char ** const argv);
+
+ inline int size() const
+ {
+ int size;
+ MPI_Comm_size(MPI_COMM_WORLD, &size);
+ return size;
+ }
+
+ inline int rank() const
+ {
+ int rank;
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ return rank;
+ }
+
+ std::vector<char*> split_work() const;
+ inline int argc() const { return m_argc; }
+ inline bool isroot() const { return m_isroot; }
+ inline void wait() const { MPI_Barrier(MPI_COMM_WORLD); }
+};
+
+#endif /* ORGANIZERMPI_H_8HFBYG90 */
diff --git a/apps/OrganizerOMP.cpp b/apps/OrganizerOMP.cpp
@@ -1,60 +0,0 @@
-// File : OrganizerOMP.cpp
-// Date : Thu Apr 28 10:59:03 2016
-// Author : Fabian Wermelinger
-// Description: OpenMP Organizer Implementation
-// Copyright 2016 ETH Zurich. All Rights Reserved.
-#include <string>
-#include <iostream>
-#include <cstdio>
-#include <cstdlib>
-#include "OrganizerOMP.h"
-
-using namespace std;
-
-OrganizerOMP::OrganizerOMP(const int argc, char ** const argv) : m_nscenes(0), m_scenes(nullptr), m_argc(1)
-{
- // get scenes
- bool bfoundScenes = false;
- for (int i=1; i < argc; ++i)
- {
- const string key(argv[i]);
- if (key == "-scenes")
- {
- m_scenes = (argv + (i+1));
- m_nscenes = argc - (i+1);
- bfoundScenes = true;
- break;
- }
- ++m_argc;
- }
- if (!bfoundScenes)
- {
- // Define input scenes (=input files) at the end of the argument list
- // by using the option "-scenes". You can use globbing here if there
- // are many scenes.
- cerr << "ERROR: No input scenes given. Abort..." << endl;
- cerr << " : (Note: -scenes must be the last argument, followed by [list of] input files)" << endl;
- abort();
- }
-}
-
-vector<char*> OrganizerOMP::split_work() const
-{
- const int myID = tid();
- const int nthreads = size();
- const int myshare = m_nscenes/nthreads;
- const int rem = m_nscenes - nthreads * myshare;
- vector<char*> myscenes;
-
- for (int i=0; i < myshare; ++i) // try to distribute work equally
- myscenes.push_back(m_scenes[i*nthreads + myID]);
-
- if (myID < rem)
- myscenes.push_back(m_scenes[myshare*nthreads + myID]);
-
-#pragma omp critical
- {
- printf("[Thread %d/%d: Load = %d scene(s), start @ %s]\n", myID, nthreads, myscenes.size(), myscenes.front());
- }
- return myscenes;
-}
diff --git a/apps/OrganizerOMP.h b/apps/OrganizerOMP.h
@@ -1,63 +0,0 @@
-// File : OrganizerOMP.h
-// Date : Thu Apr 28 09:53:58 2016
-// Author : Fabian Wermelinger
-// Description: OpenMP Organizer
-// Copyright 2016 ETH Zurich. All Rights Reserved.
-#ifndef ORGANIZEROMP_H_8HFBYG90
-#define ORGANIZEROMP_H_8HFBYG90
-
-#include <vector>
-#ifdef _USE_OMP_
-#include <omp.h>
-#endif /* _USE_OMP_ */
-
-
-class OrganizerOMP
-{
-private:
- int m_nscenes;
- char** m_scenes;
- int m_argc;
-
-public:
- OrganizerOMP(const int argc, char ** const argv);
-
- static int max_size()
- {
-#ifdef _USE_OMP_
- return omp_get_max_threads();
-#else
- return 1;
-#endif /* _USE_OMP_ */
- }
-
- static void set_size(const int nthreads)
- {
-#ifdef _USE_OMP_
- return omp_set_num_threads(nthreads);
-#endif /* _USE_OMP_ */
- }
-
- inline int size() const
- {
-#ifdef _USE_OMP_
- return omp_get_num_threads();
-#else
- return 1;
-#endif /* _USE_OMP_ */
- }
-
- inline int tid() const
- {
-#ifdef _USE_OMP_
- return omp_get_thread_num();
-#else
- return 0;
-#endif /* _USE_OMP_ */
- }
-
- std::vector<char*> split_work() const;
- inline int argc() const { return m_argc; }
-};
-
-#endif /* ORGANIZEROMP_H_8HFBYG90 */
diff --git a/apps/polaroidCamera/polaroidCameraMPI.cpp b/apps/polaroidCamera/polaroidCameraMPI.cpp
@@ -4,12 +4,11 @@
// Description: Polaroid Cam app
// Copyright 2016 ETH Zurich. All Rights Reserved.
#include <iostream>
+#include <cstdio>
+#include <string>
#include <vector>
-#ifdef _USE_OMP_
-#include <omp.h>
-#endif /* _USE_OMP_ */
-#include "OrganizerOMP.h"
+#include "OrganizerMPI.h"
#include "ArgumentParser.h"
#include "Polaroid.h"
#include "Cartridges.h"
@@ -19,22 +18,81 @@ using namespace std;
int main(int argc, char* argv[])
{
-#pragma omp parallel
- {
- OrganizerOMP threads(argc, argv);
+ MPI_Init(&argc, (char***)&argv);
+
+ OrganizerMPI worker(argc, argv);
+ ArgumentParser myparser(worker.argc(), (const char**)argv);
- ArgumentParser myparser(threads.argc(), (const char**)argv);
+ if (worker.isroot())
+ {
+ cout << "Command Line: ";
+ for (int i = 0; i < argc; ++i)
+ cout << argv[i] << " ";
+ cout << endl;
myparser.print_args();
+ }
+ worker.wait();
+
+
+ myparser.set_strict_mode();
+ const string input_type = myparser("-input").asString();
+ const string output_format = myparser("-format").asString();
+ myparser.unset_strict_mode();
+
+ Cartridge* mycartridge;
+ PhotoPaper* myphoto;
+ if (myparser("-format").asString("png") == "png")
+ {
+ mycartridge = new NormalizerCartridge(myparser);
+ if (myparser("-type").asString("hsv") == "hsv")
+ myphoto = new PNG_HSV;
+ else if (myparser("-type").asString("hsv") == "mono")
+ myphoto = new PNG_MONO;
+ }
+ else if (myparser("-format").asString("png") == "hdf5")
+ {
+ mycartridge = new TransmissionCartridge(myparser);
+ myphoto = new PhotoHDF5;
+ }
+
+ const double fraction = myparser("-fraction").asDouble(0.5);
+ const int direction = myparser("-direction").asInt(0);
+ const int channel = myparser("-channel").asInt(0);
+ const bool byte_swap = myparser("-swap").asBool(false);
+ const int wavelet_type = myparser("-wtype").asInt(1);
- vector<char*> myscenes = threads.split_work();
+ Polaroid mycam;
+ vector<char*> myscenes = worker.split_work();
+ if (myscenes.size() > 0)
+ printf("[Worker %d/%d: Load = %d scene(s), start @ %s]\n", worker.rank(), worker.size(), myscenes.size(), myscenes.front());
+ else
+ printf("[Worker %d/%d: Load = %d scene(s), start @ %s]\n", worker.rank(), worker.size(), myscenes.size(), "none");
+
+ size_t k = 0;
+ for (auto scene: myscenes)
+ {
+ string basename(scene);
+ if (basename.find_last_of(".") != string::npos)
+ basename = basename.substr(0, basename.find_last_of("."));
- Polaroid cam;
- NormalizerCartridge transmission(myparser);
- // PhotoHDF5 photo("hello");
- PNG_MONO photo("hello");
- cam.load_hdf5(myscenes[0], 0.5, 2, 0);
- cam.capture(transmission, photo);
+ if (input_type == "hdf5")
+ mycam.load_hdf5(scene, fraction, direction, channel);
+ else if (input_type == "wavelet")
+ mycam.load_wavelet(scene, fraction, direction, channel, byte_swap, wavelet_type);
+
+ myphoto->make_new(basename+"-polaroid", mycam.width(), mycam.height());
+ mycam.capture(*mycartridge, *myphoto);
+
+ ++k;
+ if (worker.isroot())
+ printf("[Progress %3.1f %%]\n", static_cast<double>(k)/myscenes.size()*100.0);
}
+ delete mycartridge;
+ delete myphoto;
+
+ worker.wait();
+ MPI_Finalize();
+
return 0;
}
diff --git a/third_party/Makefile b/third_party/Makefile
@@ -15,6 +15,7 @@ libCubismZ.a:
libpng.a: $(OBJLib2) $(OBJLib3)
ar rcs ../lib/libpng.a $(OBJLib2) $(OBJLib3)
+ ranlib ../lib/libpng.a
.c.o:
gcc -c $(CFLAGS) -o $@ $<
diff --git a/third_party/Makefile.cubismz b/third_party/Makefile.cubismz
@@ -5,6 +5,7 @@ OBJLib1 = ${CubismZ_SRC:.cpp=.o}
all: $(OBJLib1)
ar rcs ../lib/libCubismZ.a $(OBJLib1)
+ ranlib ../lib/libCubismZ.a
.cpp.o:
g++ -c $(CPPFLAGS) $(INC) -o $@ $<