[Openmp-commits] [openmp] r251654 - [OMPT] Windows Support for OMPT

Jonathan Peyton via Openmp-commits openmp-commits at lists.llvm.org
Thu Oct 29 13:56:24 PDT 2015


Author: jlpeyton
Date: Thu Oct 29 15:56:24 2015
New Revision: 251654

URL: http://llvm.org/viewvc/llvm-project?rev=251654&view=rev
Log:
[OMPT] Windows Support for OMPT

The problem is that the ompt_tool() function (which must be implemented by a
performance tool) should be defined in the RTL as well to cover the case when
the tool is not present in the address space of the process. This functionality
is accomplished with weak symbols in Unices. Unfortunately, Windows does not
support weak symbols.

The solution in these changes is to grab the list of all modules loaded by the
process and then search for symbol "ompt_tool()" within them. The function
ompt_tool_windows() performs the search of the ompt_tool symbol. If ompt_tool is
found, then its return value is used to initialize the tool. If ompt_tool is not
found, then ompt_tool_windows() returns NULL and OMPT is thus, disabled.

While doing these changes, the OMPT_SUPPORT detection in CMake was changed to
test for the required featuers for OMPT_SUPPORT, namely: builtin_frame_address()
existence, weak attribute existence and psapi.dll existence. For
LIBOMP_HAVE_OMPT_SUPPORT to be true, it must be that the builtin_frame_address()
intrinsic exists AND one of: either weak attributes exist or psapi.dll exists.

Also, since Process Status API is used I had to add new dependency -- psapi.dll
to the library dependency micro test.

Differential Revision: http://reviews.llvm.org/D14027

Modified:
    openmp/trunk/runtime/CMakeLists.txt
    openmp/trunk/runtime/cmake/LibompMicroTests.cmake
    openmp/trunk/runtime/cmake/config-ix.cmake
    openmp/trunk/runtime/src/kmp_config.h.cmake
    openmp/trunk/runtime/src/ompt-general.c
    openmp/trunk/runtime/src/ompt-specific.c
    openmp/trunk/runtime/src/ompt-specific.h

Modified: openmp/trunk/runtime/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/CMakeLists.txt?rev=251654&r1=251653&r2=251654&view=diff
==============================================================================
--- openmp/trunk/runtime/CMakeLists.txt (original)
+++ openmp/trunk/runtime/CMakeLists.txt Thu Oct 29 15:56:24 2015
@@ -273,7 +273,6 @@ if(LIBOMP_STATS)
 endif()
 
 # OMPT-support
