From 77f1ec47bd4a5b4cdd0ceec9f75de378073cfed5 Mon Sep 17 00:00:00 2001
From: Julien Michel <julien.michel@orfeo-toolbox.org>
Date: Tue, 19 Oct 2010 10:34:22 +0200
Subject: [PATCH] ENH: Activating OpenMP support for libsvm if available

---
 Utilities/otbsvm/CMakeLists.txt | 31 +++++++++++++++++++++++++++++++
 Utilities/otbsvm/svm.cpp        |  2 ++
 2 files changed, 33 insertions(+)

diff --git a/Utilities/otbsvm/CMakeLists.txt b/Utilities/otbsvm/CMakeLists.txt
index 62591f3e9c..f7e9f44507 100644
--- a/Utilities/otbsvm/CMakeLists.txt
+++ b/Utilities/otbsvm/CMakeLists.txt
@@ -5,6 +5,7 @@
 #
 
 PROJECT(OTBSVM)
+include(CheckCXXCompilerFlag)
 
 # source files for otbsvm
 SET(OTBSVM_SRCS
@@ -17,6 +18,36 @@ IF(OTB_LIBRARY_PROPERTIES)
   SET_TARGET_PROPERTIES(otbsvm PROPERTIES ${OTB_LIBRARY_PROPERTIES})
 ENDIF(OTB_LIBRARY_PROPERTIES)
 
+# check for OpenMP
+if( NOT DEFINED USE_OPENMP OR USE_OPENMP  )
+
+  if( WIN32 )
+    CHECK_INCLUDE_FILE(omp.h HAVE_OMP_H)
+    if( HAVE_OMP_H )
+      check_cxx_compiler_flag(/openmp HAVE_OPENMP)
+
+      if( HAVE_OPENMP )
+        message(STATUS "compiling libsvm with openmp support")
+        add_definitions("/openmp")
+      endif()
+    endif()
+  elseif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
+
+    # check if compilers supports -fopenmp
+    INCLUDE(CheckCCompilerFlag)
+    check_cxx_compiler_flag(-fopenmp HAVE_OPENMP)
+    check_library_exists(gomp omp_get_num_threads "" HAS_GOMP_LIB)
+
+    if( HAVE_OPENMP AND HAS_GOMP_LIB )
+      message(STATUS "compiling libsvm with openmp support")
+      add_definitions("-fopenmp")
+      target_link_libraries(otbsvm gomp)
+      set(OPENMP_LFLAGS "-lgomp")
+    endif()
+  endif()
+endif()
+
+
 IF(NOT OTB_INSTALL_NO_LIBRARIES)
   INSTALL(TARGETS otbsvm
     RUNTIME DESTINATION ${OTB_INSTALL_BIN_DIR_CM24} COMPONENT RuntimeLibraries
diff --git a/Utilities/otbsvm/svm.cpp b/Utilities/otbsvm/svm.cpp
index 1a3a023db7..52d624fcf7 100644
--- a/Utilities/otbsvm/svm.cpp
+++ b/Utilities/otbsvm/svm.cpp
@@ -1320,6 +1320,7 @@ public:
 		int start, j;
 		if((start = cache->get_data(i,&data,len)) < len)
 		{
+# pragma omp parallel for private(j)
 			for(j=start;j<len;j++)
 	      /*** Begin OTB modification ***/
 				data[j] = (Qfloat)(y[i]*y[j]*(this->*kernel_function)(i,j,m_param));
@@ -2527,6 +2528,7 @@ double svm_predict_values(const svm_model *model, const svm_node *x, double* dec
 		int l = model->l;
 		
 		double *kvalue = Malloc(double,l);
+#pragma omp parallel for private(i)
 		for(i=0;i<l;i++)
 			kvalue[i] = Kernel::k_function(x,model->SV[i],model->param);
 
-- 
GitLab