From 80399a4086818d089d6e22521c9b4931442871ee Mon Sep 17 00:00:00 2001
From: Andreas Naumann <andreas.naumann@tu-dresden.de>
Date: Mon, 22 Nov 2010 15:08:27 +0000
Subject: [PATCH] first plugin approach for umfpack

---
 AMDiS/plugins/CMakeLists.txt       | 15 ++++++
 AMDiS/plugins/src/PluginProvider.h | 73 ++++++++++++++++++++++++++++++
 AMDiS/plugins/src/umfpack.cpp      |  9 ++++
 AMDiS/plugins/src/use.cpp          | 55 ++++++++++++++++++++++
 4 files changed, 152 insertions(+)
 create mode 100644 AMDiS/plugins/CMakeLists.txt
 create mode 100644 AMDiS/plugins/src/PluginProvider.h
 create mode 100644 AMDiS/plugins/src/umfpack.cpp
 create mode 100644 AMDiS/plugins/src/use.cpp

diff --git a/AMDiS/plugins/CMakeLists.txt b/AMDiS/plugins/CMakeLists.txt
new file mode 100644
index 00000000..e901c3b8
--- /dev/null
+++ b/AMDiS/plugins/CMakeLists.txt
@@ -0,0 +1,15 @@
+project(amdis-plugins)
+
+cmake_minimum_required(VERSION 2.8)
+include_directories(../src/ ../lib/mtl4/ ../lib/UMFPACK/Include ../lib/AMD/Include ../lib/UFconfig/ )
+link_directories(${CMAKE_CURRENT_SOURCE_DIR}/../ 
+		${CMAKE_CURRENT_SOURCE_DIR}/../lib/UMFPACK/Lib/
+		${CMAKE_CURRENT_SOURCE_DIR}/../lib/AMD/Lib/)
+add_library(amdis-umfpack SHARED src/umfpack.cpp)
+target_link_libraries(amdis-umfpack umfpack amd blas)
+
+
+add_executable(use src/use.cpp)
+target_link_libraries(use dl amdis boost_iostreams boost_system)
+#amdis was compiled with openmp -> needed openmp for the application also.
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp")
diff --git a/AMDiS/plugins/src/PluginProvider.h b/AMDiS/plugins/src/PluginProvider.h
new file mode 100644
index 00000000..9241d18f
--- /dev/null
+++ b/AMDiS/plugins/src/PluginProvider.h
@@ -0,0 +1,73 @@
+#ifndef PLUGINPROVER_H
+#define PLUGINPROVER_H
+
+#include "dlfcn.h"
+#include <string>
+
+using namespace std;
+
+namespace AMDiS {
+template< typename DesiredCreator >
+struct PluginProvider { 
+	typedef DesiredCreator* Creator();
+	typedef void Remover(DesiredCreator* );
+
+	string createName;
+	string removeName;
+
+	Remover* remover;
+
+	PluginProvider(string c, string r):
+		createName(c),
+		removeName(r),
+		remover(NULL)
+	{}
+
+	enum Error { NOLIBRARY, NOCREATOR, NOREMOVER };
+	struct Exception {
+		Error e;
+		string message;
+		Exception(Error e, string m):
+			e(e),message(m)
+		{}
+	};
+
+	DesiredCreator* create(string libname) {
+		void* library=dlopen(libname.c_str(), RTLD_LAZY);
+		if(library==NULL) {
+			throw Exception(NOLIBRARY, dlerror());
+		}
+
+		dlerror();
+
+		Creator* creator=(Creator*) (dlsym(library, createName.c_str()));
+		if(creator == NULL) {
+			throw Exception(NOCREATOR, dlerror());
+		}
+
+		remover=(Remover*) (dlsym(library, removeName.c_str()));
+		if(remover == NULL) {
+			throw Exception(NOREMOVER, dlerror());
+		}
+
+		DesiredCreator* creatingCreator=creator();
+		return creatingCreator;
+	}
+
+	void remove(DesiredCreator* dc) {
+		if(remover == NULL) {
+			throw Exception(NOREMOVER, "the remover was not set\n");
+		}
+		remover(dc);
+	}
+};
+
+//typedef OEMSolverCreator* createSolverCreator();
+//typedef void removeSolverCreator(OEMSolverCreator*);
+struct SolverPluginProvider : PluginProvider< OEMSolverCreator > {
+	SolverPluginProvider():
+		PluginProvider< OEMSolverCreator >("createSolverCreator","removeSolverCreator")
+	{}
+};
+}
+#endif
diff --git a/AMDiS/plugins/src/umfpack.cpp b/AMDiS/plugins/src/umfpack.cpp
new file mode 100644
index 00000000..790f5a96
--- /dev/null
+++ b/AMDiS/plugins/src/umfpack.cpp
@@ -0,0 +1,9 @@
+#define HAVE_UMFPACK
+#define MTL_HAS_UMFPACK
+#include "AMDiS.h"
+#include "UmfPackSolver.h"
+
+using namespace AMDiS;
+
+extern "C" OEMSolverCreator* createSolverCreator() { return new UmfPackSolver::Creator(); }
+extern "C" void removeSolverCreator(OEMSolverCreator* p) { delete p; }
diff --git a/AMDiS/plugins/src/use.cpp b/AMDiS/plugins/src/use.cpp
new file mode 100644
index 00000000..df56b585
--- /dev/null
+++ b/AMDiS/plugins/src/use.cpp
@@ -0,0 +1,55 @@
+#include "AMDiS.h"
+#include "dlfcn.h"
+#include "PluginProvider.h"
+#include <iostream>
+
+using namespace AMDiS;
+using namespace std;
+
+//typedef OEMSolverCreator* Creator();
+//typedef void Remover(OEMSolverCreator*);
+
+int main(int argc, char** argv) {
+/*	void* umfpackLib=dlopen("./libamdis-umfpack.so", RTLD_LAZY);
+	if (!umfpackLib) {
+	        cerr << "Cannot load library: " << dlerror() << '\n';
+        	return 1;
+	}
+	dlerror();
+
+	Creator* creator=(Creator*) (dlsym(umfpackLib, "createSolverCreator"));
+	if(creator == NULL) {
+		cerr << "could not load the create function in libumfpack.so \n";
+		return 2;
+	}
+
+	Remover* remover=(Remover* )(dlsym(umfpackLib, "removeSolverCreator"));
+	if( remover == NULL) {
+		cerr << "could not load the remove function in libumfpack.so \n";
+		return 3;
+	}
+
+	OEMSolverCreator* theCreator=creator();
+	*/
+	SolverPluginProvider spp;
+	OEMSolver* theSolver(NULL);
+	try {
+		OEMSolverCreator* theCreator=spp.create("./libamdis-umfpack.so");
+		theCreator->setName("umfpack");
+		theSolver=theCreator->create();
+//		remover(theCreator);
+		spp.remove(theCreator);
+	}catch(SolverPluginProvider::Exception e) {
+		std::cerr<< "could not load the umfpack solver: "<<e.message<<"\n";
+		return 1;
+	}
+	mtl::matrix::compressed2D< double > testMatrix(10,10);
+	mtl::matrix::diagonal_setup(testMatrix, 5.0);
+	mtl::vector::dense_vector< double > b(10);
+	b=4.0;
+	mtl::vector::dense_vector< double > x(10);
+	x=0.0;
+	theSolver->solveSystem(testMatrix,x,b);
+	delete theSolver;
+	return 0;
+}
-- 
GitLab