-# TODO: Make this a real feature check
 set(LIBOMP_OMPT_SUPPORT FALSE CACHE BOOL
   "OMPT-support?")
 set(LIBOMP_OMPT_BLAME TRUE CACHE BOOL

Modified: openmp/trunk/runtime/cmake/LibompMicroTests.cmake
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/cmake/LibompMicroTests.cmake?rev=251654&r1=251653&r2=251654&view=diff
==============================================================================
--- openmp/trunk/runtime/cmake/LibompMicroTests.cmake (original)
+++ openmp/trunk/runtime/cmake/LibompMicroTests.cmake Thu Oct 29 15:56:24 2015
@@ -175,6 +175,7 @@ elseif(APPLE)
   set(libomp_expected_library_deps /usr/lib/libSystem.B.dylib)
 elseif(WIN32)
   set(libomp_expected_library_deps kernel32.dll)
+  libomp_append(libomp_expected_library_deps psapi.dll LIBOMP_OMPT_SUPPORT)
 else()
   if(${MIC})
     set(libomp_expected_library_deps libc.so.6 libpthread.so.0 libdl.so.2)

Modified: openmp/trunk/runtime/cmake/config-ix.cmake
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/cmake/config-ix.cmake?rev=251654&r1=251653&r2=251654&view=diff
==============================================================================
--- openmp/trunk/runtime/cmake/config-ix.cmake (original)
+++ openmp/trunk/runtime/cmake/config-ix.cmake Thu Oct 29 15:56:24 2015
@@ -13,6 +13,7 @@ include(CheckCCompilerFlag)
 include(CheckCSourceCompiles)
 include(CheckCXXCompilerFlag)
 include(CheckLibraryExists)
+include(CheckIncludeFiles)
 include(LibompCheckLinkerFlag)
 include(LibompCheckFortranFlag)
 
@@ -187,8 +188,26 @@ else()
 endif()
 
 # Check if OMPT support is available
-if(NOT WIN32)
-  set(LIBOMP_HAVE_OMPT_SUPPORT TRUE)
-else()
+# Currently, __builtin_frame_address() is required for OMPT
+# Weak attribute is required for Unices, LIBPSAPI is used for Windows
+check_c_source_compiles("int main(int argc, char** argv) {
+  void* p = __builtin_frame_address(0);
+  return 0;}" LIBOMP_HAVE___BUILTIN_FRAME_ADDRESS)
+check_c_source_compiles("__attribute__ ((weak)) int foo(int a) { return a*a; }
+  int main(int argc, char** argv) {
+  return foo(argc);}" LIBOMP_HAVE_WEAK_ATTRIBUTE)
+check_include_files("windows.h;psapi.h" LIBOMP_HAVE_PSAPI_H)
+check_library_exists(psapi EnumProcessModules "" LIBOMP_HAVE_LIBPSAPI)
+if(LIBOMP_HAVE_PSAPI_H AND LIBOMP_HAVE_LIBPSAPI)
+  set(LIBOMP_HAVE_PSAPI TRUE)
+endif()
+if(NOT LIBOMP_HAVE___BUILTIN_FRAME_ADDRESS)
   set(LIBOMP_HAVE_OMPT_SUPPORT FALSE)
+else()
+  if(LIBOMP_HAVE_WEAK_ATTRIBUTE OR LIBOMP_HAVE_PSAPI)
+    set(LIBOMP_HAVE_OMPT_SUPPORT TRUE)
+  else()
+    set(LIBOMP_HAVE_OMPT_SUPPORT FALSE)
+  endif()
 endif()
+

Modified: openmp/trunk/runtime/src/kmp_config.h.cmake
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/src/kmp_config.h.cmake?rev=251654&r1=251653&r2=251654&view=diff
==============================================================================
--- openmp/trunk/runtime/src/kmp_config.h.cmake (original)
+++ openmp/trunk/runtime/src/kmp_config.h.cmake Thu Oct 29 15:56:24 2015
@@ -27,6 +27,10 @@
 #if LIBOMP_USE_VERSION_SYMBOLS
 # define KMP_USE_VERSION_SYMBOLS
 #endif
+#cmakedefine01 LIBOMP_HAVE_WEAK_ATTRIBUTE
+#define KMP_HAVE_WEAK_ATTRIBUTE LIBOMP_HAVE_WEAK_ATTRIBUTE
+#cmakedefine01 LIBOMP_HAVE_PSAPI
+#define KMP_HAVE_PSAPI LIBOMP_HAVE_PSAPI
 #cmakedefine01 LIBOMP_STATS
 #define KMP_STATS_ENABLED LIBOMP_STATS
 #cmakedefine01 LIBOMP_USE_DEBUGGER

Modified: openmp/trunk/runtime/src/ompt-general.c
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/src/ompt-general.c?rev=251654&r1=251653&r2=251654&view=diff
==============================================================================
--- openmp/trunk/runtime/src/ompt-general.c (original)
+++ openmp/trunk/runtime/src/ompt-general.c Thu Oct 29 15:56:24 2015
@@ -15,7 +15,6 @@
  * ompt include files
  ****************************************************************************/
 
-#include "kmp_config.h"
 #include "ompt-internal.h"
 #include "ompt-specific.c"
 
@@ -32,6 +31,9 @@
 
 #define OMPT_API_ROUTINE static
 
+#ifndef OMPT_STR_MATCH
+#define OMPT_STR_MATCH(haystack, needle) (!strcasecmp(haystack, needle))
+#endif
 
 
 /*****************************************************************************
@@ -87,17 +89,93 @@ static ompt_interface_fn_t ompt_fn_looku
 OMPT_API_ROUTINE ompt_thread_id_t ompt_get_thread_id(void);
 
 
-
 /*****************************************************************************
  * initialization and finalization (private operations)
  ****************************************************************************/
 
-_OMP_EXTERN __attribute__ (( weak ))
+/* On Unix-like systems that support weak symbols the following implementation
+ * of ompt_tool() will be used in case no tool-supplied implementation of
+ * this function is present in the address space of a process.
+ *
+ * On Windows, the ompt_tool_windows function is used to find the
+ * ompt_tool symbol across all modules loaded by a process. If ompt_tool is
+ * found, ompt_tool's return value is used to initialize the tool. Otherwise,
+ * NULL is returned and OMPT won't be enabled */
+#if OMPT_HAVE_WEAK_ATTRIBUTE
+_OMP_EXTERN 
+__attribute__ (( weak ))
 ompt_initialize_t ompt_tool()
 {
+#if OMPT_DEBUG
+    printf("ompt_tool() is called from the RTL\n");
+#endif
     return NULL;
 }
 
+#elif OMPT_HAVE_PSAPI
+
+#include <psapi.h>
+#pragma comment(lib, "psapi.lib")
+#define ompt_tool ompt_tool_windows
+
+// The number of loaded modules to start enumeration with EnumProcessModules()
+#define NUM_MODULES 128
+
+static
+ompt_initialize_t ompt_tool_windows()
+{
+    int i;
+    DWORD needed, new_size;
+    HMODULE *modules;
+    HANDLE  process = GetCurrentProcess();
+    modules = (HMODULE*)malloc( NUM_MODULES * sizeof(HMODULE) );
+    ompt_initialize_t (*ompt_tool_p)() = NULL;
+
+#if OMPT_DEBUG
+    printf("ompt_tool_windows(): looking for ompt_tool\n");
+#endif
+    if( !EnumProcessModules( process, modules, NUM_MODULES * sizeof(HMODULE),
+                             &needed ) ) {
+        // Regardless of the error reason use the stub initialization function
+        return NULL;
+    }
+    // Check if NUM_MODULES is enough to list all modules
+    new_size = needed / sizeof(HMODULE);
+    if( new_size > NUM_MODULES ) {
+#if OMPT_DEBUG
+    printf("ompt_tool_windows(): resize buffer to %d bytes\n", needed);
+#endif
+        modules = (HMODULE*)realloc( modules, needed );
+        // If resizing failed use the stub function.
+        if( !EnumProcessModules( process, modules, needed, &needed ) ) {
+            return NULL;
+        }
+    }
+    for( i = 0; i < new_size; ++i ) {
+        (FARPROC &)ompt_tool_p = GetProcAddress(modules[i], "ompt_tool");
+        if( ompt_tool_p ) {
+#if OMPT_DEBUG
+            TCHAR modName[MAX_PATH];
+            if( GetModuleFileName(modules[i], modName, MAX_PATH))
+                printf("ompt_tool_windows(): ompt_tool found in module %s\n",
+                       modName);
+#endif
+            return ompt_tool_p();
+        }
+#if OMPT_DEBUG
+        else {
+            TCHAR modName[MAX_PATH];
+            if( GetModuleFileName(modules[i], modName, MAX_PATH) )
+                printf("ompt_tool_windows(): ompt_tool not found in module %s\n",
+                       modName);
+        }
+#endif
+    }
+    return NULL;
+}
+#else
+# error Either __attribute__((weak)) or psapi.dll are required for OMPT support
+#endif // OMPT_HAVE_WEAK_ATTRIBUTE
 
 void ompt_pre_init()
 {
@@ -118,11 +196,14 @@ void ompt_pre_init()
 
     if (!ompt_env_var  || !strcmp(ompt_env_var, ""))
         tool_setting = omp_tool_unset;
-    else if (!strcasecmp(ompt_env_var, "disabled"))
+    else if (OMPT_STR_MATCH(ompt_env_var, "disabled"))
         tool_setting = omp_tool_disabled;
-    else if (!strcasecmp(ompt_env_var, "enabled"))
+    else if (OMPT_STR_MATCH(ompt_env_var, "enabled"))
         tool_setting = omp_tool_enabled;
 
+#if OMPT_DEBUG
+    printf("ompt_pre_init(): tool_setting = %d\n", tool_setting);
+#endif
     switch(tool_setting) {
     case omp_tool_disabled:
         break;
@@ -142,7 +223,9 @@ void ompt_pre_init()
             "\"enabled\").\n", ompt_env_var);
         break;
     }
-
+#if OMPT_DEBUG
+    printf("ompt_pre_init():ompt_enabled = %d\n", ompt_enabled);
+#endif
 }
 
 

Modified: openmp/trunk/runtime/src/ompt-specific.c
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/src/ompt-specific.c?rev=251654&r1=251653&r2=251654&view=diff
==============================================================================
--- openmp/trunk/runtime/src/ompt-specific.c (original)
+++ openmp/trunk/runtime/src/ompt-specific.c Thu Oct 29 15:56:24 2015
@@ -29,7 +29,7 @@
 #define NEXT_ID(id_ptr,tid) \
   ((KMP_TEST_THEN_INC64(id_ptr) << OMPT_THREAD_ID_BITS) | (tid))
 #else
-#define NEXT_ID(id_ptr,tid) (KMP_TEST_THEN_INC64(id_ptr))
+#define NEXT_ID(id_ptr,tid) (KMP_TEST_THEN_INC64((volatile kmp_int64 *)id_ptr))
 #endif
 
 //******************************************************************************

Modified: openmp/trunk/runtime/src/ompt-specific.h
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/src/ompt-specific.h?rev=251654&r1=251653&r2=251654&view=diff
==============================================================================
--- openmp/trunk/runtime/src/ompt-specific.h (original)
+++ openmp/trunk/runtime/src/ompt-specific.h Thu Oct 29 15:56:24 2015
@@ -34,6 +34,14 @@ ompt_task_id_t __ompt_get_task_id_intern
 ompt_frame_t *__ompt_get_task_frame_internal(int depth);
 
 
+/*****************************************************************************
+ * macros
+ ****************************************************************************/
+#define OMPT_DEBUG KMP_DEBUG
+#define OMPT_HAVE_WEAK_ATTRIBUTE KMP_HAVE_WEAK_ATTRIBUTE
+#define OMPT_HAVE_PSAPI KMP_HAVE_PSAPI
+#define OMPT_STR_MATCH(haystack, needle) __kmp_str_match(haystack, 0, needle)
+
 
 //******************************************************************************
 // inline functions




More information about the Openmp-commits mailing list