Compare commits
95
Commits
release_40
...
release_50
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
29b515e1e6 | ||
|
|
4ef23db17c | ||
|
|
37c72127e9 | ||
|
|
11cf126119 | ||
|
|
470366641d | ||
|
|
08f2b9ce14 | ||
|
|
67512bb555 | ||
|
|
6999fe680a | ||
|
|
1333cd34fa | ||
|
|
8072ba12e0 | ||
|
|
4efa4a63cf | ||
|
|
a07d8b0a66 | ||
|
|
92f7b797ee | ||
|
|
4c2424f72c | ||
|
|
dd87e37353 | ||
|
|
3b5852c6a1 | ||
|
|
b88a01f4ef | ||
|
|
53e0c92a88 | ||
|
|
4d238bda09 | ||
|
|
0a8f95d15f | ||
|
|
06426cf363 | ||
|
|
597a305494 | ||
|
|
3c37ab915c | ||
|
|
1c31fdada0 | ||
|
|
5e8afb8077 | ||
|
|
6943fc62c3 | ||
|
|
862483e622 | ||
|
|
8924d7386a | ||
|
|
a8b80af9fc | ||
|
|
4bdc9afa72 | ||
|
|
84e84f8bb4 | ||
|
|
2b5580f57b | ||
|
|
d2cb509fa4 | ||
|
|
20fe9e7270 | ||
|
|
fcec73a508 | ||
|
|
e60f480d75 | ||
|
|
50a02e790e | ||
|
|
e4c0f2b8d3 | ||
|
|
c2f4638c23 | ||
|
|
ac4f9700a7 | ||
|
|
e703e783e7 | ||
|
|
07c5582c3b | ||
|
|
1a189314bd | ||
|
|
81a7c91728 | ||
|
|
23f1ee8d87 | ||
|
|
079ec52a07 | ||
|
|
1eb73292d2 | ||
|
|
305e440c56 | ||
|
|
f07924fd3f | ||
|
|
ef71bbcce4 | ||
|
|
9a49cce023 | ||
|
|
fa50db79c4 | ||
|
|
b8b75f9476 | ||
|
|
c75321c16f | ||
|
|
e3e3d228fe | ||
|
|
ea09034b77 | ||
|
|
b78659393e | ||
|
|
3a5a5198c0 | ||
|
|
c5cb0abc91 | ||
|
|
1c2799754b | ||
|
|
c79f0d5955 | ||
|
|
e70eb2bba4 | ||
|
|
17fe17487c | ||
|
|
6168925936 | ||
|
|
d2a2afc3d4 | ||
|
|
96b04de80a | ||
|
|
b61de7c64a | ||
|
|
bff1acca47 | ||
|
|
d3acdf9c86 | ||
|
|
14e93081b9 | ||
|
|
fb0f861623 | ||
|
|
c80d301009 | ||
|
|
7bd7063524 | ||
|
|
b2806f6cc0 | ||
|
|
9c1e6c9bc1 | ||
|
|
0f00053d19 | ||
|
|
8f2e239462 | ||
|
|
c40fa62243 | ||
|
|
1aaa414753 | ||
|
|
4726583580 | ||
|
|
f26c30f014 | ||
|
|
cb9c397660 | ||
|
|
273c4bfef1 | ||
|
|
cf09abbf86 | ||
|
|
6009b4051a | ||
|
|
b00226fdf5 | ||
|
|
bd223d612d | ||
|
|
7ec028b27e | ||
|
|
78b78d175a | ||
|
|
c0cfee9024 | ||
|
|
1dc2e70de2 | ||
|
|
7680cbb63a | ||
|
|
3585ec7dbc | ||
|
|
fa45385094 | ||
|
|
0e5d1992ca |
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"project_id" : "openmp",
|
||||
"conduit_uri" : "https://reviews.llvm.org/"
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
#==============================================================================#
|
||||
# This file specifies intentionally untracked files that git should ignore.
|
||||
# See: http://www.kernel.org/pub/software/scm/git/docs/gitignore.html
|
||||
#
|
||||
# This file is intentionally different from the output of `git svn show-ignore`,
|
||||
# as most of those are useless.
|
||||
#==============================================================================#
|
||||
|
||||
#==============================================================================#
|
||||
# File extensions to be ignored anywhere in the tree.
|
||||
#==============================================================================#
|
||||
# Temp files created by most text editors.
|
||||
*~
|
||||
# Merge files created by git.
|
||||
*.orig
|
||||
# Byte compiled python modules.
|
||||
*.pyc
|
||||
# vim swap files
|
||||
.*.sw?
|
||||
.sw?
|
||||
#OS X specific files.
|
||||
.DS_store
|
||||
|
||||
#==============================================================================#
|
||||
# Explicit files to ignore (only matches one).
|
||||
#==============================================================================#
|
||||
# Various tag programs
|
||||
tags
|
||||
/TAGS
|
||||
/GPATH
|
||||
/GRTAGS
|
||||
/GSYMS
|
||||
/GTAGS
|
||||
.gitusers
|
||||
|
||||
#==============================================================================#
|
||||
# Directories to ignore (do not add trailing '/'s, they skip symlinks).
|
||||
#==============================================================================#
|
||||
runtime/exports
|
||||
|
||||
# Nested build directory
|
||||
/build
|
||||
@@ -3,3 +3,21 @@ cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
|
||||
set(OPENMP_LLVM_TOOLS_DIR "" CACHE PATH "Path to LLVM tools for testing")
|
||||
|
||||
add_subdirectory(runtime)
|
||||
|
||||
|
||||
# The tests currently don't pass if the generic ELF plugin is built.
|
||||
# TODO: Fix the tests and enable libomptarget by default on supported
|
||||
# architectures and platforms.
|
||||
set(ENABLE_LIBOMPTARGET OFF)
|
||||
# Currently libomptarget cannot be compiled on Windows or MacOS X.
|
||||
# Since the device plugins are only supported on Linux anyway,
|
||||
# there is no point in trying to compile libomptarget on other OSes.
|
||||
if (WIN32 OR ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
set(ENABLE_LIBOMPTARGET OFF)
|
||||
endif()
|
||||
|
||||
option(OPENMP_ENABLE_LIBOMPTARGET "Enable building libomptarget for offloading."
|
||||
${ENABLE_LIBOMPTARGET})
|
||||
if (OPENMP_ENABLE_LIBOMPTARGET)
|
||||
add_subdirectory(libomptarget)
|
||||
endif()
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
#
|
||||
#//===----------------------------------------------------------------------===//
|
||||
#//
|
||||
#// The LLVM Compiler Infrastructure
|
||||
#//
|
||||
#// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
#// Source Licenses. See LICENSE.txt for details.
|
||||
#//
|
||||
#//===----------------------------------------------------------------------===//
|
||||
#
|
||||
|
||||
=====================================================================
|
||||
How to Build the LLVM* OpenMP* Offloading Runtime Library using CMake
|
||||
=====================================================================
|
||||
|
||||
==== Version of CMake required: v2.8.0 or above ====
|
||||
|
||||
============================================
|
||||
How to call cmake initially, then repeatedly
|
||||
============================================
|
||||
- When calling cmake for the first time, all needed compiler options
|
||||
must be specified on the command line. After this initial call to
|
||||
cmake, the compiler definitions must not be included for further calls
|
||||
to cmake. Other options can be specified on the command line multiple
|
||||
times including all definitions in the Build options section below.
|
||||
- Example of configuring, building, reconfiguring, rebuilding:
|
||||
$ mkdir build
|
||||
$ cd build
|
||||
$ cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ .. # Initial configuration
|
||||
$ make
|
||||
...
|
||||
$ make clean
|
||||
$ cmake -DCMAKE_BUILD_TYPE=Debug .. # Second configuration
|
||||
$ make
|
||||
...
|
||||
$ rm -rf *
|
||||
$ cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ .. # Third configuration
|
||||
$ make
|
||||
- Notice in the example how the compiler definitions are only specified
|
||||
for an empty build directory, but other Build options are used at any time.
|
||||
- The file CMakeCache.txt which is created after the first call to cmake
|
||||
is a configuration file which holds all the values for the Build options.
|
||||
These configuration values can be changed using a text editor to modify
|
||||
CMakeCache.txt as opposed to using definitions on the command line.
|
||||
- To have cmake create a particular type of build generator file simply
|
||||
inlude the -G <Generator name> option:
|
||||
$ cmake -G "Unix Makefiles" ...
|
||||
You can see a list of generators cmake supports by executing cmake with
|
||||
no arguments and a list will be printed.
|
||||
|
||||
=====================
|
||||
Instructions to Build
|
||||
=====================
|
||||
$ cd libomptarget_top_level/ [ directory with plugins/ , deviceRTLs/ , etc. ]
|
||||
$ mkdir build
|
||||
$ cd build
|
||||
|
||||
[ Unix* Libraries ]
|
||||
$ cmake -DCMAKE_C_COMPILER=<C Compiler> -DCMAKE_CXX_COMPILER=<C++ Compiler> ..
|
||||
|
||||
$ make
|
||||
$ make install
|
||||
|
||||
===========
|
||||
Tests
|
||||
===========
|
||||
After the library has been built, there are optional tests that can be
|
||||
performed. Some will be skipped based upon the platform.
|
||||
To run the tests,
|
||||
$ make check-libomptarget
|
||||
|
||||
=============
|
||||
CMake options
|
||||
=============
|
||||
-DCMAKE_C_COMPILER=<C compiler name>
|
||||
Specify the C compiler
|
||||
|
||||
-DCMAKE_CXX_COMPILER=<C++ compiler name>
|
||||
Specify the C++ compiler
|
||||
|
||||
==== First values listed are the default value ====
|
||||
-DCMAKE_BUILD_TYPE=Release|Debug|RelWithDebInfo
|
||||
Build type can be Release, Debug, or RelWithDebInfo.
|
||||
|
||||
-DLIBOMPTARGET_ENABLE_WERROR=true|false
|
||||
Should consider warnings as errors.
|
||||
|
||||
-DLIBOMPTARGET_LLVM_LIT_EXECUTABLE=""
|
||||
Full path to the llvm-lit tool. Required for testing in out-of-tree builds.
|
||||
|
||||
-DLIBOMPTARGET_FILECHECK_EXECUTABLE=""
|
||||
Full path to the FileCheck tool. Required for testing in out-of-tree builds.
|
||||
|
||||
-DLIBOMPTARGET_OPENMP_HEADER_FOLDER=""
|
||||
Path of the folder that contains omp.h. This is required for testing
|
||||
out-of-tree builds.
|
||||
|
||||
-DLIBOMPTARGET_OPENMP_HOST_RTL_FOLDER=""
|
||||
Path of the folder that contains libomp.so. This is required for testing
|
||||
out-of-tree builds.
|
||||
|
||||
==== NVPTX device RTL specific ====
|
||||
-DLIBOMPTARGET_NVPTX_ENABLE_BCLIB=false|true
|
||||
Enable CUDA LLVM bitcode offloading device RTL. This is used for
|
||||
link time optimization of the omp runtime and application code.
|
||||
|
||||
-DLIBOMPTARGET_NVPTX_CUDA_COMPILER=<CUDA compiler name>
|
||||
Location of a CUDA compiler capable of emitting LLVM bitcode.
|
||||
Currently only the Clang compiler is supported. This is only used
|
||||
when building the CUDA LLVM bitcode offloading device RTL. If
|
||||
unspecified, the default paths are inspected.
|
||||
|
||||
-DLIBOMPTARGET_NVPTX_BC_LINKER=<LLVM bitcode linker>
|
||||
Location of a linker capable of linking LLVM bitcode objects.
|
||||
This is only used when building the CUDA LLVM bitcode offloading
|
||||
device RTL. If unspecified, the default paths are inspected.
|
||||
|
||||
-DLIBOMPTARGET_NVPTX_ALTERNATE_HOST_COMPILER=""
|
||||
Host compiler to use with NVCC. This compiler is not going to be used to produce
|
||||
any binary. Instead, this is used to overcome the input compiler checks done by
|
||||
NVCC. E.g. if using a default host compiler that is not compatible with NVCC,
|
||||
this option can be use to pass to NVCC a valid compiler to avoid the error.
|
||||
|
||||
-DLIBOMPTARGET_NVPTX_COMPUTE_CAPABILITY="35"
|
||||
Comma-separated list of CUDA compute capabilities that should be supported by
|
||||
the NVPTX device RTL. E.g. for compute capabilities 3.0 and 3.5, the option
|
||||
"30,35" should be used.
|
||||
|
||||
=======================
|
||||
Example usages of CMake
|
||||
=======================
|
||||
---- Typical usage ----
|
||||
cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ ..
|
||||
cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ ..
|
||||
|
||||
---- Request an NVPTX runtime library that supports compute capability 5.0 ----
|
||||
cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DLIBOMPTARGET_NVPTX_COMPUTE_CAPABILITY="50"
|
||||
|
||||
=========
|
||||
Footnotes
|
||||
=========
|
||||
[*] Other names and brands may be claimed as the property of others.
|
||||
@@ -0,0 +1,119 @@
|
||||
##===----------------------------------------------------------------------===##
|
||||
#
|
||||
# The LLVM Compiler Infrastructure
|
||||
#
|
||||
# This file is dual licensed under the MIT and the University of Illinois Open
|
||||
# Source Licenses. See LICENSE.txt for details.
|
||||
#
|
||||
##===----------------------------------------------------------------------===##
|
||||
#
|
||||
# Build offloading library libomptarget.so.
|
||||
#
|
||||
##===----------------------------------------------------------------------===##
|
||||
|
||||
# CMAKE libomptarget
|
||||
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
|
||||
|
||||
# Add cmake directory to search for custom cmake functions.
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules ${CMAKE_MODULE_PATH})
|
||||
|
||||
# Standalone build or part of LLVM?
|
||||
set(LIBOMPTARGET_STANDALONE_BUILD FALSE)
|
||||
if("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}" OR
|
||||
"${CMAKE_SOURCE_DIR}/libomptarget" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
project(libomptarget C CXX)
|
||||
set(LIBOMPTARGET_STANDALONE_BUILD TRUE)
|
||||
endif()
|
||||
|
||||
|
||||
if(${LIBOMPTARGET_STANDALONE_BUILD})
|
||||
set(LIBOMPTARGET_ENABLE_WERROR FALSE CACHE BOOL
|
||||
"Enable -Werror flags to turn warnings into errors for supporting compilers.")
|
||||
# CMAKE_BUILD_TYPE was not defined, set default to Release
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
endif()
|
||||
set(LIBOMPTARGET_LIBDIR_SUFFIX "" CACHE STRING
|
||||
"suffix of lib installation directory, e.g. 64 => lib64")
|
||||
else()
|
||||
set(LIBOMPTARGET_ENABLE_WERROR ${LLVM_ENABLE_WERROR})
|
||||
# If building in tree, we honor the same install suffix LLVM uses.
|
||||
set(LIBOMPTARGET_LIBDIR_SUFFIX ${LLVM_LIBDIR_SUFFIX})
|
||||
endif()
|
||||
|
||||
# Compiler flag checks.
|
||||
include(config-ix)
|
||||
|
||||
# Message utilities.
|
||||
include(LibomptargetUtils)
|
||||
|
||||
# Get dependencies for the different components of the project.
|
||||
include(LibomptargetGetDependencies)
|
||||
|
||||
# This is a list of all the targets that are supported/tested right now.
|
||||
set (LIBOMPTARGET_ALL_TARGETS "${LIBOMPTARGET_ALL_TARGETS} aarch64-unknown-linux-gnu")
|
||||
set (LIBOMPTARGET_ALL_TARGETS "${LIBOMPTARGET_ALL_TARGETS} powerpc64le-ibm-linux-gnu")
|
||||
set (LIBOMPTARGET_ALL_TARGETS "${LIBOMPTARGET_ALL_TARGETS} powerpc64-ibm-linux-gnu")
|
||||
set (LIBOMPTARGET_ALL_TARGETS "${LIBOMPTARGET_ALL_TARGETS} x86_64-pc-linux-gnu")
|
||||
set (LIBOMPTARGET_ALL_TARGETS "${LIBOMPTARGET_ALL_TARGETS} nvptx64-nvidia-cuda")
|
||||
|
||||
# Once the plugins for the different targets are validated, they will be added to
|
||||
# the list of supported targets in the current system.
|
||||
set (LIBOMPTARGET_SYSTEM_TARGETS "")
|
||||
|
||||
# Set base directories - required for lit to locate the tests.
|
||||
set(LIBOMPTARGET_BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
set(LIBOMPTARGET_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
# We need C++11 support.
|
||||
if(LIBOMPTARGET_HAVE_STD_CPP11_FLAG)
|
||||
|
||||
libomptarget_say("Building offloading runtime library libomptarget.")
|
||||
|
||||
# Enable support for C++11.
|
||||
add_definitions(-std=c++11)
|
||||
|
||||
if(LIBOMPTARGET_ENABLE_WERROR AND LIBOMPTARGET_HAVE_WERROR_FLAG)
|
||||
add_definitions(-Werror)
|
||||
endif()
|
||||
|
||||
# If building this library in debug mode, we define a macro to enable
|
||||
# dumping progress messages at runtime.
|
||||
string( TOLOWER "${CMAKE_BUILD_TYPE}" LIBOMPTARGET_CMAKE_BUILD_TYPE)
|
||||
if(LIBOMPTARGET_CMAKE_BUILD_TYPE MATCHES debug)
|
||||
add_definitions(-DOMPTARGET_DEBUG)
|
||||
add_definitions(-g)
|
||||
add_definitions(-O0)
|
||||
endif()
|
||||
|
||||
set(src_files
|
||||
src/omptarget.cpp
|
||||
)
|
||||
|
||||
include_directories(src/)
|
||||
|
||||
# Build libomptarget library with libdl dependency.
|
||||
add_library(omptarget SHARED ${src_files})
|
||||
target_link_libraries(omptarget
|
||||
${CMAKE_DL_LIBS}
|
||||
"-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/exports")
|
||||
|
||||
# Install libomptarget under the lib destination folder.
|
||||
install(TARGETS omptarget LIBRARY DESTINATION lib${LIBOMPTARGET_LIBDIR_SUFFIX})
|
||||
|
||||
# Retrieve the path to the resulting library so that it can be used for
|
||||
# testing.
|
||||
get_target_property(LIBOMPTARGET_LIBRARY_DIR omptarget LIBRARY_OUTPUT_DIRECTORY)
|
||||
if(NOT LIBOMPTARGET_LIBRARY_DIR)
|
||||
set(LIBOMPTARGET_LIBRARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
|
||||
endif()
|
||||
|
||||
# Build offloading plugins and device RTLs if they are available.
|
||||
add_subdirectory(plugins)
|
||||
|
||||
# Add tests.
|
||||
add_subdirectory(test)
|
||||
|
||||
else(LIBOMPTARGET_HAVE_STD_CPP11_FLAG)
|
||||
libomptarget_say("Not building offloading runtime library libomptarget: host compiler must have c++11 support.")
|
||||
endif(LIBOMPTARGET_HAVE_STD_CPP11_FLAG)
|
||||
@@ -0,0 +1,74 @@
|
||||
|
||||
README for the LLVM* OpenMP* Offloading Runtime Library (libomptarget)
|
||||
======================================================================
|
||||
|
||||
How to Build the LLVM* OpenMP* Offloading Runtime Library (libomptarget)
|
||||
========================================================================
|
||||
In-tree build:
|
||||
|
||||
$ cd where-you-want-to-live
|
||||
Check out openmp (libomptarget lives under ./libomptarget) into llvm/projects
|
||||
$ cd where-you-want-to-build
|
||||
$ mkdir build && cd build
|
||||
$ cmake path/to/llvm -DCMAKE_C_COMPILER=<C compiler> -DCMAKE_CXX_COMPILER=<C++ compiler>
|
||||
$ make omptarget
|
||||
|
||||
Out-of-tree build:
|
||||
|
||||
$ cd where-you-want-to-live
|
||||
Check out openmp (libomptarget lives under ./libomptarget)
|
||||
$ cd where-you-want-to-live/openmp/libomptarget
|
||||
$ mkdir build && cd build
|
||||
$ cmake path/to/openmp -DCMAKE_C_COMPILER=<C compiler> -DCMAKE_CXX_COMPILER=<C++ compiler>
|
||||
$ make
|
||||
|
||||
For details about building, please look at Build_With_CMake.txt
|
||||
|
||||
Architectures Supported
|
||||
=======================
|
||||
The current library has been only tested in Linux operating system and the
|
||||
following host architectures:
|
||||
* Intel(R) 64 architecture
|
||||
* IBM(R) Power architecture (big endian)
|
||||
* IBM(R) Power architecture (little endian)
|
||||
* ARM(R) AArch64 architecture (little endian)
|
||||
|
||||
The currently supported offloading device architectures are:
|
||||
* Intel(R) 64 architecture (generic 64-bit plugin - mostly for testing purposes)
|
||||
* IBM(R) Power architecture (big endian) (generic 64-bit plugin - mostly for testing purposes)
|
||||
* IBM(R) Power architecture (little endian) (generic 64-bit plugin - mostly for testing purposes)
|
||||
* ARM(R) AArch64 architecture (little endian) (generic 64-bit plugin - mostly for testing purposes)
|
||||
* CUDA(R) enabled 64-bit NVIDIA(R) GPU architectures
|
||||
|
||||
Supported RTL Build Configurations
|
||||
==================================
|
||||
Supported Architectures: Intel(R) 64, IBM(R) Power 7 and Power 8
|
||||
|
||||
---------------------------
|
||||
| gcc | clang |
|
||||
--------------|------------|------------|
|
||||
| Linux* OS | Yes(1) | Yes(2) |
|
||||
-----------------------------------------
|
||||
|
||||
(1) gcc version 4.8.2 or later is supported.
|
||||
(2) clang version 3.7 or later is supported.
|
||||
|
||||
|
||||
Front-end Compilers that work with this RTL
|
||||
===========================================
|
||||
|
||||
The following compilers are known to do compatible code generation for
|
||||
this RTL:
|
||||
- clang (from https://github.com/clang-ykt )
|
||||
- clang (development branch at http://clang.llvm.org - several features still
|
||||
under development)
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
Notices
|
||||
=======
|
||||
This library and related compiler support is still under development, so the
|
||||
employed interface is likely to change in the future.
|
||||
|
||||
*Other names and brands may be claimed as the property of others.
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
#
|
||||
#//===----------------------------------------------------------------------===//
|
||||
#//
|
||||
#// The LLVM Compiler Infrastructure
|
||||
#//
|
||||
#// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
#// Source Licenses. See LICENSE.txt for details.
|
||||
#//
|
||||
#//===----------------------------------------------------------------------===//
|
||||
#
|
||||
|
||||
# Try to detect in the system several dependencies required by the different
|
||||
# components of libomptarget. These are the dependencies we have:
|
||||
#
|
||||
# libelf : required by some targets to handle the ELF files at runtime.
|
||||
# libffi : required to launch target kernels given function and argument
|
||||
# pointers.
|
||||
# CUDA : required to control offloading to NVIDIA GPUs.
|
||||
|
||||
include (FindPackageHandleStandardArgs)
|
||||
|
||||
################################################################################
|
||||
# Looking for libelf...
|
||||
################################################################################
|
||||
|
||||
find_path (
|
||||
LIBOMPTARGET_DEP_LIBELF_INCLUDE_DIR
|
||||
NAMES
|
||||
libelf.h
|
||||
PATHS
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
/opt/local/include
|
||||
/sw/include
|
||||
ENV CPATH
|
||||
PATH_SUFFIXES
|
||||
libelf)
|
||||
|
||||
find_library (
|
||||
LIBOMPTARGET_DEP_LIBELF_LIBRARIES
|
||||
NAMES
|
||||
elf
|
||||
PATHS
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
/opt/local/lib
|
||||
/sw/lib
|
||||
ENV LIBRARY_PATH
|
||||
ENV LD_LIBRARY_PATH)
|
||||
|
||||
set(LIBOMPTARGET_DEP_LIBELF_INCLUDE_DIRS ${LIBOMPTARGET_DEP_LIBELF_INCLUDE_DIR})
|
||||
find_package_handle_standard_args(
|
||||
LIBOMPTARGET_DEP_LIBELF
|
||||
DEFAULT_MSG
|
||||
LIBOMPTARGET_DEP_LIBELF_LIBRARIES
|
||||
LIBOMPTARGET_DEP_LIBELF_INCLUDE_DIRS)
|
||||
|
||||
mark_as_advanced(
|
||||
LIBOMPTARGET_DEP_LIBELF_INCLUDE_DIRS
|
||||
LIBOMPTARGET_DEP_LIBELF_LIBRARIES)
|
||||
|
||||
################################################################################
|
||||
# Looking for libffi...
|
||||
################################################################################
|
||||
find_package(PkgConfig)
|
||||
|
||||
pkg_check_modules(LIBOMPTARGET_SEARCH_LIBFFI QUIET libffi)
|
||||
|
||||
find_path (
|
||||
LIBOMPTARGET_DEP_LIBFFI_INCLUDE_DIR
|
||||
NAMES
|
||||
ffi.h
|
||||
HINTS
|
||||
${LIBOMPTARGET_SEARCH_LIBFFI_INCLUDEDIR}
|
||||
${LIBOMPTARGET_SEARCH_LIBFFI_INCLUDE_DIRS}
|
||||
PATHS
|
||||
/usr/include
|
||||
/usr/local/include
|
||||
/opt/local/include
|
||||
/sw/include
|
||||
ENV CPATH)
|
||||
|
||||
# Don't bother look for the library if the header files were not found.
|
||||
if (LIBOMPTARGET_DEP_LIBFFI_INCLUDE_DIR)
|
||||
find_library (
|
||||
LIBOMPTARGET_DEP_LIBFFI_LIBRARIES
|
||||
NAMES
|
||||
ffi
|
||||
HINTS
|
||||
${LIBOMPTARGET_SEARCH_LIBFFI_LIBDIR}
|
||||
${LIBOMPTARGET_SEARCH_LIBFFI_LIBRARY_DIRS}
|
||||
PATHS
|
||||
/usr/lib
|
||||
/usr/local/lib
|
||||
/opt/local/lib
|
||||
/sw/lib
|
||||
ENV LIBRARY_PATH
|
||||
ENV LD_LIBRARY_PATH)
|
||||
endif()
|
||||
|
||||
set(LIBOMPTARGET_DEP_LIBFFI_INCLUDE_DIRS ${LIBOMPTARGET_DEP_LIBFFI_INCLUDE_DIR})
|
||||
find_package_handle_standard_args(
|
||||
LIBOMPTARGET_DEP_LIBFFI
|
||||
DEFAULT_MSG
|
||||
LIBOMPTARGET_DEP_LIBFFI_LIBRARIES
|
||||
LIBOMPTARGET_DEP_LIBFFI_INCLUDE_DIRS)
|
||||
|
||||
mark_as_advanced(
|
||||
LIBOMPTARGET_DEP_LIBFFI_INCLUDE_DIRS
|
||||
LIBOMPTARGET_DEP_LIBFFI_LIBRARIES)
|
||||
|
||||
################################################################################
|
||||
# Looking for CUDA...
|
||||
################################################################################
|
||||
find_package(CUDA QUIET)
|
||||
|
||||
set(LIBOMPTARGET_DEP_CUDA_FOUND ${CUDA_FOUND})
|
||||
set(LIBOMPTARGET_DEP_CUDA_LIBRARIES ${CUDA_LIBRARIES})
|
||||
set(LIBOMPTARGET_DEP_CUDA_INCLUDE_DIRS ${CUDA_INCLUDE_DIRS})
|
||||
|
||||
mark_as_advanced(
|
||||
LIBOMPTARGET_DEP_CUDA_FOUND
|
||||
LIBOMPTARGET_DEP_CUDA_INCLUDE_DIRS
|
||||
LIBOMPTARGET_DEP_CUDA_LIBRARIES)
|
||||
@@ -0,0 +1,28 @@
|
||||
#
|
||||
#//===----------------------------------------------------------------------===//
|
||||
#//
|
||||
#// The LLVM Compiler Infrastructure
|
||||
#//
|
||||
#// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
#// Source Licenses. See LICENSE.txt for details.
|
||||
#//
|
||||
#//===----------------------------------------------------------------------===//
|
||||
#
|
||||
|
||||
# void libomptarget_say(string message_to_user);
|
||||
# - prints out message_to_user
|
||||
macro(libomptarget_say message_to_user)
|
||||
message(STATUS "LIBOMPTARGET: ${message_to_user}")
|
||||
endmacro()
|
||||
|
||||
# void libomptarget_warning_say(string message_to_user);
|
||||
# - prints out message_to_user with a warning
|
||||
macro(libomptarget_warning_say message_to_user)
|
||||
message(WARNING "LIBOMPTARGET: ${message_to_user}")
|
||||
endmacro()
|
||||
|
||||
# void libomptarget_error_say(string message_to_user);
|
||||
# - prints out message_to_user with an error and exits cmake
|
||||
macro(libomptarget_error_say message_to_user)
|
||||
message(FATAL_ERROR "LIBOMPTARGET: ${message_to_user}")
|
||||
endmacro()
|
||||
@@ -0,0 +1,17 @@
|
||||
#
|
||||
#//===----------------------------------------------------------------------===//
|
||||
#//
|
||||
#// The LLVM Compiler Infrastructure
|
||||
#//
|
||||
#// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
#// Source Licenses. See LICENSE.txt for details.
|
||||
#//
|
||||
#//===----------------------------------------------------------------------===//
|
||||
#
|
||||
|
||||
include(CheckCCompilerFlag)
|
||||
include(CheckCXXCompilerFlag)
|
||||
|
||||
# Checking C, CXX
|
||||
check_cxx_compiler_flag(-std=c++11 LIBOMPTARGET_HAVE_STD_CPP11_FLAG)
|
||||
check_c_compiler_flag(-Werror LIBOMPTARGET_HAVE_WERROR_FLAG)
|
||||
@@ -0,0 +1,28 @@
|
||||
VERS1.0 {
|
||||
global:
|
||||
__tgt_register_lib;
|
||||
__tgt_unregister_lib;
|
||||
__tgt_target_data_begin;
|
||||
__tgt_target_data_end;
|
||||
__tgt_target_data_update;
|
||||
__tgt_target;
|
||||
__tgt_target_teams;
|
||||
__tgt_target_data_begin_nowait;
|
||||
__tgt_target_data_end_nowait;
|
||||
__tgt_target_data_update_nowait;
|
||||
__tgt_target_nowait;
|
||||
__tgt_target_teams_nowait;
|
||||
omp_get_num_devices;
|
||||
omp_get_initial_device;
|
||||
omp_target_alloc;
|
||||
omp_target_free;
|
||||
omp_target_is_present;
|
||||
omp_target_memcpy;
|
||||
omp_target_memcpy_rect;
|
||||
omp_target_associate_ptr;
|
||||
omp_target_disassociate_ptr;
|
||||
__kmpc_push_target_tripcount;
|
||||
local:
|
||||
*;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
##===----------------------------------------------------------------------===##
|
||||
#
|
||||
# The LLVM Compiler Infrastructure
|
||||
#
|
||||
# This file is dual licensed under the MIT and the University of Illinois Open
|
||||
# Source Licenses. See LICENSE.txt for details.
|
||||
#
|
||||
##===----------------------------------------------------------------------===##
|
||||
#
|
||||
# Build plugins for the user system if available.
|
||||
#
|
||||
##===----------------------------------------------------------------------===##
|
||||
|
||||
# void build_generic_elf64(string tmachine, string tmachine_name, string tmachine_libname, string elf_machine_id);
|
||||
# - build a plugin for an ELF based generic 64-bit target based on libffi.
|
||||
# - tmachine: name of the machine processor as used in the cmake build system.
|
||||
# - tmachine_name: name of the machine to be printed with the debug messages.
|
||||
# - tmachine_libname: machine name to be appended to the plugin library name.
|
||||
macro(build_generic_elf64 tmachine tmachine_name tmachine_libname tmachine_triple elf_machine_id)
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "${tmachine}$")
|
||||
if(LIBOMPTARGET_DEP_LIBELF_FOUND)
|
||||
if(LIBOMPTARGET_DEP_LIBFFI_FOUND)
|
||||
|
||||
libomptarget_say("Building ${tmachine_name} offloading plugin.")
|
||||
|
||||
include_directories(${LIBOMPTARGET_DEP_LIBFFI_INCLUDE_DIR})
|
||||
include_directories(${LIBOMPTARGET_DEP_LIBELF_INCLUDE_DIR})
|
||||
|
||||
# Define macro to be used as prefix of the runtime messages for this target.
|
||||
add_definitions("-DTARGET_NAME=${tmachine_name}")
|
||||
|
||||
# Define macro with the ELF ID for this target.
|
||||
add_definitions("-DTARGET_ELF_ID=${elf_machine_id}")
|
||||
|
||||
add_library("omptarget.rtl.${tmachine_libname}" SHARED
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../generic-elf-64bit/src/rtl.cpp)
|
||||
|
||||
# Install plugin under the lib destination folder.
|
||||
install(TARGETS "omptarget.rtl.${tmachine_libname}"
|
||||
LIBRARY DESTINATION lib${LIBOMPTARGET_LIBDIR_SUFFIX})
|
||||
|
||||
target_link_libraries(
|
||||
"omptarget.rtl.${tmachine_libname}"
|
||||
${LIBOMPTARGET_DEP_LIBFFI_LIBRARIES}
|
||||
${LIBOMPTARGET_DEP_LIBELF_LIBRARIES}
|
||||
dl
|
||||
"-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/../exports")
|
||||
|
||||
# Report to the parent scope that we are building a plugin.
|
||||
set(LIBOMPTARGET_SYSTEM_TARGETS
|
||||
"${LIBOMPTARGET_SYSTEM_TARGETS} ${tmachine_triple}" PARENT_SCOPE)
|
||||
|
||||
else(LIBOMPTARGET_DEP_LIBFFI_FOUND)
|
||||
libomptarget_say("Not building ${tmachine_name} offloading plugin: libffi dependency not found.")
|
||||
endif(LIBOMPTARGET_DEP_LIBFFI_FOUND)
|
||||
else(LIBOMPTARGET_DEP_LIBELF_FOUND)
|
||||
libomptarget_say("Not building ${tmachine_name} offloading plugin: libelf dependency not found.")
|
||||
endif(LIBOMPTARGET_DEP_LIBELF_FOUND)
|
||||
else()
|
||||
libomptarget_say("Not building ${tmachine_name} offloading plugin: machine not found in the system.")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
add_subdirectory(aarch64)
|
||||
add_subdirectory(cuda)
|
||||
add_subdirectory(ppc64)
|
||||
add_subdirectory(ppc64le)
|
||||
add_subdirectory(x86_64)
|
||||
|
||||
# Make sure the parent scope can see the plugins that will be created.
|
||||
set(LIBOMPTARGET_SYSTEM_TARGETS "${LIBOMPTARGET_SYSTEM_TARGETS}" PARENT_SCOPE)
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
##===----------------------------------------------------------------------===##
|
||||
#
|
||||
# The LLVM Compiler Infrastructure
|
||||
#
|
||||
# This file is dual licensed under the MIT and the University of Illinois Open
|
||||
# Source Licenses. See LICENSE.txt for details.
|
||||
#
|
||||
##===----------------------------------------------------------------------===##
|
||||
#
|
||||
# Build a plugin for an aarch64 machine if available.
|
||||
#
|
||||
##===----------------------------------------------------------------------===##
|
||||
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
build_generic_elf64("aarch64" "aarch64" "aarch64" "aarch64-unknown-linux-gnu" "183")
|
||||
else()
|
||||
libomptarget_say("Not building aarch64 offloading plugin: machine not found in the system.")
|
||||
endif()
|
||||
@@ -0,0 +1,73 @@
|
||||
//===-- elf_common.c - Common ELF functionality -------------------*- C -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.txt for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Common ELF functionality for target plugins.
|
||||
// Must be included in the plugin source file AFTER omptarget.h has been
|
||||
// included and macro DP(...) has been defined.
|
||||
// .
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#if !(defined(_OMPTARGET_H_) && defined(DP))
|
||||
#error Include elf_common.c in the plugin source AFTER omptarget.h has been\
|
||||
included and macro DP(...) has been defined.
|
||||
#endif
|
||||
|
||||
#include <elf.h>
|
||||
#include <libelf.h>
|
||||
|
||||
// Check whether an image is valid for execution on target_id
|
||||
static inline int32_t elf_check_machine(__tgt_device_image *image,
|
||||
uint16_t target_id) {
|
||||
|
||||
// Is the library version incompatible with the header file?
|
||||
if (elf_version(EV_CURRENT) == EV_NONE) {
|
||||
DP("Incompatible ELF library!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *img_begin = (char *)image->ImageStart;
|
||||
char *img_end = (char *)image->ImageEnd;
|
||||
size_t img_size = img_end - img_begin;
|
||||
|
||||
// Obtain elf handler
|
||||
Elf *e = elf_memory(img_begin, img_size);
|
||||
if (!e) {
|
||||
DP("Unable to get ELF handle: %s!\n", elf_errmsg(-1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Check if ELF is the right kind.
|
||||
if (elf_kind(e) != ELF_K_ELF) {
|
||||
DP("Unexpected ELF type!\n");
|
||||
return 0;
|
||||
}
|
||||
Elf64_Ehdr *eh64 = elf64_getehdr(e);
|
||||
Elf32_Ehdr *eh32 = elf32_getehdr(e);
|
||||
|
||||
if (!eh64 && !eh32) {
|
||||
DP("Unable to get machine ID from ELF file!\n");
|
||||
elf_end(e);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t MachineID;
|
||||
if (eh64 && !eh32)
|
||||
MachineID = eh64->e_machine;
|
||||
else if (eh32 && !eh64)
|
||||
MachineID = eh32->e_machine;
|
||||
else {
|
||||
DP("Ambiguous ELF header!\n");
|
||||
elf_end(e);
|
||||
return 0;
|
||||
}
|
||||
|
||||
elf_end(e);
|
||||
return MachineID == target_id;
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
##===----------------------------------------------------------------------===##
|
||||
#
|
||||
# The LLVM Compiler Infrastructure
|
||||
#
|
||||
# This file is dual licensed under the MIT and the University of Illinois Open
|
||||
# Source Licenses. See LICENSE.txt for details.
|
||||
#
|
||||
##===----------------------------------------------------------------------===##
|
||||
#
|
||||
# Build a plugin for a CUDA machine if available.
|
||||
#
|
||||
##===----------------------------------------------------------------------===##
|
||||
if(LIBOMPTARGET_DEP_LIBELF_FOUND)
|
||||
if(LIBOMPTARGET_DEP_CUDA_FOUND)
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "(x86_64)|(ppc64le)$" AND CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
|
||||
libomptarget_say("Building CUDA offloading plugin.")
|
||||
|
||||
# Define the suffix for the runtime messaging dumps.
|
||||
add_definitions(-DTARGET_NAME=CUDA)
|
||||
|
||||
if(LIBOMPTARGET_CMAKE_BUILD_TYPE MATCHES debug)
|
||||
add_definitions(-DCUDA_ERROR_REPORT)
|
||||
endif()
|
||||
|
||||
include_directories(${LIBOMPTARGET_DEP_CUDA_INCLUDE_DIRS})
|
||||
include_directories(${LIBOMPTARGET_DEP_LIBELF_INCLUDE_DIRS})
|
||||
|
||||
add_library(omptarget.rtl.cuda SHARED src/rtl.cpp)
|
||||
|
||||
# Install plugin under the lib destination folder.
|
||||
install(TARGETS omptarget.rtl.cuda LIBRARY DESTINATION lib${LIBOMPTARGET_LIBDIR_SUFFIX})
|
||||
|
||||
target_link_libraries(omptarget.rtl.cuda
|
||||
${LIBOMPTARGET_DEP_CUDA_LIBRARIES}
|
||||
cuda
|
||||
${LIBOMPTARGET_DEP_LIBELF_LIBRARIES}
|
||||
"-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/../exports")
|
||||
|
||||
# Report to the parent scope that we are building a plugin for CUDA.
|
||||
set(LIBOMPTARGET_SYSTEM_TARGETS "${LIBOMPTARGET_SYSTEM_TARGETS} nvptx64-nvidia-cuda" PARENT_SCOPE)
|
||||
else()
|
||||
libomptarget_say("Not building CUDA offloading plugin: only support CUDA in Linux x86_64 or ppc64le hosts.")
|
||||
endif()
|
||||
else()
|
||||
libomptarget_say("Not building CUDA offloading plugin: CUDA not found in system.")
|
||||
endif()
|
||||
else(LIBOMPTARGET_DEP_LIBELF_FOUND)
|
||||
libomptarget_say("Not building CUDA offloading plugin: libelf dependency not found.")
|
||||
endif(LIBOMPTARGET_DEP_LIBELF_FOUND)
|
||||
@@ -0,0 +1,694 @@
|
||||
//===----RTLs/cuda/src/rtl.cpp - Target RTLs Implementation ------- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.txt for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// RTL for CUDA machine
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cuda.h>
|
||||
#include <cuda_runtime_api.h>
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "omptargetplugin.h"
|
||||
|
||||
#ifndef TARGET_NAME
|
||||
#define TARGET_NAME CUDA
|
||||
#endif
|
||||
|
||||
#define GETNAME2(name) #name
|
||||
#define GETNAME(name) GETNAME2(name)
|
||||
#define DP(...) DEBUGP("Target " GETNAME(TARGET_NAME) " RTL", __VA_ARGS__)
|
||||
|
||||
#include "../../common/elf_common.c"
|
||||
|
||||
// Utility for retrieving and printing CUDA error string.
|
||||
#ifdef CUDA_ERROR_REPORT
|
||||
#define CUDA_ERR_STRING(err) \
|
||||
do { \
|
||||
const char *errStr; \
|
||||
cuGetErrorString(err, &errStr); \
|
||||
DP("CUDA error is: %s\n", errStr); \
|
||||
} while (0)
|
||||
#else
|
||||
#define CUDA_ERR_STRING(err) \
|
||||
{}
|
||||
#endif
|
||||
|
||||
/// Keep entries table per device.
|
||||
struct FuncOrGblEntryTy {
|
||||
__tgt_target_table Table;
|
||||
std::vector<__tgt_offload_entry> Entries;
|
||||
};
|
||||
|
||||
enum ExecutionModeType {
|
||||
SPMD, // constructors, destructors,
|
||||
// combined constructs (`teams distribute parallel for [simd]`)
|
||||
GENERIC, // everything else
|
||||
NONE
|
||||
};
|
||||
|
||||
/// Use a single entity to encode a kernel and a set of flags
|
||||
struct KernelTy {
|
||||
CUfunction Func;
|
||||
|
||||
// execution mode of kernel
|
||||
// 0 - SPMD mode (without master warp)
|
||||
// 1 - Generic mode (with master warp)
|
||||
int8_t ExecutionMode;
|
||||
|
||||
KernelTy(CUfunction _Func, int8_t _ExecutionMode)
|
||||
: Func(_Func), ExecutionMode(_ExecutionMode) {}
|
||||
};
|
||||
|
||||
/// List that contains all the kernels.
|
||||
/// FIXME: we may need this to be per device and per library.
|
||||
std::list<KernelTy> KernelsList;
|
||||
|
||||
/// Class containing all the device information.
|
||||
class RTLDeviceInfoTy {
|
||||
std::vector<FuncOrGblEntryTy> FuncGblEntries;
|
||||
|
||||
public:
|
||||
int NumberOfDevices;
|
||||
std::vector<CUmodule> Modules;
|
||||
std::vector<CUcontext> Contexts;
|
||||
|
||||
// Device properties
|
||||
std::vector<int> ThreadsPerBlock;
|
||||
std::vector<int> BlocksPerGrid;
|
||||
std::vector<int> WarpSize;
|
||||
|
||||
// OpenMP properties
|
||||
std::vector<int> NumTeams;
|
||||
std::vector<int> NumThreads;
|
||||
|
||||
// OpenMP Environment properties
|
||||
int EnvNumTeams;
|
||||
int EnvTeamLimit;
|
||||
|
||||
//static int EnvNumThreads;
|
||||
static const int HardTeamLimit = 1<<16; // 64k
|
||||
static const int HardThreadLimit = 1024;
|
||||
static const int DefaultNumTeams = 128;
|
||||
static const int DefaultNumThreads = 128;
|
||||
|
||||
// Record entry point associated with device
|
||||
void addOffloadEntry(int32_t device_id, __tgt_offload_entry entry) {
|
||||
assert(device_id < (int32_t)FuncGblEntries.size() &&
|
||||
"Unexpected device id!");
|
||||
FuncOrGblEntryTy &E = FuncGblEntries[device_id];
|
||||
|
||||
E.Entries.push_back(entry);
|
||||
}
|
||||
|
||||
// Return true if the entry is associated with device
|
||||
bool findOffloadEntry(int32_t device_id, void *addr) {
|
||||
assert(device_id < (int32_t)FuncGblEntries.size() &&
|
||||
"Unexpected device id!");
|
||||
FuncOrGblEntryTy &E = FuncGblEntries[device_id];
|
||||
|
||||
for (auto &it : E.Entries) {
|
||||
if (it.addr == addr)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return the pointer to the target entries table
|
||||
__tgt_target_table *getOffloadEntriesTable(int32_t device_id) {
|
||||
assert(device_id < (int32_t)FuncGblEntries.size() &&
|
||||
"Unexpected device id!");
|
||||
FuncOrGblEntryTy &E = FuncGblEntries[device_id];
|
||||
|
||||
int32_t size = E.Entries.size();
|
||||
|
||||
// Table is empty
|
||||
if (!size)
|
||||
return 0;
|
||||
|
||||
__tgt_offload_entry *begin = &E.Entries[0];
|
||||
__tgt_offload_entry *end = &E.Entries[size - 1];
|
||||
|
||||
// Update table info according to the entries and return the pointer
|
||||
E.Table.EntriesBegin = begin;
|
||||
E.Table.EntriesEnd = ++end;
|
||||
|
||||
return &E.Table;
|
||||
}
|
||||
|
||||
// Clear entries table for a device
|
||||
void clearOffloadEntriesTable(int32_t device_id) {
|
||||
assert(device_id < (int32_t)FuncGblEntries.size() &&
|
||||
"Unexpected device id!");
|
||||
FuncOrGblEntryTy &E = FuncGblEntries[device_id];
|
||||
E.Entries.clear();
|
||||
E.Table.EntriesBegin = E.Table.EntriesEnd = 0;
|
||||
}
|
||||
|
||||
RTLDeviceInfoTy() {
|
||||
DP("Start initializing CUDA\n");
|
||||
|
||||
CUresult err = cuInit(0);
|
||||
if (err != CUDA_SUCCESS) {
|
||||
DP("Error when initializing CUDA\n");
|
||||
CUDA_ERR_STRING(err);
|
||||
return;
|
||||
}
|
||||
|
||||
NumberOfDevices = 0;
|
||||
|
||||
err = cuDeviceGetCount(&NumberOfDevices);
|
||||
if (err != CUDA_SUCCESS) {
|
||||
DP("Error when getting CUDA device count\n");
|
||||
CUDA_ERR_STRING(err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (NumberOfDevices == 0) {
|
||||
DP("There are no devices supporting CUDA.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
FuncGblEntries.resize(NumberOfDevices);
|
||||
Contexts.resize(NumberOfDevices);
|
||||
ThreadsPerBlock.resize(NumberOfDevices);
|
||||
BlocksPerGrid.resize(NumberOfDevices);
|
||||
WarpSize.resize(NumberOfDevices);
|
||||
NumTeams.resize(NumberOfDevices);
|
||||
NumThreads.resize(NumberOfDevices);
|
||||
|
||||
// Get environment variables regarding teams
|
||||
char *envStr = getenv("OMP_TEAM_LIMIT");
|
||||
if (envStr) {
|
||||
// OMP_TEAM_LIMIT has been set
|
||||
EnvTeamLimit = std::stoi(envStr);
|
||||
DP("Parsed OMP_TEAM_LIMIT=%d\n", EnvTeamLimit);
|
||||
} else {
|
||||
EnvTeamLimit = -1;
|
||||
}
|
||||
envStr = getenv("OMP_NUM_TEAMS");
|
||||
if (envStr) {
|
||||
// OMP_NUM_TEAMS has been set
|
||||
EnvNumTeams = std::stoi(envStr);
|
||||
DP("Parsed OMP_NUM_TEAMS=%d\n", EnvNumTeams);
|
||||
} else {
|
||||
EnvNumTeams = -1;
|
||||
}
|
||||
}
|
||||
|
||||
~RTLDeviceInfoTy() {
|
||||
// Close modules
|
||||
for (auto &module : Modules)
|
||||
if (module) {
|
||||
CUresult err = cuModuleUnload(module);
|
||||
if (err != CUDA_SUCCESS) {
|
||||
DP("Error when unloading CUDA module\n");
|
||||
CUDA_ERR_STRING(err);
|
||||
}
|
||||
}
|
||||
|
||||
// Destroy contexts
|
||||
for (auto &ctx : Contexts)
|
||||
if (ctx) {
|
||||
CUresult err = cuCtxDestroy(ctx);
|
||||
if (err != CUDA_SUCCESS) {
|
||||
DP("Error when destroying CUDA context\n");
|
||||
CUDA_ERR_STRING(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static RTLDeviceInfoTy DeviceInfo;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int32_t __tgt_rtl_is_valid_binary(__tgt_device_image *image) {
|
||||
return elf_check_machine(image, 190); // EM_CUDA = 190.
|
||||
}
|
||||
|
||||
int32_t __tgt_rtl_number_of_devices() { return DeviceInfo.NumberOfDevices; }
|
||||
|
||||
int32_t __tgt_rtl_init_device(int32_t device_id) {
|
||||
|
||||
CUdevice cuDevice;
|
||||
DP("Getting device %d\n", device_id);
|
||||
CUresult err = cuDeviceGet(&cuDevice, device_id);
|
||||
if (err != CUDA_SUCCESS) {
|
||||
DP("Error when getting CUDA device with id = %d\n", device_id);
|
||||
CUDA_ERR_STRING(err);
|
||||
return OFFLOAD_FAIL;
|
||||
}
|
||||
|
||||
// Create the context and save it to use whenever this device is selected.
|
||||
err = cuCtxCreate(&DeviceInfo.Contexts[device_id], CU_CTX_SCHED_BLOCKING_SYNC,
|
||||
cuDevice);
|
||||
if (err != CUDA_SUCCESS) {
|
||||
DP("Error when creating a CUDA context\n");
|
||||
CUDA_ERR_STRING(err);
|
||||
return OFFLOAD_FAIL;
|
||||
}
|
||||
|
||||
// scan properties to determine number of threads/block and blocks/grid.
|
||||
struct cudaDeviceProp Properties;
|
||||
cudaError_t error = cudaGetDeviceProperties(&Properties, device_id);
|
||||
if (error != cudaSuccess) {
|
||||
DP("Error getting device Properties, use defaults\n");
|
||||
DeviceInfo.BlocksPerGrid[device_id] = RTLDeviceInfoTy::DefaultNumTeams;
|
||||
DeviceInfo.ThreadsPerBlock[device_id] = RTLDeviceInfoTy::DefaultNumThreads;
|
||||
DeviceInfo.WarpSize[device_id] = 32;
|
||||
} else {
|
||||
// Get blocks per grid
|
||||
if (Properties.maxGridSize[0] <= RTLDeviceInfoTy::HardTeamLimit) {
|
||||
DeviceInfo.BlocksPerGrid[device_id] = Properties.maxGridSize[0];
|
||||
DP("Using %d CUDA blocks per grid\n", Properties.maxGridSize[0]);
|
||||
} else {
|
||||
DeviceInfo.BlocksPerGrid[device_id] = RTLDeviceInfoTy::HardTeamLimit;
|
||||
DP("Max CUDA blocks per grid %d exceeds the hard team limit %d, capping "
|
||||
"at the hard limit\n", Properties.maxGridSize[0],
|
||||
RTLDeviceInfoTy::HardTeamLimit);
|
||||
}
|
||||
|
||||
// Get threads per block, exploit threads only along x axis
|
||||
if (Properties.maxThreadsDim[0] <= RTLDeviceInfoTy::HardThreadLimit) {
|
||||
DeviceInfo.ThreadsPerBlock[device_id] = Properties.maxThreadsDim[0];
|
||||
DP("Using %d CUDA threads per block\n", Properties.maxThreadsDim[0]);
|
||||
if (Properties.maxThreadsDim[0] < Properties.maxThreadsPerBlock) {
|
||||
DP("(fewer than max per block along all xyz dims %d)\n",
|
||||
Properties.maxThreadsPerBlock);
|
||||
}
|
||||
} else {
|
||||
DeviceInfo.ThreadsPerBlock[device_id] = RTLDeviceInfoTy::HardThreadLimit;
|
||||
DP("Max CUDA threads per block %d exceeds the hard thread limit %d, "
|
||||
"capping at the hard limit\n", Properties.maxThreadsDim[0],
|
||||
RTLDeviceInfoTy::HardThreadLimit);
|
||||
}
|
||||
|
||||
// Get warp size
|
||||
DeviceInfo.WarpSize[device_id] = Properties.warpSize;
|
||||
}
|
||||
|
||||
// Adjust teams to the env variables
|
||||
if (DeviceInfo.EnvTeamLimit > 0 &&
|
||||
DeviceInfo.BlocksPerGrid[device_id] > DeviceInfo.EnvTeamLimit) {
|
||||
DeviceInfo.BlocksPerGrid[device_id] = DeviceInfo.EnvTeamLimit;
|
||||
DP("Capping max CUDA blocks per grid to OMP_TEAM_LIMIT=%d\n",
|
||||
DeviceInfo.EnvTeamLimit);
|
||||
}
|
||||
|
||||
DP("Max number of CUDA blocks %d, threads %d & warp size %d\n",
|
||||
DeviceInfo.BlocksPerGrid[device_id], DeviceInfo.ThreadsPerBlock[device_id],
|
||||
DeviceInfo.WarpSize[device_id]);
|
||||
|
||||
// Set default number of teams
|
||||
if (DeviceInfo.EnvNumTeams > 0) {
|
||||
DeviceInfo.NumTeams[device_id] = DeviceInfo.EnvNumTeams;
|
||||
DP("Default number of teams set according to environment %d\n",
|
||||
DeviceInfo.EnvNumTeams);
|
||||
} else {
|
||||
DeviceInfo.NumTeams[device_id] = RTLDeviceInfoTy::DefaultNumTeams;
|
||||
DP("Default number of teams set according to library's default %d\n",
|
||||
RTLDeviceInfoTy::DefaultNumTeams);
|
||||
}
|
||||
if (DeviceInfo.NumTeams[device_id] > DeviceInfo.BlocksPerGrid[device_id]) {
|
||||
DeviceInfo.NumTeams[device_id] = DeviceInfo.BlocksPerGrid[device_id];
|
||||
DP("Default number of teams exceeds device limit, capping at %d\n",
|
||||
DeviceInfo.BlocksPerGrid[device_id]);
|
||||
}
|
||||
|
||||
// Set default number of threads
|
||||
DeviceInfo.NumThreads[device_id] = RTLDeviceInfoTy::DefaultNumThreads;
|
||||
DP("Default number of threads set according to library's default %d\n",
|
||||
RTLDeviceInfoTy::DefaultNumThreads);
|
||||
if (DeviceInfo.NumThreads[device_id] >
|
||||
DeviceInfo.ThreadsPerBlock[device_id]) {
|
||||
DeviceInfo.NumTeams[device_id] = DeviceInfo.ThreadsPerBlock[device_id];
|
||||
DP("Default number of threads exceeds device limit, capping at %d\n",
|
||||
DeviceInfo.ThreadsPerBlock[device_id]);
|
||||
}
|
||||
|
||||
return OFFLOAD_SUCCESS;
|
||||
}
|
||||
|
||||
__tgt_target_table *__tgt_rtl_load_binary(int32_t device_id,
|
||||
__tgt_device_image *image) {
|
||||
|
||||
// Set the context we are using.
|
||||
CUresult err = cuCtxSetCurrent(DeviceInfo.Contexts[device_id]);
|
||||
if (err != CUDA_SUCCESS) {
|
||||
DP("Error when setting a CUDA context for device %d\n", device_id);
|
||||
CUDA_ERR_STRING(err);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Clear the offload table as we are going to create a new one.
|
||||
DeviceInfo.clearOffloadEntriesTable(device_id);
|
||||
|
||||
// Create the module and extract the function pointers.
|
||||
|
||||
CUmodule cumod;
|
||||
DP("Load data from image " DPxMOD "\n", DPxPTR(image->ImageStart));
|
||||
err = cuModuleLoadDataEx(&cumod, image->ImageStart, 0, NULL, NULL);
|
||||
if (err != CUDA_SUCCESS) {
|
||||
DP("Error when loading CUDA module\n");
|
||||
CUDA_ERR_STRING(err);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DP("CUDA module successfully loaded!\n");
|
||||
DeviceInfo.Modules.push_back(cumod);
|
||||
|
||||
// Find the symbols in the module by name.
|
||||
__tgt_offload_entry *HostBegin = image->EntriesBegin;
|
||||
__tgt_offload_entry *HostEnd = image->EntriesEnd;
|
||||
|
||||
for (__tgt_offload_entry *e = HostBegin; e != HostEnd; ++e) {
|
||||
|
||||
if (!e->addr) {
|
||||
// We return NULL when something like this happens, the host should have
|
||||
// always something in the address to uniquely identify the target region.
|
||||
DP("Invalid binary: host entry '<null>' (size = %zd)...\n", e->size);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (e->size) {
|
||||
__tgt_offload_entry entry = *e;
|
||||
|
||||
CUdeviceptr cuptr;
|
||||
size_t cusize;
|
||||
err = cuModuleGetGlobal(&cuptr, &cusize, cumod, e->name);
|
||||
|
||||
if (err != CUDA_SUCCESS) {
|
||||
DP("Loading global '%s' (Failed)\n", e->name);
|
||||
CUDA_ERR_STRING(err);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (cusize != e->size) {
|
||||
DP("Loading global '%s' - size mismatch (%zd != %zd)\n", e->name,
|
||||
cusize, e->size);
|
||||
CUDA_ERR_STRING(err);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DP("Entry point " DPxMOD " maps to global %s (" DPxMOD ")\n",
|
||||
DPxPTR(e - HostBegin), e->name, DPxPTR(cuptr));
|
||||
entry.addr = (void *)cuptr;
|
||||
|
||||
DeviceInfo.addOffloadEntry(device_id, entry);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
CUfunction fun;
|
||||
err = cuModuleGetFunction(&fun, cumod, e->name);
|
||||
|
||||
if (err != CUDA_SUCCESS) {
|
||||
DP("Loading '%s' (Failed)\n", e->name);
|
||||
CUDA_ERR_STRING(err);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DP("Entry point " DPxMOD " maps to %s (" DPxMOD ")\n",
|
||||
DPxPTR(e - HostBegin), e->name, DPxPTR(fun));
|
||||
|
||||
// default value GENERIC (in case symbol is missing from cubin file)
|
||||
int8_t ExecModeVal = ExecutionModeType::GENERIC;
|
||||
std::string ExecModeNameStr (e->name);
|
||||
ExecModeNameStr += "_exec_mode";
|
||||
const char *ExecModeName = ExecModeNameStr.c_str();
|
||||
|
||||
CUdeviceptr ExecModePtr;
|
||||
size_t cusize;
|
||||
err = cuModuleGetGlobal(&ExecModePtr, &cusize, cumod, ExecModeName);
|
||||
if (err == CUDA_SUCCESS) {
|
||||
if ((size_t)cusize != sizeof(int8_t)) {
|
||||
DP("Loading global exec_mode '%s' - size mismatch (%zd != %zd)\n",
|
||||
ExecModeName, cusize, sizeof(int8_t));
|
||||
CUDA_ERR_STRING(err);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
err = cuMemcpyDtoH(&ExecModeVal, ExecModePtr, cusize);
|
||||
if (err != CUDA_SUCCESS) {
|
||||
DP("Error when copying data from device to host. Pointers: "
|
||||
"host = " DPxMOD ", device = " DPxMOD ", size = %zd\n",
|
||||
DPxPTR(&ExecModeVal), DPxPTR(ExecModePtr), cusize);
|
||||
CUDA_ERR_STRING(err);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ExecModeVal < 0 || ExecModeVal > 1) {
|
||||
DP("Error wrong exec_mode value specified in cubin file: %d\n",
|
||||
ExecModeVal);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
DP("Loading global exec_mode '%s' - symbol missing, using default value "
|
||||
"GENERIC (1)\n", ExecModeName);
|
||||
CUDA_ERR_STRING(err);
|
||||
}
|
||||
|
||||
KernelsList.push_back(KernelTy(fun, ExecModeVal));
|
||||
|
||||
__tgt_offload_entry entry = *e;
|
||||
entry.addr = (void *)&KernelsList.back();
|
||||
DeviceInfo.addOffloadEntry(device_id, entry);
|
||||
}
|
||||
|
||||
return DeviceInfo.getOffloadEntriesTable(device_id);
|
||||
}
|
||||
|
||||
void *__tgt_rtl_data_alloc(int32_t device_id, int64_t size, void *hst_ptr) {
|
||||
if (size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Set the context we are using.
|
||||
CUresult err = cuCtxSetCurrent(DeviceInfo.Contexts[device_id]);
|
||||
if (err != CUDA_SUCCESS) {
|
||||
DP("Error while trying to set CUDA current context\n");
|
||||
CUDA_ERR_STRING(err);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CUdeviceptr ptr;
|
||||
err = cuMemAlloc(&ptr, size);
|
||||
if (err != CUDA_SUCCESS) {
|
||||
DP("Error while trying to allocate %d\n", err);
|
||||
CUDA_ERR_STRING(err);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *vptr = (void *)ptr;
|
||||
return vptr;
|
||||
}
|
||||
|
||||
int32_t __tgt_rtl_data_submit(int32_t device_id, void *tgt_ptr, void *hst_ptr,
|
||||
int64_t size) {
|
||||
// Set the context we are using.
|
||||
CUresult err = cuCtxSetCurrent(DeviceInfo.Contexts[device_id]);
|
||||
if (err != CUDA_SUCCESS) {
|
||||
DP("Error when setting CUDA context\n");
|
||||
CUDA_ERR_STRING(err);
|
||||
return OFFLOAD_FAIL;
|
||||
}
|
||||
|
||||
err = cuMemcpyHtoD((CUdeviceptr)tgt_ptr, hst_ptr, size);
|
||||
if (err != CUDA_SUCCESS) {
|
||||
DP("Error when copying data from host to device. Pointers: host = " DPxMOD
|
||||
", device = " DPxMOD ", size = %" PRId64 "\n", DPxPTR(hst_ptr),
|
||||
DPxPTR(tgt_ptr), size);
|
||||
CUDA_ERR_STRING(err);
|
||||
return OFFLOAD_FAIL;
|
||||
}
|
||||
return OFFLOAD_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t __tgt_rtl_data_retrieve(int32_t device_id, void *hst_ptr, void *tgt_ptr,
|
||||
int64_t size) {
|
||||
// Set the context we are using.
|
||||
CUresult err = cuCtxSetCurrent(DeviceInfo.Contexts[device_id]);
|
||||
if (err != CUDA_SUCCESS) {
|
||||
DP("Error when setting CUDA context\n");
|
||||
CUDA_ERR_STRING(err);
|
||||
return OFFLOAD_FAIL;
|
||||
}
|
||||
|
||||
err = cuMemcpyDtoH(hst_ptr, (CUdeviceptr)tgt_ptr, size);
|
||||
if (err != CUDA_SUCCESS) {
|
||||
DP("Error when copying data from device to host. Pointers: host = " DPxMOD
|
||||
", device = " DPxMOD ", size = %" PRId64 "\n", DPxPTR(hst_ptr),
|
||||
DPxPTR(tgt_ptr), size);
|
||||
CUDA_ERR_STRING(err);
|
||||
return OFFLOAD_FAIL;
|
||||
}
|
||||
return OFFLOAD_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t __tgt_rtl_data_delete(int32_t device_id, void *tgt_ptr) {
|
||||
// Set the context we are using.
|
||||
CUresult err = cuCtxSetCurrent(DeviceInfo.Contexts[device_id]);
|
||||
if (err != CUDA_SUCCESS) {
|
||||
DP("Error when setting CUDA context\n");
|
||||
CUDA_ERR_STRING(err);
|
||||
return OFFLOAD_FAIL;
|
||||
}
|
||||
|
||||
err = cuMemFree((CUdeviceptr)tgt_ptr);
|
||||
if (err != CUDA_SUCCESS) {
|
||||
DP("Error when freeing CUDA memory\n");
|
||||
CUDA_ERR_STRING(err);
|
||||
return OFFLOAD_FAIL;
|
||||
}
|
||||
return OFFLOAD_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t __tgt_rtl_run_target_team_region(int32_t device_id, void *tgt_entry_ptr,
|
||||
void **tgt_args, ptrdiff_t *tgt_offsets, int32_t arg_num, int32_t team_num,
|
||||
int32_t thread_limit, uint64_t loop_tripcount) {
|
||||
// Set the context we are using.
|
||||
CUresult err = cuCtxSetCurrent(DeviceInfo.Contexts[device_id]);
|
||||
if (err != CUDA_SUCCESS) {
|
||||
DP("Error when setting CUDA context\n");
|
||||
CUDA_ERR_STRING(err);
|
||||
return OFFLOAD_FAIL;
|
||||
}
|
||||
|
||||
// All args are references.
|
||||
std::vector<void *> args(arg_num);
|
||||
std::vector<void *> ptrs(arg_num);
|
||||
|
||||
for (int32_t i = 0; i < arg_num; ++i) {
|
||||
ptrs[i] = (void *)((intptr_t)tgt_args[i] + tgt_offsets[i]);
|
||||
args[i] = &ptrs[i];
|
||||
}
|
||||
|
||||
KernelTy *KernelInfo = (KernelTy *)tgt_entry_ptr;
|
||||
|
||||
int cudaThreadsPerBlock;
|
||||
|
||||
if (thread_limit > 0) {
|
||||
cudaThreadsPerBlock = thread_limit;
|
||||
DP("Setting CUDA threads per block to requested %d\n", thread_limit);
|
||||
// Add master warp if necessary
|
||||
if (KernelInfo->ExecutionMode == GENERIC) {
|
||||
cudaThreadsPerBlock += DeviceInfo.WarpSize[device_id];
|
||||
DP("Adding master warp: +%d threads\n", DeviceInfo.WarpSize[device_id]);
|
||||
}
|
||||
} else {
|
||||
cudaThreadsPerBlock = DeviceInfo.NumThreads[device_id];
|
||||
DP("Setting CUDA threads per block to default %d\n",
|
||||
DeviceInfo.NumThreads[device_id]);
|
||||
}
|
||||
|
||||
if (cudaThreadsPerBlock > DeviceInfo.ThreadsPerBlock[device_id]) {
|
||||
cudaThreadsPerBlock = DeviceInfo.ThreadsPerBlock[device_id];
|
||||
DP("Threads per block capped at device limit %d\n",
|
||||
DeviceInfo.ThreadsPerBlock[device_id]);
|
||||
}
|
||||
|
||||
int kernel_limit;
|
||||
err = cuFuncGetAttribute(&kernel_limit,
|
||||
CU_FUNC_ATTRIBUTE_MAX_THREADS_PER_BLOCK, KernelInfo->Func);
|
||||
if (err == CUDA_SUCCESS) {
|
||||
if (kernel_limit < cudaThreadsPerBlock) {
|
||||
cudaThreadsPerBlock = kernel_limit;
|
||||
DP("Threads per block capped at kernel limit %d\n", kernel_limit);
|
||||
}
|
||||
}
|
||||
|
||||
int cudaBlocksPerGrid;
|
||||
if (team_num <= 0) {
|
||||
if (loop_tripcount > 0 && DeviceInfo.EnvNumTeams < 0) {
|
||||
if (KernelInfo->ExecutionMode == SPMD) {
|
||||
// We have a combined construct, i.e. `target teams distribute parallel
|
||||
// for [simd]`. We launch so many teams so that each thread will
|
||||
// execute one iteration of the loop.
|
||||
// round up to the nearest integer
|
||||
cudaBlocksPerGrid = ((loop_tripcount - 1) / cudaThreadsPerBlock) + 1;
|
||||
} else {
|
||||
// If we reach this point, then we have a non-combined construct, i.e.
|
||||
// `teams distribute` with a nested `parallel for` and each team is
|
||||
// assigned one iteration of the `distribute` loop. E.g.:
|
||||
//
|
||||
// #pragma omp target teams distribute
|
||||
// for(...loop_tripcount...) {
|
||||
// #pragma omp parallel for
|
||||
// for(...) {}
|
||||
// }
|
||||
//
|
||||
// Threads within a team will execute the iterations of the `parallel`
|
||||
// loop.
|
||||
cudaBlocksPerGrid = loop_tripcount;
|
||||
}
|
||||
DP("Using %d teams due to loop trip count %" PRIu64 " and number of "
|
||||
"threads per block %d\n", cudaBlocksPerGrid, loop_tripcount,
|
||||
cudaThreadsPerBlock);
|
||||
} else {
|
||||
cudaBlocksPerGrid = DeviceInfo.NumTeams[device_id];
|
||||
DP("Using default number of teams %d\n", DeviceInfo.NumTeams[device_id]);
|
||||
}
|
||||
} else if (team_num > DeviceInfo.BlocksPerGrid[device_id]) {
|
||||
cudaBlocksPerGrid = DeviceInfo.BlocksPerGrid[device_id];
|
||||
DP("Capping number of teams to team limit %d\n",
|
||||
DeviceInfo.BlocksPerGrid[device_id]);
|
||||
} else {
|
||||
cudaBlocksPerGrid = team_num;
|
||||
DP("Using requested number of teams %d\n", team_num);
|
||||
}
|
||||
|
||||
// Run on the device.
|
||||
DP("Launch kernel with %d blocks and %d threads\n", cudaBlocksPerGrid,
|
||||
cudaThreadsPerBlock);
|
||||
|
||||
err = cuLaunchKernel(KernelInfo->Func, cudaBlocksPerGrid, 1, 1,
|
||||
cudaThreadsPerBlock, 1, 1, 0 /*bytes of shared memory*/, 0, &args[0], 0);
|
||||
if (err != CUDA_SUCCESS) {
|
||||
DP("Device kernel launch failed!\n");
|
||||
CUDA_ERR_STRING(err);
|
||||
assert(err == CUDA_SUCCESS && "Unable to launch target execution!");
|
||||
return OFFLOAD_FAIL;
|
||||
}
|
||||
|
||||
DP("Launch of entry point at " DPxMOD " successful!\n",
|
||||
DPxPTR(tgt_entry_ptr));
|
||||
|
||||
cudaError_t sync_error = cudaDeviceSynchronize();
|
||||
if (sync_error != cudaSuccess) {
|
||||
DP("Kernel execution error at " DPxMOD ", %s.\n", DPxPTR(tgt_entry_ptr),
|
||||
cudaGetErrorString(sync_error));
|
||||
return OFFLOAD_FAIL;
|
||||
} else {
|
||||
DP("Kernel execution at " DPxMOD " successful!\n", DPxPTR(tgt_entry_ptr));
|
||||
}
|
||||
|
||||
return OFFLOAD_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t __tgt_rtl_run_target_region(int32_t device_id, void *tgt_entry_ptr,
|
||||
void **tgt_args, ptrdiff_t *tgt_offsets, int32_t arg_num) {
|
||||
// use one team and the default number of threads.
|
||||
const int32_t team_num = 1;
|
||||
const int32_t thread_limit = 0;
|
||||
return __tgt_rtl_run_target_team_region(device_id, tgt_entry_ptr, tgt_args,
|
||||
tgt_offsets, arg_num, team_num, thread_limit, 0);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,15 @@
|
||||
VERS1.0 {
|
||||
global:
|
||||
__tgt_rtl_is_valid_binary;
|
||||
__tgt_rtl_number_of_devices;
|
||||
__tgt_rtl_init_device;
|
||||
__tgt_rtl_load_binary;
|
||||
__tgt_rtl_data_alloc;
|
||||
__tgt_rtl_data_submit;
|
||||
__tgt_rtl_data_retrieve;
|
||||
__tgt_rtl_data_delete;
|
||||
__tgt_rtl_run_target_team_region;
|
||||
__tgt_rtl_run_target_region;
|
||||
local:
|
||||
*;
|
||||
};
|
||||
@@ -0,0 +1,319 @@
|
||||
//===-RTLs/generic-64bit/src/rtl.cpp - Target RTLs Implementation - C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.txt for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// RTL for generic 64-bit machine
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <dlfcn.h>
|
||||
#include <ffi.h>
|
||||
#include <gelf.h>
|
||||
#include <link.h>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
#include "omptargetplugin.h"
|
||||
|
||||
#ifndef TARGET_NAME
|
||||
#define TARGET_NAME Generic ELF - 64bit
|
||||
#endif
|
||||
|
||||
#ifndef TARGET_ELF_ID
|
||||
#define TARGET_ELF_ID 0
|
||||
#endif
|
||||
|
||||
#define GETNAME2(name) #name
|
||||
#define GETNAME(name) GETNAME2(name)
|
||||
#define DP(...) DEBUGP("Target " GETNAME(TARGET_NAME) " RTL", __VA_ARGS__)
|
||||
|
||||
#include "../../common/elf_common.c"
|
||||
|
||||
#define NUMBER_OF_DEVICES 4
|
||||
#define OFFLOADSECTIONNAME ".omp_offloading.entries"
|
||||
|
||||
/// Array of Dynamic libraries loaded for this target.
|
||||
struct DynLibTy {
|
||||
char *FileName;
|
||||
void *Handle;
|
||||
};
|
||||
|
||||
/// Keep entries table per device.
|
||||
struct FuncOrGblEntryTy {
|
||||
__tgt_target_table Table;
|
||||
};
|
||||
|
||||
/// Class containing all the device information.
|
||||
class RTLDeviceInfoTy {
|
||||
std::vector<FuncOrGblEntryTy> FuncGblEntries;
|
||||
|
||||
public:
|
||||
std::list<DynLibTy> DynLibs;
|
||||
|
||||
// Record entry point associated with device.
|
||||
void createOffloadTable(int32_t device_id, __tgt_offload_entry *begin,
|
||||
__tgt_offload_entry *end) {
|
||||
assert(device_id < (int32_t)FuncGblEntries.size() &&
|
||||
"Unexpected device id!");
|
||||
FuncOrGblEntryTy &E = FuncGblEntries[device_id];
|
||||
|
||||
E.Table.EntriesBegin = begin;
|
||||
E.Table.EntriesEnd = end;
|
||||
}
|
||||
|
||||
// Return true if the entry is associated with device.
|
||||
bool findOffloadEntry(int32_t device_id, void *addr) {
|
||||
assert(device_id < (int32_t)FuncGblEntries.size() &&
|
||||
"Unexpected device id!");
|
||||
FuncOrGblEntryTy &E = FuncGblEntries[device_id];
|
||||
|
||||
for (__tgt_offload_entry *i = E.Table.EntriesBegin, *e = E.Table.EntriesEnd;
|
||||
i < e; ++i) {
|
||||
if (i->addr == addr)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return the pointer to the target entries table.
|
||||
__tgt_target_table *getOffloadEntriesTable(int32_t device_id) {
|
||||
assert(device_id < (int32_t)FuncGblEntries.size() &&
|
||||
"Unexpected device id!");
|
||||
FuncOrGblEntryTy &E = FuncGblEntries[device_id];
|
||||
|
||||
return &E.Table;
|
||||
}
|
||||
|
||||
RTLDeviceInfoTy(int32_t num_devices) { FuncGblEntries.resize(num_devices); }
|
||||
|
||||
~RTLDeviceInfoTy() {
|
||||
// Close dynamic libraries
|
||||
for (auto &lib : DynLibs) {
|
||||
if (lib.Handle) {
|
||||
dlclose(lib.Handle);
|
||||
remove(lib.FileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static RTLDeviceInfoTy DeviceInfo(NUMBER_OF_DEVICES);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int32_t __tgt_rtl_is_valid_binary(__tgt_device_image *image) {
|
||||
// If we don't have a valid ELF ID we can just fail.
|
||||
#if TARGET_ELF_ID < 1
|
||||
return 0;
|
||||
#else
|
||||
return elf_check_machine(image, TARGET_ELF_ID);
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t __tgt_rtl_number_of_devices() { return NUMBER_OF_DEVICES; }
|
||||
|
||||
int32_t __tgt_rtl_init_device(int32_t device_id) { return OFFLOAD_SUCCESS; }
|
||||
|
||||
__tgt_target_table *__tgt_rtl_load_binary(int32_t device_id,
|
||||
__tgt_device_image *image) {
|
||||
|
||||
DP("Dev %d: load binary from " DPxMOD " image\n", device_id,
|
||||
DPxPTR(image->ImageStart));
|
||||
|
||||
assert(device_id >= 0 && device_id < NUMBER_OF_DEVICES && "bad dev id");
|
||||
|
||||
size_t ImageSize = (size_t)image->ImageEnd - (size_t)image->ImageStart;
|
||||
size_t NumEntries = (size_t)(image->EntriesEnd - image->EntriesBegin);
|
||||
DP("Expecting to have %zd entries defined.\n", NumEntries);
|
||||
|
||||
// Is the library version incompatible with the header file?
|
||||
if (elf_version(EV_CURRENT) == EV_NONE) {
|
||||
DP("Incompatible ELF library!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Obtain elf handler
|
||||
Elf *e = elf_memory((char *)image->ImageStart, ImageSize);
|
||||
if (!e) {
|
||||
DP("Unable to get ELF handle: %s!\n", elf_errmsg(-1));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (elf_kind(e) != ELF_K_ELF) {
|
||||
DP("Invalid Elf kind!\n");
|
||||
elf_end(e);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Find the entries section offset
|
||||
Elf_Scn *section = 0;
|
||||
Elf64_Off entries_offset = 0;
|
||||
|
||||
size_t shstrndx;
|
||||
|
||||
if (elf_getshdrstrndx(e, &shstrndx)) {
|
||||
DP("Unable to get ELF strings index!\n");
|
||||
elf_end(e);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while ((section = elf_nextscn(e, section))) {
|
||||
GElf_Shdr hdr;
|
||||
gelf_getshdr(section, &hdr);
|
||||
|
||||
if (!strcmp(elf_strptr(e, shstrndx, hdr.sh_name), OFFLOADSECTIONNAME)) {
|
||||
entries_offset = hdr.sh_addr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!entries_offset) {
|
||||
DP("Entries Section Offset Not Found\n");
|
||||
elf_end(e);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DP("Offset of entries section is (" DPxMOD ").\n", DPxPTR(entries_offset));
|
||||
|
||||
// load dynamic library and get the entry points. We use the dl library
|
||||
// to do the loading of the library, but we could do it directly to avoid the
|
||||
// dump to the temporary file.
|
||||
//
|
||||
// 1) Create tmp file with the library contents.
|
||||
// 2) Use dlopen to load the file and dlsym to retrieve the symbols.
|
||||
char tmp_name[] = "/tmp/tmpfile_XXXXXX";
|
||||
int tmp_fd = mkstemp(tmp_name);
|
||||
|
||||
if (tmp_fd == -1) {
|
||||
elf_end(e);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FILE *ftmp = fdopen(tmp_fd, "wb");
|
||||
|
||||
if (!ftmp) {
|
||||
elf_end(e);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fwrite(image->ImageStart, ImageSize, 1, ftmp);
|
||||
fclose(ftmp);
|
||||
|
||||
DynLibTy Lib = {tmp_name, dlopen(tmp_name, RTLD_LAZY)};
|
||||
|
||||
if (!Lib.Handle) {
|
||||
DP("Target library loading error: %s\n", dlerror());
|
||||
elf_end(e);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DeviceInfo.DynLibs.push_back(Lib);
|
||||
|
||||
struct link_map *libInfo = (struct link_map *)Lib.Handle;
|
||||
|
||||
// The place where the entries info is loaded is the library base address
|
||||
// plus the offset determined from the ELF file.
|
||||
Elf64_Addr entries_addr = libInfo->l_addr + entries_offset;
|
||||
|
||||
DP("Pointer to first entry to be loaded is (" DPxMOD ").\n",
|
||||
DPxPTR(entries_addr));
|
||||
|
||||
// Table of pointers to all the entries in the target.
|
||||
__tgt_offload_entry *entries_table = (__tgt_offload_entry *)entries_addr;
|
||||
|
||||
__tgt_offload_entry *entries_begin = &entries_table[0];
|
||||
__tgt_offload_entry *entries_end = entries_begin + NumEntries;
|
||||
|
||||
if (!entries_begin) {
|
||||
DP("Can't obtain entries begin\n");
|
||||
elf_end(e);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DP("Entries table range is (" DPxMOD ")->(" DPxMOD ")\n",
|
||||
DPxPTR(entries_begin), DPxPTR(entries_end));
|
||||
DeviceInfo.createOffloadTable(device_id, entries_begin, entries_end);
|
||||
|
||||
elf_end(e);
|
||||
|
||||
return DeviceInfo.getOffloadEntriesTable(device_id);
|
||||
}
|
||||
|
||||
void *__tgt_rtl_data_alloc(int32_t device_id, int64_t size, void *hst_ptr) {
|
||||
void *ptr = malloc(size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
int32_t __tgt_rtl_data_submit(int32_t device_id, void *tgt_ptr, void *hst_ptr,
|
||||
int64_t size) {
|
||||
memcpy(tgt_ptr, hst_ptr, size);
|
||||
return OFFLOAD_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t __tgt_rtl_data_retrieve(int32_t device_id, void *hst_ptr, void *tgt_ptr,
|
||||
int64_t size) {
|
||||
memcpy(hst_ptr, tgt_ptr, size);
|
||||
return OFFLOAD_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t __tgt_rtl_data_delete(int32_t device_id, void *tgt_ptr) {
|
||||
free(tgt_ptr);
|
||||
return OFFLOAD_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t __tgt_rtl_run_target_team_region(int32_t device_id, void *tgt_entry_ptr,
|
||||
void **tgt_args, ptrdiff_t *tgt_offsets, int32_t arg_num, int32_t team_num,
|
||||
int32_t thread_limit, uint64_t loop_tripcount /*not used*/) {
|
||||
// ignore team num and thread limit.
|
||||
|
||||
// Use libffi to launch execution.
|
||||
ffi_cif cif;
|
||||
|
||||
// All args are references.
|
||||
std::vector<ffi_type *> args_types(arg_num, &ffi_type_pointer);
|
||||
std::vector<void *> args(arg_num);
|
||||
std::vector<void *> ptrs(arg_num);
|
||||
|
||||
for (int32_t i = 0; i < arg_num; ++i) {
|
||||
ptrs[i] = (void *)((intptr_t)tgt_args[i] + tgt_offsets[i]);
|
||||
args[i] = &ptrs[i];
|
||||
}
|
||||
|
||||
ffi_status status = ffi_prep_cif(&cif, FFI_DEFAULT_ABI, arg_num,
|
||||
&ffi_type_void, &args_types[0]);
|
||||
|
||||
assert(status == FFI_OK && "Unable to prepare target launch!");
|
||||
|
||||
if (status != FFI_OK)
|
||||
return OFFLOAD_FAIL;
|
||||
|
||||
DP("Running entry point at " DPxMOD "...\n", DPxPTR(tgt_entry_ptr));
|
||||
|
||||
void (*entry)(void);
|
||||
*((void**) &entry) = tgt_entry_ptr;
|
||||
ffi_call(&cif, entry, NULL, &args[0]);
|
||||
return OFFLOAD_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t __tgt_rtl_run_target_region(int32_t device_id, void *tgt_entry_ptr,
|
||||
void **tgt_args, ptrdiff_t *tgt_offsets, int32_t arg_num) {
|
||||
// use one team and one thread.
|
||||
return __tgt_rtl_run_target_team_region(device_id, tgt_entry_ptr, tgt_args,
|
||||
tgt_offsets, arg_num, 1, 1, 0);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,18 @@
|
||||
##===----------------------------------------------------------------------===##
|
||||
#
|
||||
# The LLVM Compiler Infrastructure
|
||||
#
|
||||
# This file is dual licensed under the MIT and the University of Illinois Open
|
||||
# Source Licenses. See LICENSE.txt for details.
|
||||
#
|
||||
##===----------------------------------------------------------------------===##
|
||||
#
|
||||
# Build a plugin for a ppc64 machine if available.
|
||||
#
|
||||
##===----------------------------------------------------------------------===##
|
||||
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
build_generic_elf64("ppc64" "PPC64" "ppc64" "powerpc64-ibm-linux-gnu" "21")
|
||||
else()
|
||||
libomptarget_say("Not building ppc64 offloading plugin: machine not found in the system.")
|
||||
endif()
|
||||
@@ -0,0 +1,18 @@
|
||||
##===----------------------------------------------------------------------===##
|
||||
#
|
||||
# The LLVM Compiler Infrastructure
|
||||
#
|
||||
# This file is dual licensed under the MIT and the University of Illinois Open
|
||||
# Source Licenses. See LICENSE.txt for details.
|
||||
#
|
||||
##===----------------------------------------------------------------------===##
|
||||
#
|
||||
# Build a plugin for a ppc64le machine if available.
|
||||
#
|
||||
##===----------------------------------------------------------------------===##
|
||||
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
build_generic_elf64("ppc64le" "PPC64le" "ppc64" "powerpc64le-ibm-linux-gnu" "21")
|
||||
else()
|
||||
libomptarget_say("Not building ppc64le offloading plugin: machine not found in the system.")
|
||||
endif()
|
||||
@@ -0,0 +1,18 @@
|
||||
##===----------------------------------------------------------------------===##
|
||||
#
|
||||
# The LLVM Compiler Infrastructure
|
||||
#
|
||||
# This file is dual licensed under the MIT and the University of Illinois Open
|
||||
# Source Licenses. See LICENSE.txt for details.
|
||||
#
|
||||
##===----------------------------------------------------------------------===##
|
||||
#
|
||||
# Build a plugin for a x86_64 machine if available.
|
||||
#
|
||||
##===----------------------------------------------------------------------===##
|
||||
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
build_generic_elf64("x86_64" "x86_64" "x86_64" "x86_64-pc-linux-gnu" "62")
|
||||
else()
|
||||
libomptarget_say("Not building x86_64 offloading plugin: machine not found in the system.")
|
||||
endif()
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,237 @@
|
||||
//===-------- omptarget.h - Target independent OpenMP target RTL -- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.txt for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Interface to be used by Clang during the codegen of a
|
||||
// target region.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _OMPTARGET_H_
|
||||
#define _OMPTARGET_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#define OFFLOAD_SUCCESS (0)
|
||||
#define OFFLOAD_FAIL (~0)
|
||||
|
||||
#define OFFLOAD_DEVICE_DEFAULT -1
|
||||
#define HOST_DEVICE -10
|
||||
|
||||
/// Data attributes for each data reference used in an OpenMP target region.
|
||||
enum tgt_map_type {
|
||||
// No flags
|
||||
OMP_TGT_MAPTYPE_NONE = 0x000,
|
||||
// copy data from host to device
|
||||
OMP_TGT_MAPTYPE_TO = 0x001,
|
||||
// copy data from device to host
|
||||
OMP_TGT_MAPTYPE_FROM = 0x002,
|
||||
// copy regardless of the reference count
|
||||
OMP_TGT_MAPTYPE_ALWAYS = 0x004,
|
||||
// force unmapping of data
|
||||
OMP_TGT_MAPTYPE_DELETE = 0x008,
|
||||
// map the pointer as well as the pointee
|
||||
OMP_TGT_MAPTYPE_PTR_AND_OBJ = 0x010,
|
||||
// pass device base address to kernel
|
||||
OMP_TGT_MAPTYPE_TARGET_PARAM = 0x020,
|
||||
// return base device address of mapped data
|
||||
OMP_TGT_MAPTYPE_RETURN_PARAM = 0x040,
|
||||
// private variable - not mapped
|
||||
OMP_TGT_MAPTYPE_PRIVATE = 0x080,
|
||||
// copy by value - not mapped
|
||||
OMP_TGT_MAPTYPE_LITERAL = 0x100,
|
||||
// mapping is implicit
|
||||
OMP_TGT_MAPTYPE_IMPLICIT = 0x200,
|
||||
// member of struct, member given by 4 MSBs - 1
|
||||
OMP_TGT_MAPTYPE_MEMBER_OF = 0xffff000000000000
|
||||
};
|
||||
|
||||
enum OpenMPOffloadingDeclareTargetFlags {
|
||||
/// Mark the entry as having a 'link' attribute.
|
||||
OMP_DECLARE_TARGET_LINK = 0x01,
|
||||
/// Mark the entry as being a global constructor.
|
||||
OMP_DECLARE_TARGET_CTOR = 0x02,
|
||||
/// Mark the entry as being a global destructor.
|
||||
OMP_DECLARE_TARGET_DTOR = 0x04
|
||||
};
|
||||
|
||||
/// This struct is a record of an entry point or global. For a function
|
||||
/// entry point the size is expected to be zero
|
||||
struct __tgt_offload_entry {
|
||||
void *addr; // Pointer to the offload entry info (function or global)
|
||||
char *name; // Name of the function or global
|
||||
size_t size; // Size of the entry info (0 if it is a function)
|
||||
int32_t flags; // Flags associated with the entry, e.g. 'link'.
|
||||
int32_t reserved; // Reserved, to be used by the runtime library.
|
||||
};
|
||||
|
||||
/// This struct is a record of the device image information
|
||||
struct __tgt_device_image {
|
||||
void *ImageStart; // Pointer to the target code start
|
||||
void *ImageEnd; // Pointer to the target code end
|
||||
__tgt_offload_entry *EntriesBegin; // Begin of table with all target entries
|
||||
__tgt_offload_entry *EntriesEnd; // End of table (non inclusive)
|
||||
};
|
||||
|
||||
/// This struct is a record of all the host code that may be offloaded to a
|
||||
/// target.
|
||||
struct __tgt_bin_desc {
|
||||
int32_t NumDeviceImages; // Number of device types supported
|
||||
__tgt_device_image *DeviceImages; // Array of device images (1 per dev. type)
|
||||
__tgt_offload_entry *HostEntriesBegin; // Begin of table with all host entries
|
||||
__tgt_offload_entry *HostEntriesEnd; // End of table (non inclusive)
|
||||
};
|
||||
|
||||
/// This struct contains the offload entries identified by the target runtime
|
||||
struct __tgt_target_table {
|
||||
__tgt_offload_entry *EntriesBegin; // Begin of the table with all the entries
|
||||
__tgt_offload_entry
|
||||
*EntriesEnd; // End of the table with all the entries (non inclusive)
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Implemented in libomp, they are called from within __tgt_* functions.
|
||||
int omp_get_default_device(void) __attribute__((weak));
|
||||
int32_t __kmpc_omp_taskwait(void *loc_ref, int32_t gtid) __attribute__((weak));
|
||||
|
||||
int omp_get_num_devices(void);
|
||||
int omp_get_initial_device(void);
|
||||
void *omp_target_alloc(size_t size, int device_num);
|
||||
void omp_target_free(void *device_ptr, int device_num);
|
||||
int omp_target_is_present(void *ptr, int device_num);
|
||||
int omp_target_memcpy(void *dst, void *src, size_t length, size_t dst_offset,
|
||||
size_t src_offset, int dst_device, int src_device);
|
||||
int omp_target_memcpy_rect(void *dst, void *src, size_t element_size,
|
||||
int num_dims, const size_t *volume, const size_t *dst_offsets,
|
||||
const size_t *src_offsets, const size_t *dst_dimensions,
|
||||
const size_t *src_dimensions, int dst_device, int src_device);
|
||||
int omp_target_associate_ptr(void *host_ptr, void *device_ptr, size_t size,
|
||||
size_t device_offset, int device_num);
|
||||
int omp_target_disassociate_ptr(void *host_ptr, int device_num);
|
||||
|
||||
/// adds a target shared library to the target execution image
|
||||
void __tgt_register_lib(__tgt_bin_desc *desc);
|
||||
|
||||
/// removes a target shared library from the target execution image
|
||||
void __tgt_unregister_lib(__tgt_bin_desc *desc);
|
||||
|
||||
// creates the host to target data mapping, stores it in the
|
||||
// libomptarget.so internal structure (an entry in a stack of data maps) and
|
||||
// passes the data to the device;
|
||||
void __tgt_target_data_begin(int32_t device_id, int32_t arg_num,
|
||||
void **args_base, void **args, int64_t *arg_sizes,
|
||||
int32_t *arg_types);
|
||||
void __tgt_target_data_begin_nowait(int32_t device_id, int32_t arg_num,
|
||||
void **args_base, void **args,
|
||||
int64_t *arg_sizes, int32_t *arg_types,
|
||||
int32_t depNum, void *depList,
|
||||
int32_t noAliasDepNum,
|
||||
void *noAliasDepList);
|
||||
|
||||
// passes data from the target, release target memory and destroys the
|
||||
// host-target mapping (top entry from the stack of data maps) created by
|
||||
// the last __tgt_target_data_begin
|
||||
void __tgt_target_data_end(int32_t device_id, int32_t arg_num, void **args_base,
|
||||
void **args, int64_t *arg_sizes, int32_t *arg_types);
|
||||
void __tgt_target_data_end_nowait(int32_t device_id, int32_t arg_num,
|
||||
void **args_base, void **args,
|
||||
int64_t *arg_sizes, int32_t *arg_types,
|
||||
int32_t depNum, void *depList,
|
||||
int32_t noAliasDepNum, void *noAliasDepList);
|
||||
|
||||
/// passes data to/from the target
|
||||
void __tgt_target_data_update(int32_t device_id, int32_t arg_num,
|
||||
void **args_base, void **args, int64_t *arg_sizes,
|
||||
int32_t *arg_types);
|
||||
void __tgt_target_data_update_nowait(int32_t device_id, int32_t arg_num,
|
||||
void **args_base, void **args,
|
||||
int64_t *arg_sizes, int32_t *arg_types,
|
||||
int32_t depNum, void *depList,
|
||||
int32_t noAliasDepNum,
|
||||
void *noAliasDepList);
|
||||
|
||||
// Performs the same actions as data_begin in case arg_num is non-zero
|
||||
// and initiates run of offloaded region on target platform; if arg_num
|
||||
// is non-zero after the region execution is done it also performs the
|
||||
// same action as data_end above. The following types are used; this
|
||||
// function returns 0 if it was able to transfer the execution to a
|
||||
// target and an int different from zero otherwise.
|
||||
int __tgt_target(int32_t device_id, void *host_ptr, int32_t arg_num,
|
||||
void **args_base, void **args, int64_t *arg_sizes,
|
||||
int32_t *arg_types);
|
||||
int __tgt_target_nowait(int32_t device_id, void *host_ptr, int32_t arg_num,
|
||||
void **args_base, void **args, int64_t *arg_sizes,
|
||||
int32_t *arg_types, int32_t depNum, void *depList,
|
||||
int32_t noAliasDepNum, void *noAliasDepList);
|
||||
|
||||
int __tgt_target_teams(int32_t device_id, void *host_ptr, int32_t arg_num,
|
||||
void **args_base, void **args, int64_t *arg_sizes,
|
||||
int32_t *arg_types, int32_t num_teams,
|
||||
int32_t thread_limit);
|
||||
int __tgt_target_teams_nowait(int32_t device_id, void *host_ptr,
|
||||
int32_t arg_num, void **args_base, void **args,
|
||||
int64_t *arg_sizes, int32_t *arg_types,
|
||||
int32_t num_teams, int32_t thread_limit,
|
||||
int32_t depNum, void *depList,
|
||||
int32_t noAliasDepNum, void *noAliasDepList);
|
||||
void __kmpc_push_target_tripcount(int32_t device_id, uint64_t loop_tripcount);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef OMPTARGET_DEBUG
|
||||
#include <stdio.h>
|
||||
#define DEBUGP(prefix, ...) \
|
||||
{ \
|
||||
fprintf(stderr, "%s --> ", prefix); \
|
||||
fprintf(stderr, __VA_ARGS__); \
|
||||
}
|
||||
|
||||
#ifndef __STDC_FORMAT_MACROS
|
||||
#define __STDC_FORMAT_MACROS
|
||||
#endif
|
||||
|
||||
#include <inttypes.h>
|
||||
#define DPxMOD "0x%0*" PRIxPTR
|
||||
#define DPxPTR(ptr) ((int)(2*sizeof(uintptr_t))), ((uintptr_t) (ptr))
|
||||
|
||||
/*
|
||||
* To printf a pointer in hex with a fixed width of 16 digits and a leading 0x,
|
||||
* use printf("ptr=" DPxMOD "...\n", DPxPTR(ptr));
|
||||
*
|
||||
* DPxMOD expands to:
|
||||
* "0x%0*" PRIxPTR
|
||||
* where PRIxPTR expands to an appropriate modifier for the type uintptr_t on a
|
||||
* specific platform, e.g. "lu" if uintptr_t is typedef'd as unsigned long:
|
||||
* "0x%0*lu"
|
||||
*
|
||||
* Ultimately, the whole statement expands to:
|
||||
* printf("ptr=0x%0*lu...\n", // the 0* modifier expects an extra argument
|
||||
* // specifying the width of the output
|
||||
* (int)(2*sizeof(uintptr_t)), // the extra argument specifying the width
|
||||
* // 8 digits for 32bit systems
|
||||
* // 16 digits for 64bit
|
||||
* (uintptr_t) ptr);
|
||||
*/
|
||||
#else
|
||||
#define DEBUGP(prefix, ...) \
|
||||
{}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN extern "C"
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
#endif // _OMPTARGET_H_
|
||||
@@ -0,0 +1,92 @@
|
||||
//===-- omptargetplugin.h - Target dependent OpenMP Plugin API --*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.txt for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines an interface between target independent OpenMP offload
|
||||
// runtime library libomptarget and target dependent plugin.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef _OMPTARGETPLUGIN_H_
|
||||
#define _OMPTARGETPLUGIN_H_
|
||||
|
||||
#include <omptarget.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Return the number of available devices of the type supported by the
|
||||
// target RTL.
|
||||
int32_t __tgt_rtl_number_of_devices(void);
|
||||
|
||||
// Return an integer different from zero if the provided device image can be
|
||||
// supported by the runtime. The functionality is similar to comparing the
|
||||
// result of __tgt__rtl__load__binary to NULL. However, this is meant to be a
|
||||
// lightweight query to determine if the RTL is suitable for an image without
|
||||
// having to load the library, which can be expensive.
|
||||
int32_t __tgt_rtl_is_valid_binary(__tgt_device_image *Image);
|
||||
|
||||
// Initialize the specified device. In case of success return 0; otherwise
|
||||
// return an error code.
|
||||
int32_t __tgt_rtl_init_device(int32_t ID);
|
||||
|
||||
// Pass an executable image section described by image to the specified
|
||||
// device and prepare an address table of target entities. In case of error,
|
||||
// return NULL. Otherwise, return a pointer to the built address table.
|
||||
// Individual entries in the table may also be NULL, when the corresponding
|
||||
// offload region is not supported on the target device.
|
||||
__tgt_target_table *__tgt_rtl_load_binary(int32_t ID,
|
||||
__tgt_device_image *Image);
|
||||
|
||||
// Allocate data on the particular target device, of the specified size.
|
||||
// HostPtr is a address of the host data the allocated target data
|
||||
// will be associated with (HostPtr may be NULL if it is not known at
|
||||
// allocation time, like for example it would be for target data that
|
||||
// is allocated by omp_target_alloc() API). Return address of the
|
||||
// allocated data on the target that will be used by libomptarget.so to
|
||||
// initialize the target data mapping structures. These addresses are
|
||||
// used to generate a table of target variables to pass to
|
||||
// __tgt_rtl_run_region(). The __tgt_rtl_data_alloc() returns NULL in
|
||||
// case an error occurred on the target device.
|
||||
void *__tgt_rtl_data_alloc(int32_t ID, int64_t Size, void *HostPtr);
|
||||
|
||||
// Pass the data content to the target device using the target address.
|
||||
// In case of success, return zero. Otherwise, return an error code.
|
||||
int32_t __tgt_rtl_data_submit(int32_t ID, void *TargetPtr, void *HostPtr,
|
||||
int64_t Size);
|
||||
|
||||
// Retrieve the data content from the target device using its address.
|
||||
// In case of success, return zero. Otherwise, return an error code.
|
||||
int32_t __tgt_rtl_data_retrieve(int32_t ID, void *HostPtr, void *TargetPtr,
|
||||
int64_t Size);
|
||||
|
||||
// De-allocate the data referenced by target ptr on the device. In case of
|
||||
// success, return zero. Otherwise, return an error code.
|
||||
int32_t __tgt_rtl_data_delete(int32_t ID, void *TargetPtr);
|
||||
|
||||
// Transfer control to the offloaded entry Entry on the target device.
|
||||
// Args and Offsets are arrays of NumArgs size of target addresses and
|
||||
// offsets. An offset should be added to the target address before passing it
|
||||
// to the outlined function on device side. In case of success, return zero.
|
||||
// Otherwise, return an error code.
|
||||
int32_t __tgt_rtl_run_target_region(int32_t ID, void *Entry, void **Args,
|
||||
ptrdiff_t *Offsets, int32_t NumArgs);
|
||||
|
||||
// Similar to __tgt_rtl_run_target_region, but additionally specify the
|
||||
// number of teams to be created and a number of threads in each team.
|
||||
int32_t __tgt_rtl_run_target_team_region(int32_t ID, void *Entry, void **Args,
|
||||
ptrdiff_t *Offsets, int32_t NumArgs,
|
||||
int32_t NumTeams, int32_t ThreadLimit,
|
||||
uint64_t loop_tripcount);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _OMPTARGETPLUGIN_H_
|
||||
@@ -0,0 +1,92 @@
|
||||
# CMakeLists.txt file for unit testing OpenMP Library
|
||||
include(FindPythonInterp)
|
||||
include(CheckTypeSize)
|
||||
if(NOT PYTHONINTERP_FOUND)
|
||||
libomptarget_warning_say("Could not find Python.")
|
||||
libomptarget_warning_say("The check-libomptarget target will not be available!")
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(LIBOMPTARGET_TEST_CFLAGS "" CACHE STRING
|
||||
"Extra compiler flags to send to the test compiler")
|
||||
|
||||
if(${LIBOMPTARGET_STANDALONE_BUILD})
|
||||
# Make sure we can use the console pool for recent cmake and ninja > 1.5
|
||||
if(CMAKE_VERSION VERSION_LESS 3.1.20141117)
|
||||
set(cmake_3_2_USES_TERMINAL)
|
||||
else()
|
||||
set(cmake_3_2_USES_TERMINAL USES_TERMINAL)
|
||||
endif()
|
||||
set(LIBOMPTARGET_TEST_C_COMPILER ${CMAKE_C_COMPILER} CACHE STRING
|
||||
"C compiler to use for testing OpenMP offloading library")
|
||||
set(LIBOMPTARGET_TEST_CXX_COMPILER ${CMAKE_CXX_COMPILER} CACHE STRING
|
||||
"C++ compiler to use for testing OpenMP offloading library")
|
||||
set(LIBOMPTARGET_TEST_OPENMP_FLAG -fopenmp CACHE STRING
|
||||
"OpenMP compiler flag to use for testing OpenMP offloading library")
|
||||
find_program(LIBOMPTARGET_LLVM_LIT_EXECUTABLE
|
||||
NAMES llvm-lit lit.py lit
|
||||
PATHS ${OPENMP_LLVM_TOOLS_DIR})
|
||||
if(NOT LIBOMPTARGET_LLVM_LIT_EXECUTABLE)
|
||||
libomptarget_say("Cannot find llvm-lit.")
|
||||
libomptarget_say("Please put llvm-lit in your PATH or set LIBOMPTARGET_LLVM_LIT_EXECUTABLE to its full path or point OPENMP_LLVM_TOOLS_DIR to its directory")
|
||||
libomptarget_warning_say("The check-libomptarget target will not be available!")
|
||||
return()
|
||||
endif()
|
||||
|
||||
find_program(LIBOMPTARGET_FILECHECK_EXECUTABLE
|
||||
NAMES FileCheck
|
||||
PATHS ${OPENMP_LLVM_TOOLS_DIR})
|
||||
if(NOT LIBOMPTARGET_FILECHECK_EXECUTABLE)
|
||||
libomptarget_say("Cannot find FileCheck.")
|
||||
libomptarget_say("Please put FileCheck in your PATH or set LIBOMPTARGET_FILECHECK_EXECUTABLE to its full path or point OPENMP_LLVM_TOOLS_DIR to its directory")
|
||||
libomptarget_warning_say("The check-libomptarget target will not be available!")
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Set lit arguments
|
||||
# The -j 1 lets the actual tests run with the entire machine.
|
||||
# We have one test thread that spawns the tests serially. This allows
|
||||
# Each test to use the entire machine.
|
||||
set(LIBOMPTARGET_LIT_ARGS_DEFAULT "-sv --show-unsupported --show-xfail -j 1")
|
||||
if(MSVC OR XCODE)
|
||||
set(LIBOMPTARGET_LIT_ARGS_DEFAULT "${LIBOMPTARGET_LIT_ARGS_DEFAULT} --no-progress-bar")
|
||||
endif()
|
||||
set(LIBOMPTARGET_LIT_ARGS "${LIBOMPTARGET_LIT_ARGS_DEFAULT}" CACHE STRING
|
||||
"Default options for lit")
|
||||
separate_arguments(LIBOMPTARGET_LIT_ARGS)
|
||||
add_custom_target(check-libomptarget
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${LIBOMPTARGET_LLVM_LIT_EXECUTABLE} ${LIBOMPTARGET_LIT_ARGS} ${CMAKE_CURRENT_BINARY_DIR}
|
||||
DEPENDS omptarget
|
||||
COMMENT "Running libomptarget tests"
|
||||
${cmake_3_2_USES_TERMINAL}
|
||||
)
|
||||
|
||||
set(LIBOMPTARGET_OPENMP_HEADER_FOLDER "${CMAKE_CURRENT_BINARY_DIR}/../../runtime/src" CACHE STRING
|
||||
"Path to folder containing omp.h")
|
||||
set(LIBOMPTARGET_OPENMP_HOST_RTL_FOLDER "${CMAKE_CURRENT_BINARY_DIR}/../../runtime/src" CACHE STRING
|
||||
"Path to folder containing libomp.so")
|
||||
else()
|
||||
# LLVM source tree build, test just-built clang
|
||||
if(NOT MSVC)
|
||||
set(LIBOMPTARGET_TEST_C_COMPILER ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang)
|
||||
set(LIBOMPTARGET_TEST_CXX_COMPILER ${LLVM_RUNTIME_OUTPUT_INTDIR}/clang++)
|
||||
set(LIBOMPTARGET_FILECHECK_EXECUTABLE ${LLVM_RUNTIME_OUTPUT_INTDIR}/FileCheck)
|
||||
else()
|
||||
libomptarget_warning_say("Not prepared to run tests on Windows systems.")
|
||||
endif()
|
||||
set(LIBOMPTARGET_TEST_OPENMP_FLAG -fopenmp=libomp)
|
||||
# Use add_lit_testsuite() from LLVM CMake. This also depends on OpenMP
|
||||
# implementation because it uses omp.h.
|
||||
add_lit_testsuite(check-libomptarget
|
||||
"Running libomptarget tests"
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
DEPENDS omptarget omp
|
||||
)
|
||||
|
||||
set(LIBOMPTARGET_OPENMP_HEADER_FOLDER "${LIBOMPTARGET_BINARY_DIR}/../runtime/src")
|
||||
endif()
|
||||
|
||||
# Configure the lit.site.cfg.in file
|
||||
set(AUTO_GEN_COMMENT "## Autogenerated by libomptarget configuration.\n# Do not edit!")
|
||||
configure_file(lit.site.cfg.in lit.site.cfg @ONLY)
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
# -*- Python -*- vim: set ft=python ts=4 sw=4 expandtab tw=79:
|
||||
# Configuration file for the 'lit' test runner.
|
||||
|
||||
import os
|
||||
import lit.formats
|
||||
|
||||
# Tell pylint that we know config and lit_config exist somewhere.
|
||||
if 'PYLINT_IMPORT' in os.environ:
|
||||
config = object()
|
||||
lit_config = object()
|
||||
|
||||
def append_dynamic_library_path(name, value, sep):
|
||||
if name in config.environment:
|
||||
config.environment[name] = value + sep + config.environment[name]
|
||||
else:
|
||||
config.environment[name] = value
|
||||
|
||||
# name: The name of this test suite.
|
||||
config.name = 'libomptarget'
|
||||
|
||||
# suffixes: A list of file extensions to treat as test files.
|
||||
config.suffixes = ['.c', '.cpp', '.cc']
|
||||
|
||||
# test_source_root: The root path where tests are located.
|
||||
config.test_source_root = os.path.dirname(__file__)
|
||||
|
||||
# test_exec_root: The root object directory where output is placed
|
||||
config.test_exec_root = config.libomptarget_obj_root
|
||||
|
||||
# test format
|
||||
config.test_format = lit.formats.ShTest()
|
||||
|
||||
# compiler flags
|
||||
config.test_cflags = config.test_openmp_flag + \
|
||||
" -I " + config.test_source_root + \
|
||||
" -I " + config.omp_header_directory + \
|
||||
" -L " + config.library_dir;
|
||||
|
||||
if config.omp_host_rtl_directory:
|
||||
config.test_cflags = config.test_cflags + " -L " + \
|
||||
config.omp_host_rtl_directory
|
||||
|
||||
config.test_cflags = config.test_cflags + " " + config.test_extra_cflags
|
||||
|
||||
# Setup environment to find dynamic library at runtime
|
||||
if config.operating_system == 'Windows':
|
||||
append_dynamic_library_path('PATH', config.library_dir, ";")
|
||||
append_dynamic_library_path('PATH', config.omp_host_rtl_directory, ";")
|
||||
elif config.operating_system == 'Darwin':
|
||||
append_dynamic_library_path('DYLD_LIBRARY_PATH', config.library_dir, ":")
|
||||
append_dynamic_library_path('DYLD_LIBRARY_PATH', \
|
||||
config.omp_host_rtl_directory, ";")
|
||||
config.test_cflags += " -Wl,-rpath," + config.library_dir
|
||||
config.test_cflags += " -Wl,-rpath," + config.omp_host_rtl_directory
|
||||
else: # Unices
|
||||
append_dynamic_library_path('LD_LIBRARY_PATH', config.library_dir, ":")
|
||||
append_dynamic_library_path('LD_LIBRARY_PATH', \
|
||||
config.omp_host_rtl_directory, ":")
|
||||
|
||||
# substitutions
|
||||
# - for targets that exist in the system create the actual command.
|
||||
# - for valid targets that do not exist in the system, return false, so that the
|
||||
# same test can be used for different targets.
|
||||
|
||||
# Scan all the valid targets.
|
||||
for libomptarget_target in config.libomptarget_all_targets:
|
||||
# Is this target in the current system? If so create a compile, run and test
|
||||
# command. Otherwise create command that return false.
|
||||
if libomptarget_target in config.libomptarget_system_targets:
|
||||
config.substitutions.append(("%libomptarget-compilexx-run-and-check-" + \
|
||||
libomptarget_target, \
|
||||
"%libomptarget-compilexx-and-run-" + libomptarget_target + \
|
||||
" | " + config.libomptarget_filecheck + " %s"))
|
||||
config.substitutions.append(("%libomptarget-compile-run-and-check-" + \
|
||||
libomptarget_target, \
|
||||
"%libomptarget-compile-and-run-" + libomptarget_target + \
|
||||
" | " + config.libomptarget_filecheck + " %s"))
|
||||
config.substitutions.append(("%libomptarget-compilexx-and-run-" + \
|
||||
libomptarget_target, \
|
||||
"%clangxx-" + libomptarget_target + " %s -o %t-" + \
|
||||
libomptarget_target + " && %t-" + libomptarget_target))
|
||||
config.substitutions.append(("%libomptarget-compile-and-run-" + \
|
||||
libomptarget_target, \
|
||||
"%clang-" + libomptarget_target + " %s -o %t-" + \
|
||||
libomptarget_target + " && %t-" + libomptarget_target))
|
||||
config.substitutions.append(("%clangxx-" + libomptarget_target, \
|
||||
"%clangxx %cflags -fopenmp-targets=" + libomptarget_target))
|
||||
config.substitutions.append(("%clang-" + libomptarget_target, \
|
||||
"%clang %cflags -fopenmp-targets=" + libomptarget_target))
|
||||
config.substitutions.append(("%fcheck-" + libomptarget_target, \
|
||||
config.libomptarget_filecheck + " %s"))
|
||||
else:
|
||||
config.substitutions.append(("%libomptarget-compile-run-and-check-" + \
|
||||
libomptarget_target, \
|
||||
"echo ignored-command"))
|
||||
config.substitutions.append(("%libomptarget-compilexx-run-and-check-" + \
|
||||
libomptarget_target, \
|
||||
"echo ignored-command"))
|
||||
config.substitutions.append(("%libomptarget-compile-and-run-" + \
|
||||
libomptarget_target, \
|
||||
"echo ignored-command"))
|
||||
config.substitutions.append(("%libomptarget-compilexx-and-run-" + \
|
||||
libomptarget_target, \
|
||||
"echo ignored-command"))
|
||||
config.substitutions.append(("%clang-" + libomptarget_target, \
|
||||
"echo ignored-command"))
|
||||
config.substitutions.append(("%clangxx-" + libomptarget_target, \
|
||||
"echo ignored-command"))
|
||||
config.substitutions.append(("%fcheck-" + libomptarget_target, \
|
||||
"echo ignored-command"))
|
||||
|
||||
config.substitutions.append(("%clangxx", config.test_cxx_compiler))
|
||||
config.substitutions.append(("%clang", config.test_c_compiler))
|
||||
config.substitutions.append(("%openmp_flag", config.test_openmp_flag))
|
||||
config.substitutions.append(("%cflags", config.test_cflags))
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
@AUTO_GEN_COMMENT@
|
||||
|
||||
config.test_c_compiler = "@LIBOMPTARGET_TEST_C_COMPILER@"
|
||||
config.test_cxx_compiler = "@LIBOMPTARGET_TEST_CXX_COMPILER@"
|
||||
config.test_openmp_flag = "@LIBOMPTARGET_TEST_OPENMP_FLAG@"
|
||||
# For the moment we still need to pass libomptarget explicitly. Once the driver
|
||||
# patch, lands, this is not required anymore.
|
||||
config.test_extra_cflags = "-lomptarget @LIBOMPTARGET_TEST_CFLAGS@"
|
||||
config.libomptarget_obj_root = "@CMAKE_CURRENT_BINARY_DIR@"
|
||||
config.library_dir = "@LIBOMPTARGET_LIBRARY_DIR@"
|
||||
config.omp_header_directory = "@LIBOMPTARGET_OPENMP_HEADER_FOLDER@"
|
||||
config.omp_host_rtl_directory = "@LIBOMPTARGET_OPENMP_HOST_RTL_FOLDER@"
|
||||
config.operating_system = "@CMAKE_SYSTEM_NAME@"
|
||||
config.libomptarget_all_targets = "@LIBOMPTARGET_ALL_TARGETS@".split()
|
||||
config.libomptarget_system_targets = "@LIBOMPTARGET_SYSTEM_TARGETS@".split()
|
||||
config.libomptarget_filecheck = "@LIBOMPTARGET_FILECHECK_EXECUTABLE@"
|
||||
|
||||
# Let the main config do the real work.
|
||||
lit_config.load_config(config, "@LIBOMPTARGET_BASE_DIR@/test/lit.cfg")
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
// RUN: %libomptarget-compile-run-and-check-aarch64-unknown-linux-gnu
|
||||
// RUN: %libomptarget-compile-run-and-check-powerpc64-ibm-linux-gnu
|
||||
// RUN: %libomptarget-compile-run-and-check-powerpc64le-ibm-linux-gnu
|
||||
// RUN: %libomptarget-compile-run-and-check-x86_64-pc-linux-gnu
|
||||
|
||||
#include <stdio.h>
|
||||
#include <omp.h>
|
||||
|
||||
int main(void) {
|
||||
int isHost = -1;
|
||||
|
||||
#pragma omp target map(from: isHost)
|
||||
{ isHost = omp_is_initial_device(); }
|
||||
|
||||
if (isHost < 0) {
|
||||
printf("Runtime error, isHost=%d\n", isHost);
|
||||
}
|
||||
|
||||
// CHECK: Target region executed on the device
|
||||
printf("Target region executed on the %s\n", isHost ? "host" : "device");
|
||||
|
||||
return isHost;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
// RUN: %libomptarget-compilexx-run-and-check-aarch64-unknown-linux-gnu
|
||||
// RUN: %libomptarget-compilexx-run-and-check-powerpc64-ibm-linux-gnu
|
||||
// RUN: %libomptarget-compilexx-run-and-check-powerpc64le-ibm-linux-gnu
|
||||
// RUN: %libomptarget-compilexx-run-and-check-x86_64-pc-linux-gnu
|
||||
|
||||
#include <stdio.h>
|
||||
#include <omp.h>
|
||||
|
||||
int main(void) {
|
||||
int isHost = 0;
|
||||
|
||||
#pragma omp target map(from: isHost)
|
||||
{ isHost = omp_is_initial_device(); }
|
||||
|
||||
if (isHost < 0) {
|
||||
printf("Runtime error, isHost=%d\n", isHost);
|
||||
}
|
||||
|
||||
// CHECK: Target region executed on the device
|
||||
printf("Target region executed on the %s\n", isHost ? "host" : "device");
|
||||
|
||||
return isHost;
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
---
|
||||
BasedOnStyle: LLVM
|
||||
AlignTrailingComments: false
|
||||
SortIncludes: false
|
||||
---
|
||||
# Language: Cpp
|
||||
# AccessModifierOffset: -2
|
||||
# AlignAfterOpenBracket: Align
|
||||
# AlignConsecutiveAssignments: false
|
||||
# AlignConsecutiveDeclarations: false
|
||||
# AlignEscapedNewlinesLeft: false
|
||||
# AlignOperands: false
|
||||
# AlignTrailingComments: false
|
||||
# AllowAllParametersOfDeclarationOnNextLine: true
|
||||
# AllowShortBlocksOnASingleLine: false
|
||||
# AllowShortCaseLabelsOnASingleLine: false
|
||||
# AllowShortFunctionsOnASingleLine: All
|
||||
# AllowShortIfStatementsOnASingleLine: false
|
||||
# AllowShortLoopsOnASingleLine: false
|
||||
# AlwaysBreakAfterDefinitionReturnType: None
|
||||
# AlwaysBreakAfterReturnType: None
|
||||
# AlwaysBreakBeforeMultilineStrings: false
|
||||
# AlwaysBreakTemplateDeclarations: false
|
||||
# BinPackArguments: true
|
||||
# BinPackParameters: true
|
||||
# BraceWrapping:
|
||||
# AfterClass: false
|
||||
# AfterControlStatement: false
|
||||
# AfterEnum: false
|
||||
# AfterFunction: false
|
||||
# AfterNamespace: false
|
||||
# AfterObjCDeclaration: false
|
||||
# AfterStruct: false
|
||||
# AfterUnion: false
|
||||
# BeforeCatch: false
|
||||
# BeforeElse: false
|
||||
# IndentBraces: false
|
||||
# # BreakBeforeBinaryOperators: None
|
||||
# BreakBeforeBraces: Attach
|
||||
# BreakBeforeTernaryOperators: true
|
||||
# BreakConstructorInitializersBeforeComma: false
|
||||
# ColumnLimit: 80
|
||||
# CommentPragmas: '^ IWYU pragma:'
|
||||
# ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
# ConstructorInitializerIndentWidth: 4
|
||||
# ContinuationIndentWidth: 4
|
||||
# Cpp11BracedListStyle: true
|
||||
# DerivePointerAlignment: false
|
||||
# DisableFormat: true
|
||||
# ExperimentalAutoDetectBinPacking: false
|
||||
# ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
|
||||
# IncludeCategories:
|
||||
# - Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||
# Priority: 2
|
||||
# - Regex: '^(<|"(gtest|isl|json)/)'
|
||||
# Priority: 3
|
||||
# - Regex: '.*'
|
||||
# Priority: 1
|
||||
# IndentCaseLabels: false
|
||||
# IndentWidth: 2
|
||||
# IndentWrappedFunctionNames: false
|
||||
# KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
# MacroBlockBegin: ''
|
||||
# MacroBlockEnd: ''
|
||||
# MaxEmptyLinesToKeep: 2
|
||||
# NamespaceIndentation: None
|
||||
# ObjCBlockIndentWidth: 2
|
||||
# ObjCSpaceAfterProperty: false
|
||||
# ObjCSpaceBeforeProtocolList: true
|
||||
# PenaltyBreakBeforeFirstCallParameter: 19
|
||||
# PenaltyBreakComment: 300
|
||||
# PenaltyBreakFirstLessLess: 120
|
||||
# PenaltyBreakString: 1000
|
||||
# PenaltyExcessCharacter: 1000000
|
||||
# PenaltyReturnTypeOnItsOwnLine: 60
|
||||
# PointerAlignment: Right
|
||||
# ReflowComments: true
|
||||
# SpaceAfterCStyleCast: false
|
||||
# SpaceBeforeAssignmentOperators: true
|
||||
# SpaceBeforeParens: ControlStatements
|
||||
# SpaceInEmptyParentheses: false
|
||||
# SpacesBeforeTrailingComments: 1
|
||||
# SpacesInAngles: false
|
||||
# SpacesInContainerLiterals: true
|
||||
# SpacesInCStyleCastParentheses: false
|
||||
# SpacesInParentheses: false
|
||||
# SpacesInSquareBrackets: false
|
||||
# Standard: Cpp11
|
||||
# TabWidth: 8
|
||||
# UseTab: Never
|
||||
...
|
||||
@@ -116,8 +116,8 @@ Library type can be normal, profile, or stubs.
|
||||
-DCMAKE_BUILD_TYPE=Release|Debug|RelWithDebInfo
|
||||
Build type can be Release, Debug, or RelWithDebInfo.
|
||||
|
||||
-DLIBOMP_OMP_VERSION=45|40|30
|
||||
OpenMP version can be either 45, 40 or 30.
|
||||
-DLIBOMP_OMP_VERSION=50|45|40|30
|
||||
OpenMP version can be either 50, 45, 40 or 30.
|
||||
|
||||
-DLIBOMP_MIC_ARCH=knc|knf
|
||||
This value is ignored if LIBOMP_ARCH != mic
|
||||
|
||||
+11
-8
@@ -89,15 +89,13 @@ libomp_check_variable(LIBOMP_ARCH 32e x86_64 32 i386 arm ppc64 ppc64le aarch64 m
|
||||
set(LIBOMP_LIB_TYPE normal CACHE STRING
|
||||
"Performance,Profiling,Stubs library (normal/profile/stubs)")
|
||||
libomp_check_variable(LIBOMP_LIB_TYPE normal profile stubs)
|
||||
set(LIBOMP_OMP_VERSION 45 CACHE STRING
|
||||
"The OpenMP version (45/40/30)")
|
||||
if(LIBOMP_OMP_VERSION EQUAL 41)
|
||||
libomp_warning_say("LIBOMP_OMP_VERSION=41 is deprecated and will be removed in a later version. Please use 45.")
|
||||
set(LIBOMP_OMP_VERSION 45)
|
||||
endif()
|
||||
libomp_check_variable(LIBOMP_OMP_VERSION 45 40 30)
|
||||
set(LIBOMP_OMP_VERSION 50 CACHE STRING
|
||||
"The OpenMP version (50/45/40/30)")
|
||||
libomp_check_variable(LIBOMP_OMP_VERSION 50 45 40 30)
|
||||
# Set the OpenMP Year and Month assiociated with version
|
||||
if(${LIBOMP_OMP_VERSION} GREATER 45 OR ${LIBOMP_OMP_VERSION} EQUAL 45)
|
||||
if(${LIBOMP_OMP_VERSION} GREATER 50 OR ${LIBOMP_OMP_VERSION} EQUAL 50)
|
||||
set(LIBOMP_OMP_YEAR_MONTH 201611)
|
||||
elseif(${LIBOMP_OMP_VERSION} GREATER 45 OR ${LIBOMP_OMP_VERSION} EQUAL 45)
|
||||
set(LIBOMP_OMP_YEAR_MONTH 201511)
|
||||
elseif(${LIBOMP_OMP_VERSION} GREATER 40 OR ${LIBOMP_OMP_VERSION} EQUAL 40)
|
||||
set(LIBOMP_OMP_YEAR_MONTH 201307)
|
||||
@@ -309,6 +307,11 @@ if(WIN32 AND NOT LIBOMP_ENABLE_SHARED)
|
||||
libomp_error_say("Static libraries requested but not available on Windows")
|
||||
endif()
|
||||
|
||||
if(LIBOMP_USE_ITT_NOTIFY AND NOT LIBOMP_ENABLE_SHARED)
|
||||
message(STATUS "ITT Notify not supported for static libraries - forcing ITT Notify off")
|
||||
set(LIBOMP_USE_ITT_NOTIFY FALSE)
|
||||
endif()
|
||||
|
||||
# OMPT-support
|
||||
set(LIBOMP_OMPT_DEBUG FALSE CACHE BOOL
|
||||
"Trace OMPT initialization?")
|
||||
|
||||
@@ -192,6 +192,9 @@ function(libomp_get_gdflags gdflags)
|
||||
libomp_append(gdflags_local "-D stub" STUBS_LIBRARY)
|
||||
libomp_append(gdflags_local "-D HAVE_QUAD" LIBOMP_USE_QUAD_PRECISION)
|
||||
libomp_append(gdflags_local "-D USE_DEBUGGER" LIBOMP_USE_DEBUGGER)
|
||||
if(${LIBOMP_OMP_VERSION} GREATER 50 OR ${LIBOMP_OMP_VERSION} EQUAL 50)
|
||||
libomp_append(gdflags_local "-D OMP_50")
|
||||
endif()
|
||||
if(${LIBOMP_OMP_VERSION} GREATER 45 OR ${LIBOMP_OMP_VERSION} EQUAL 45)
|
||||
libomp_append(gdflags_local "-D OMP_45")
|
||||
endif()
|
||||
|
||||
@@ -93,7 +93,7 @@ else()
|
||||
# Unix specific files
|
||||
libomp_append(LIBOMP_CXXFILES z_Linux_util.cpp)
|
||||
libomp_append(LIBOMP_CXXFILES kmp_gsupport.cpp)
|
||||
libomp_append(LIBOMP_ASMFILES z_Linux_asm.s) # Unix assembly file
|
||||
libomp_append(LIBOMP_ASMFILES z_Linux_asm.S) # Unix assembly file
|
||||
endif()
|
||||
libomp_append(LIBOMP_CFILES thirdparty/ittnotify/ittnotify_static.c LIBOMP_USE_ITT_NOTIFY)
|
||||
libomp_append(LIBOMP_CXXFILES kmp_debugger.cpp LIBOMP_USE_DEBUGGER)
|
||||
|
||||
+14
-1
@@ -351,7 +351,7 @@ kmpc_set_defaults 224
|
||||
%ifdef OMP_30
|
||||
__kmpc_omp_taskyield 235
|
||||
%endif # OMP_30
|
||||
__kmpc_place_threads 236
|
||||
# __kmpc_place_threads 236
|
||||
%endif
|
||||
|
||||
# OpenMP 4.0 entry points
|
||||
@@ -397,6 +397,15 @@ kmpc_set_defaults 224
|
||||
kmpc_aligned_malloc 265
|
||||
kmpc_set_disp_num_buffers 267
|
||||
|
||||
# OpenMP 5.0 entry points
|
||||
# TODO: change to OMP_50 once it is implemented
|
||||
%ifndef stub
|
||||
%ifdef OMP_45
|
||||
__kmpc_task_reduction_init 268
|
||||
__kmpc_task_reduction_get_th_data 269
|
||||
%endif
|
||||
%endif
|
||||
|
||||
# User API entry points that have both lower- and upper- case versions for Fortran.
|
||||
# Number for lowercase version is indicated. Number for uppercase is obtained by adding 1000.
|
||||
# User API entry points are entry points that start with 'kmp_' or 'omp_'.
|
||||
@@ -1108,15 +1117,19 @@ kmp_set_disp_num_buffers 890
|
||||
|
||||
%ifdef HAVE_QUAD
|
||||
__kmpc_atomic_fixed1_sub_rev_fp
|
||||
__kmpc_atomic_fixed1u_sub_rev_fp
|
||||
__kmpc_atomic_fixed1_div_rev_fp
|
||||
__kmpc_atomic_fixed1u_div_rev_fp
|
||||
__kmpc_atomic_fixed2_sub_rev_fp
|
||||
__kmpc_atomic_fixed2u_sub_rev_fp
|
||||
__kmpc_atomic_fixed2_div_rev_fp
|
||||
__kmpc_atomic_fixed2u_div_rev_fp
|
||||
__kmpc_atomic_fixed4_sub_rev_fp
|
||||
__kmpc_atomic_fixed4u_sub_rev_fp
|
||||
__kmpc_atomic_fixed4_div_rev_fp
|
||||
__kmpc_atomic_fixed4u_div_rev_fp
|
||||
__kmpc_atomic_fixed8_sub_rev_fp
|
||||
__kmpc_atomic_fixed8u_sub_rev_fp
|
||||
__kmpc_atomic_fixed8_div_rev_fp
|
||||
__kmpc_atomic_fixed8u_div_rev_fp
|
||||
__kmpc_atomic_float4_sub_rev_fp
|
||||
|
||||
@@ -84,10 +84,7 @@ VERSION {
|
||||
__kmp_acquire_tas_lock;
|
||||
__kmp_acquire_ticket_lock;
|
||||
__kmp_fork_call;
|
||||
__kmp_get_reduce_method;
|
||||
__kmp_invoke_microtask;
|
||||
__kmp_itt_fini_ittlib;
|
||||
__kmp_itt_init_ittlib;
|
||||
#if KMP_USE_MONITOR
|
||||
__kmp_launch_monitor;
|
||||
__kmp_reap_monitor;
|
||||
|
||||
+390
-401
@@ -13,13 +13,13 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
#include <strstream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
#include <strstream>
|
||||
|
||||
/* Given a set of n object files h ('external' object files) and a set of m
|
||||
object files o ('internal' object files),
|
||||
@@ -30,468 +30,457 @@
|
||||
Usage:
|
||||
hide.exe <n> <filenames for h> <filenames for o>
|
||||
|
||||
Thus, the prefixed symbols become hidden in the sense that they now have a special
|
||||
prefix.
|
||||
Thus, the prefixed symbols become hidden in the sense that they now have a
|
||||
special prefix.
|
||||
*/
|
||||
|
||||
using namespace std;
|
||||
|
||||
void stop(char* errorMsg) {
|
||||
printf("%s\n", errorMsg);
|
||||
exit(1);
|
||||
void stop(char *errorMsg) {
|
||||
printf("%s\n", errorMsg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// an entry in the symbol table of a .OBJ file
|
||||
class Symbol {
|
||||
public:
|
||||
__int64 name;
|
||||
unsigned value;
|
||||
unsigned short sectionNum, type;
|
||||
char storageClass, nAux;
|
||||
__int64 name;
|
||||
unsigned value;
|
||||
unsigned short sectionNum, type;
|
||||
char storageClass, nAux;
|
||||
};
|
||||
|
||||
class _rstream : public istrstream {
|
||||
private:
|
||||
const char *buf;
|
||||
const char *buf;
|
||||
|
||||
protected:
|
||||
_rstream(pair<const char*, streamsize> p):istrstream(p.first,p.second),buf(p.first){}
|
||||
~_rstream() {
|
||||
delete[]buf;
|
||||
}
|
||||
_rstream(pair<const char *, streamsize> p)
|
||||
: istrstream(p.first, p.second), buf(p.first) {}
|
||||
~_rstream() { delete[] buf; }
|
||||
};
|
||||
|
||||
/* A stream encapuslating the content of a file or the content of a string, overriding the
|
||||
>> operator to read various integer types in binary form, as well as a symbol table
|
||||
entry.
|
||||
*/
|
||||
// A stream encapuslating the content of a file or the content of a string,
|
||||
// overriding the >> operator to read various integer types in binary form,
|
||||
// as well as a symbol table entry.
|
||||
class rstream : public _rstream {
|
||||
private:
|
||||
template<class T>
|
||||
inline rstream& doRead(T &x) {
|
||||
read((char*)&x, sizeof(T));
|
||||
return *this;
|
||||
}
|
||||
static pair<const char*, streamsize> getBuf(const char *fileName) {
|
||||
ifstream raw(fileName,ios::binary | ios::in);
|
||||
if(!raw.is_open())
|
||||
stop("rstream.getBuf: Error opening file");
|
||||
raw.seekg(0,ios::end);
|
||||
streampos fileSize = raw.tellg();
|
||||
if(fileSize < 0)
|
||||
stop("rstream.getBuf: Error reading file");
|
||||
char *buf = new char[fileSize];
|
||||
raw.seekg(0,ios::beg);
|
||||
raw.read(buf, fileSize);
|
||||
return pair<const char*, streamsize>(buf,fileSize);
|
||||
}
|
||||
template <class T> inline rstream &doRead(T &x) {
|
||||
read((char *)&x, sizeof(T));
|
||||
return *this;
|
||||
}
|
||||
static pair<const char *, streamsize> getBuf(const char *fileName) {
|
||||
ifstream raw(fileName, ios::binary | ios::in);
|
||||
if (!raw.is_open())
|
||||
stop("rstream.getBuf: Error opening file");
|
||||
raw.seekg(0, ios::end);
|
||||
streampos fileSize = raw.tellg();
|
||||
if (fileSize < 0)
|
||||
stop("rstream.getBuf: Error reading file");
|
||||
char *buf = new char[fileSize];
|
||||
raw.seekg(0, ios::beg);
|
||||
raw.read(buf, fileSize);
|
||||
return pair<const char *, streamsize>(buf, fileSize);
|
||||
}
|
||||
|
||||
public:
|
||||
// construct from a string
|
||||
rstream(const char *buf,streamsize size):_rstream(pair<const char*,streamsize>(buf, size)){}
|
||||
/* construct from a file whole content is fully read once to initialize the content of
|
||||
this stream
|
||||
*/
|
||||
rstream(const char *fileName):_rstream(getBuf(fileName)){}
|
||||
rstream& operator>>(int &x) {
|
||||
return doRead(x);
|
||||
}
|
||||
rstream& operator>>(unsigned &x) {
|
||||
return doRead(x);
|
||||
}
|
||||
rstream& operator>>(short &x) {
|
||||
return doRead(x);
|
||||
}
|
||||
rstream& operator>>(unsigned short &x) {
|
||||
return doRead(x);
|
||||
}
|
||||
rstream& operator>>(Symbol &e) {
|
||||
read((char*)&e, 18);
|
||||
return *this;
|
||||
}
|
||||
// construct from a string
|
||||
rstream(const char *buf, streamsize size)
|
||||
: _rstream(pair<const char *, streamsize>(buf, size)) {}
|
||||
// construct from a file whole content is fully read once to initialize the
|
||||
// content of this stream
|
||||
rstream(const char *fileName) : _rstream(getBuf(fileName)) {}
|
||||
rstream &operator>>(int &x) { return doRead(x); }
|
||||
rstream &operator>>(unsigned &x) { return doRead(x); }
|
||||
rstream &operator>>(short &x) { return doRead(x); }
|
||||
rstream &operator>>(unsigned short &x) { return doRead(x); }
|
||||
rstream &operator>>(Symbol &e) {
|
||||
read((char *)&e, 18);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
// string table in a .OBJ file
|
||||
class StringTable {
|
||||
private:
|
||||
map<string, unsigned> directory;
|
||||
size_t length;
|
||||
char *data;
|
||||
map<string, unsigned> directory;
|
||||
size_t length;
|
||||
char *data;
|
||||
|
||||
// make <directory> from <length> bytes in <data>
|
||||
void makeDirectory(void) {
|
||||
unsigned i = 4;
|
||||
while(i < length) {
|
||||
string s = string(data + i);
|
||||
directory.insert(make_pair(s, i));
|
||||
i += s.size() + 1;
|
||||
}
|
||||
// make <directory> from <length> bytes in <data>
|
||||
void makeDirectory(void) {
|
||||
unsigned i = 4;
|
||||
while (i < length) {
|
||||
string s = string(data + i);
|
||||
directory.insert(make_pair(s, i));
|
||||
i += s.size() + 1;
|
||||
}
|
||||
// initialize <length> and <data> with contents specified by the arguments
|
||||
void init(const char *_data) {
|
||||
unsigned _length = *(unsigned*)_data;
|
||||
}
|
||||
// initialize <length> and <data> with contents specified by the arguments
|
||||
void init(const char *_data) {
|
||||
unsigned _length = *(unsigned *)_data;
|
||||
|
||||
if(_length < sizeof(unsigned) || _length != *(unsigned*)_data)
|
||||
stop("StringTable.init: Invalid symbol table");
|
||||
if(_data[_length - 1]) {
|
||||
// to prevent runaway strings, make sure the data ends with a zero
|
||||
data = new char[length = _length + 1];
|
||||
data[_length] = 0;
|
||||
} else {
|
||||
data = new char[length = _length];
|
||||
}
|
||||
*(unsigned*)data = length;
|
||||
KMP_MEMCPY(data + sizeof(unsigned), _data + sizeof(unsigned),
|
||||
length - sizeof(unsigned));
|
||||
makeDirectory();
|
||||
if (_length < sizeof(unsigned) || _length != *(unsigned *)_data)
|
||||
stop("StringTable.init: Invalid symbol table");
|
||||
if (_data[_length - 1]) {
|
||||
// to prevent runaway strings, make sure the data ends with a zero
|
||||
data = new char[length = _length + 1];
|
||||
data[_length] = 0;
|
||||
} else {
|
||||
data = new char[length = _length];
|
||||
}
|
||||
*(unsigned *)data = length;
|
||||
KMP_MEMCPY(data + sizeof(unsigned), _data + sizeof(unsigned),
|
||||
length - sizeof(unsigned));
|
||||
makeDirectory();
|
||||
}
|
||||
|
||||
public:
|
||||
StringTable(rstream &f) {
|
||||
/* Construct string table by reading from f.
|
||||
*/
|
||||
streampos s;
|
||||
unsigned strSize;
|
||||
char *strData;
|
||||
StringTable(rstream &f) {
|
||||
// Construct string table by reading from f.
|
||||
streampos s;
|
||||
unsigned strSize;
|
||||
char *strData;
|
||||
|
||||
s = f.tellg();
|
||||
f>>strSize;
|
||||
if(strSize < sizeof(unsigned))
|
||||
stop("StringTable: Invalid string table");
|
||||
strData = new char[strSize];
|
||||
*(unsigned*)strData = strSize;
|
||||
// read the raw data into <strData>
|
||||
f.read(strData + sizeof(unsigned), strSize - sizeof(unsigned));
|
||||
s = f.tellg() - s;
|
||||
if(s < strSize)
|
||||
stop("StringTable: Unexpected EOF");
|
||||
init(strData);
|
||||
delete[]strData;
|
||||
}
|
||||
StringTable(const set<string> &strings) {
|
||||
/* Construct string table from given strings.
|
||||
*/
|
||||
char *p;
|
||||
set<string>::const_iterator it;
|
||||
size_t s;
|
||||
s = f.tellg();
|
||||
f >> strSize;
|
||||
if (strSize < sizeof(unsigned))
|
||||
stop("StringTable: Invalid string table");
|
||||
strData = new char[strSize];
|
||||
*(unsigned *)strData = strSize;
|
||||
// read the raw data into <strData>
|
||||
f.read(strData + sizeof(unsigned), strSize - sizeof(unsigned));
|
||||
s = f.tellg() - s;
|
||||
if (s < strSize)
|
||||
stop("StringTable: Unexpected EOF");
|
||||
init(strData);
|
||||
delete[] strData;
|
||||
}
|
||||
StringTable(const set<string> &strings) {
|
||||
// Construct string table from given strings.
|
||||
char *p;
|
||||
set<string>::const_iterator it;
|
||||
size_t s;
|
||||
|
||||
// count required size for data
|
||||
for(length = sizeof(unsigned), it = strings.begin(); it != strings.end(); ++it) {
|
||||
size_t l = (*it).size();
|
||||
// count required size for data
|
||||
for (length = sizeof(unsigned), it = strings.begin(); it != strings.end();
|
||||
++it) {
|
||||
size_t l = (*it).size();
|
||||
|
||||
if(l > (unsigned) 0xFFFFFFFF)
|
||||
stop("StringTable: String too long");
|
||||
if(l > 8) {
|
||||
length += l + 1;
|
||||
if(length > (unsigned) 0xFFFFFFFF)
|
||||
stop("StringTable: Symbol table too long");
|
||||
}
|
||||
}
|
||||
data = new char[length];
|
||||
*(unsigned*)data = length;
|
||||
// populate data and directory
|
||||
for(p = data + sizeof(unsigned), it = strings.begin(); it != strings.end(); ++it) {
|
||||
const string &str = *it;
|
||||
size_t l = str.size();
|
||||
if(l > 8) {
|
||||
directory.insert(make_pair(str, p - data));
|
||||
KMP_MEMCPY(p, str.c_str(), l);
|
||||
p[l] = 0;
|
||||
p += l + 1;
|
||||
}
|
||||
}
|
||||
if (l > (unsigned)0xFFFFFFFF)
|
||||
stop("StringTable: String too long");
|
||||
if (l > 8) {
|
||||
length += l + 1;
|
||||
if (length > (unsigned)0xFFFFFFFF)
|
||||
stop("StringTable: Symbol table too long");
|
||||
}
|
||||
}
|
||||
~StringTable() {
|
||||
delete[] data;
|
||||
data = new char[length];
|
||||
*(unsigned *)data = length;
|
||||
// populate data and directory
|
||||
for (p = data + sizeof(unsigned), it = strings.begin(); it != strings.end();
|
||||
++it) {
|
||||
const string &str = *it;
|
||||
size_t l = str.size();
|
||||
if (l > 8) {
|
||||
directory.insert(make_pair(str, p - data));
|
||||
KMP_MEMCPY(p, str.c_str(), l);
|
||||
p[l] = 0;
|
||||
p += l + 1;
|
||||
}
|
||||
}
|
||||
/* Returns encoding for given string based on this string table.
|
||||
Error if string length is greater than 8 but string is not in
|
||||
the string table--returns 0.
|
||||
*/
|
||||
__int64 encode(const string &str) {
|
||||
__int64 r;
|
||||
}
|
||||
~StringTable() { delete[] data; }
|
||||
// Returns encoding for given string based on this string table. Error if
|
||||
// string length is greater than 8 but string is not in the string table
|
||||
// -- returns 0.
|
||||
__int64 encode(const string &str) {
|
||||
__int64 r;
|
||||
|
||||
if(str.size() <= 8) {
|
||||
// encoded directly
|
||||
((char*)&r)[7] = 0;
|
||||
KMP_STRNCPY_S((char*)&r, sizeof(r), str.c_str(), 8);
|
||||
return r;
|
||||
} else {
|
||||
// represented as index into table
|
||||
map<string,unsigned>::const_iterator it = directory.find(str);
|
||||
if(it == directory.end())
|
||||
stop("StringTable::encode: String now found in string table");
|
||||
((unsigned*)&r)[0] = 0;
|
||||
((unsigned*)&r)[1] = (*it).second;
|
||||
return r;
|
||||
}
|
||||
if (str.size() <= 8) {
|
||||
// encoded directly
|
||||
((char *)&r)[7] = 0;
|
||||
KMP_STRNCPY_S((char *)&r, sizeof(r), str.c_str(), 8);
|
||||
return r;
|
||||
} else {
|
||||
// represented as index into table
|
||||
map<string, unsigned>::const_iterator it = directory.find(str);
|
||||
if (it == directory.end())
|
||||
stop("StringTable::encode: String now found in string table");
|
||||
((unsigned *)&r)[0] = 0;
|
||||
((unsigned *)&r)[1] = (*it).second;
|
||||
return r;
|
||||
}
|
||||
/* Returns string represented by x based on this string table.
|
||||
Error if x references an invalid position in the table--returns
|
||||
the empty string.
|
||||
*/
|
||||
string decode(__int64 x) const {
|
||||
if(*(unsigned*)&x == 0) {
|
||||
// represented as index into table
|
||||
unsigned &p = ((unsigned*)&x)[1];
|
||||
if(p >= length)
|
||||
stop("StringTable::decode: Invalid string table lookup");
|
||||
return string(data + p);
|
||||
} else {
|
||||
// encoded directly
|
||||
char *p = (char*)&x;
|
||||
int i;
|
||||
}
|
||||
// Returns string represented by x based on this string table. Error if x
|
||||
// references an invalid position in the table--returns the empty string.
|
||||
string decode(__int64 x) const {
|
||||
if (*(unsigned *)&x == 0) {
|
||||
// represented as index into table
|
||||
unsigned &p = ((unsigned *)&x)[1];
|
||||
if (p >= length)
|
||||
stop("StringTable::decode: Invalid string table lookup");
|
||||
return string(data + p);
|
||||
} else {
|
||||
// encoded directly
|
||||
char *p = (char *)&x;
|
||||
int i;
|
||||
|
||||
for(i = 0; i < 8 && p[i]; ++i);
|
||||
return string(p, i);
|
||||
}
|
||||
}
|
||||
void write(ostream &os) {
|
||||
os.write(data, length);
|
||||
for (i = 0; i < 8 && p[i]; ++i)
|
||||
;
|
||||
return string(p, i);
|
||||
}
|
||||
}
|
||||
void write(ostream &os) { os.write(data, length); }
|
||||
};
|
||||
|
||||
/* for the named object file, determines the set of defined symbols and the set of undefined external symbols
|
||||
and writes them to <defined> and <undefined> respectively
|
||||
*/
|
||||
void computeExternalSymbols(const char *fileName, set<string> *defined, set<string> *undefined){
|
||||
streampos fileSize;
|
||||
size_t strTabStart;
|
||||
unsigned symTabStart, symNEntries;
|
||||
rstream f(fileName);
|
||||
// for the named object file, determines the set of defined symbols and the set
|
||||
// of undefined external symbols and writes them to <defined> and <undefined>
|
||||
// respectively
|
||||
void computeExternalSymbols(const char *fileName, set<string> *defined,
|
||||
set<string> *undefined) {
|
||||
streampos fileSize;
|
||||
size_t strTabStart;
|
||||
unsigned symTabStart, symNEntries;
|
||||
rstream f(fileName);
|
||||
|
||||
f.seekg(0,ios::end);
|
||||
fileSize = f.tellg();
|
||||
f.seekg(0, ios::end);
|
||||
fileSize = f.tellg();
|
||||
|
||||
f.seekg(8);
|
||||
f >> symTabStart >> symNEntries;
|
||||
// seek to the string table
|
||||
f.seekg(strTabStart = symTabStart + 18 * (size_t)symNEntries);
|
||||
if(f.eof()) {
|
||||
printf("computeExternalSymbols: fileName='%s', fileSize = %lu, symTabStart = %u, symNEntries = %u\n",
|
||||
fileName, (unsigned long) fileSize, symTabStart, symNEntries);
|
||||
stop("computeExternalSymbols: Unexpected EOF 1");
|
||||
}
|
||||
StringTable stringTable(f); // read the string table
|
||||
if(f.tellg() != fileSize)
|
||||
stop("computeExternalSymbols: Unexpected data after string table");
|
||||
|
||||
f.clear();
|
||||
f.seekg(symTabStart); // seek to the symbol table
|
||||
|
||||
defined->clear(); undefined->clear();
|
||||
for(int i = 0; i < symNEntries; ++i) {
|
||||
// process each entry
|
||||
Symbol e;
|
||||
|
||||
if(f.eof())
|
||||
stop("computeExternalSymbols: Unexpected EOF 2");
|
||||
f>>e;
|
||||
if(f.fail())
|
||||
stop("computeExternalSymbols: File read error");
|
||||
if(e.nAux) { // auxiliary entry: skip
|
||||
f.seekg(e.nAux * 18, ios::cur);
|
||||
i += e.nAux;
|
||||
}
|
||||
// if symbol is extern and defined in the current file, insert it
|
||||
if(e.storageClass == 2)
|
||||
if(e.sectionNum)
|
||||
defined->insert(stringTable.decode(e.name));
|
||||
else
|
||||
undefined->insert(stringTable.decode(e.name));
|
||||
f.seekg(8);
|
||||
f >> symTabStart >> symNEntries;
|
||||
// seek to the string table
|
||||
f.seekg(strTabStart = symTabStart + 18 * (size_t)symNEntries);
|
||||
if (f.eof()) {
|
||||
printf("computeExternalSymbols: fileName='%s', fileSize = %lu, symTabStart "
|
||||
"= %u, symNEntries = %u\n",
|
||||
fileName, (unsigned long)fileSize, symTabStart, symNEntries);
|
||||
stop("computeExternalSymbols: Unexpected EOF 1");
|
||||
}
|
||||
StringTable stringTable(f); // read the string table
|
||||
if (f.tellg() != fileSize)
|
||||
stop("computeExternalSymbols: Unexpected data after string table");
|
||||
|
||||
f.clear();
|
||||
f.seekg(symTabStart); // seek to the symbol table
|
||||
|
||||
defined->clear();
|
||||
undefined->clear();
|
||||
for (int i = 0; i < symNEntries; ++i) {
|
||||
// process each entry
|
||||
Symbol e;
|
||||
|
||||
if (f.eof())
|
||||
stop("computeExternalSymbols: Unexpected EOF 2");
|
||||
f >> e;
|
||||
if (f.fail())
|
||||
stop("computeExternalSymbols: File read error");
|
||||
if (e.nAux) { // auxiliary entry: skip
|
||||
f.seekg(e.nAux * 18, ios::cur);
|
||||
i += e.nAux;
|
||||
}
|
||||
// if symbol is extern and defined in the current file, insert it
|
||||
if (e.storageClass == 2)
|
||||
if (e.sectionNum)
|
||||
defined->insert(stringTable.decode(e.name));
|
||||
else
|
||||
undefined->insert(stringTable.decode(e.name));
|
||||
}
|
||||
}
|
||||
|
||||
/* For each occurrence of an external symbol in the object file named by
|
||||
by <fileName> that is a member of <hide>, renames it by prefixing
|
||||
with "__kmp_external_", writing back the file in-place
|
||||
*/
|
||||
// For each occurrence of an external symbol in the object file named by
|
||||
// by <fileName> that is a member of <hide>, renames it by prefixing
|
||||
// with "__kmp_external_", writing back the file in-place
|
||||
void hideSymbols(char *fileName, const set<string> &hide) {
|
||||
static const string prefix("__kmp_external_");
|
||||
set<string> strings; // set of all occurring symbols, appropriately prefixed
|
||||
streampos fileSize;
|
||||
size_t strTabStart;
|
||||
unsigned symTabStart, symNEntries;
|
||||
int i;
|
||||
rstream in(fileName);
|
||||
static const string prefix("__kmp_external_");
|
||||
set<string> strings; // set of all occurring symbols, appropriately prefixed
|
||||
streampos fileSize;
|
||||
size_t strTabStart;
|
||||
unsigned symTabStart, symNEntries;
|
||||
int i;
|
||||
rstream in(fileName);
|
||||
|
||||
in.seekg(0,ios::end);
|
||||
fileSize = in.tellg();
|
||||
in.seekg(0, ios::end);
|
||||
fileSize = in.tellg();
|
||||
|
||||
in.seekg(8);
|
||||
in >> symTabStart >> symNEntries;
|
||||
in.seekg(strTabStart = symTabStart + 18 * (size_t)symNEntries);
|
||||
if(in.eof())
|
||||
stop("hideSymbols: Unexpected EOF");
|
||||
StringTable stringTableOld(in); // read original string table
|
||||
in.seekg(8);
|
||||
in >> symTabStart >> symNEntries;
|
||||
in.seekg(strTabStart = symTabStart + 18 * (size_t)symNEntries);
|
||||
if (in.eof())
|
||||
stop("hideSymbols: Unexpected EOF");
|
||||
StringTable stringTableOld(in); // read original string table
|
||||
|
||||
if(in.tellg() != fileSize)
|
||||
stop("hideSymbols: Unexpected data after string table");
|
||||
if (in.tellg() != fileSize)
|
||||
stop("hideSymbols: Unexpected data after string table");
|
||||
|
||||
// compute set of occurring strings with prefix added
|
||||
for(i = 0; i < symNEntries; ++i) {
|
||||
Symbol e;
|
||||
// compute set of occurring strings with prefix added
|
||||
for (i = 0; i < symNEntries; ++i) {
|
||||
Symbol e;
|
||||
|
||||
in.seekg(symTabStart + i * 18);
|
||||
if(in.eof())
|
||||
stop("hideSymbols: Unexpected EOF");
|
||||
in >> e;
|
||||
if(in.fail())
|
||||
stop("hideSymbols: File read error");
|
||||
if(e.nAux)
|
||||
i += e.nAux;
|
||||
const string &s = stringTableOld.decode(e.name);
|
||||
// if symbol is extern and found in <hide>, prefix and insert into strings,
|
||||
// otherwise, just insert into strings without prefix
|
||||
strings.insert( (e.storageClass == 2 && hide.find(s) != hide.end()) ?
|
||||
prefix + s : s);
|
||||
in.seekg(symTabStart + i * 18);
|
||||
if (in.eof())
|
||||
stop("hideSymbols: Unexpected EOF");
|
||||
in >> e;
|
||||
if (in.fail())
|
||||
stop("hideSymbols: File read error");
|
||||
if (e.nAux)
|
||||
i += e.nAux;
|
||||
const string &s = stringTableOld.decode(e.name);
|
||||
// if symbol is extern and found in <hide>, prefix and insert into strings,
|
||||
// otherwise, just insert into strings without prefix
|
||||
strings.insert(
|
||||
(e.storageClass == 2 && hide.find(s) != hide.end()) ? prefix + s : s);
|
||||
}
|
||||
|
||||
ofstream out(fileName, ios::trunc | ios::out | ios::binary);
|
||||
if (!out.is_open())
|
||||
stop("hideSymbols: Error opening output file");
|
||||
|
||||
// make new string table from string set
|
||||
StringTable stringTableNew = StringTable(strings);
|
||||
|
||||
// copy input file to output file up to just before the symbol table
|
||||
in.seekg(0);
|
||||
char *buf = new char[symTabStart];
|
||||
in.read(buf, symTabStart);
|
||||
out.write(buf, symTabStart);
|
||||
delete[] buf;
|
||||
|
||||
// copy input symbol table to output symbol table with name translation
|
||||
for (i = 0; i < symNEntries; ++i) {
|
||||
Symbol e;
|
||||
|
||||
in.seekg(symTabStart + i * 18);
|
||||
if (in.eof())
|
||||
stop("hideSymbols: Unexpected EOF");
|
||||
in >> e;
|
||||
if (in.fail())
|
||||
stop("hideSymbols: File read error");
|
||||
const string &s = stringTableOld.decode(e.name);
|
||||
out.seekp(symTabStart + i * 18);
|
||||
e.name = stringTableNew.encode(
|
||||
(e.storageClass == 2 && hide.find(s) != hide.end()) ? prefix + s : s);
|
||||
out.write((char *)&e, 18);
|
||||
if (out.fail())
|
||||
stop("hideSymbols: File write error");
|
||||
if (e.nAux) {
|
||||
// copy auxiliary symbol table entries
|
||||
int nAux = e.nAux;
|
||||
for (int j = 1; j <= nAux; ++j) {
|
||||
in >> e;
|
||||
out.seekp(symTabStart + (i + j) * 18);
|
||||
out.write((char *)&e, 18);
|
||||
}
|
||||
i += nAux;
|
||||
}
|
||||
|
||||
ofstream out(fileName, ios::trunc | ios::out | ios::binary);
|
||||
if(!out.is_open())
|
||||
stop("hideSymbols: Error opening output file");
|
||||
|
||||
// make new string table from string set
|
||||
StringTable stringTableNew = StringTable(strings);
|
||||
|
||||
// copy input file to output file up to just before the symbol table
|
||||
in.seekg(0);
|
||||
char *buf = new char[symTabStart];
|
||||
in.read(buf, symTabStart);
|
||||
out.write(buf, symTabStart);
|
||||
delete []buf;
|
||||
|
||||
// copy input symbol table to output symbol table with name translation
|
||||
for(i = 0; i < symNEntries; ++i) {
|
||||
Symbol e;
|
||||
|
||||
in.seekg(symTabStart + i*18);
|
||||
if(in.eof())
|
||||
stop("hideSymbols: Unexpected EOF");
|
||||
in >> e;
|
||||
if(in.fail())
|
||||
stop("hideSymbols: File read error");
|
||||
const string &s = stringTableOld.decode(e.name);
|
||||
out.seekp(symTabStart + i*18);
|
||||
e.name = stringTableNew.encode( (e.storageClass == 2 && hide.find(s) != hide.end()) ?
|
||||
prefix + s : s);
|
||||
out.write((char*)&e, 18);
|
||||
if(out.fail())
|
||||
stop("hideSymbols: File write error");
|
||||
if(e.nAux) {
|
||||
// copy auxiliary symbol table entries
|
||||
int nAux = e.nAux;
|
||||
for(int j = 1; j <= nAux; ++j) {
|
||||
in >> e;
|
||||
out.seekp(symTabStart + (i + j) * 18);
|
||||
out.write((char*)&e, 18);
|
||||
}
|
||||
i += nAux;
|
||||
}
|
||||
}
|
||||
// output string table
|
||||
stringTableNew.write(out);
|
||||
}
|
||||
// output string table
|
||||
stringTableNew.write(out);
|
||||
}
|
||||
|
||||
// returns true iff <a> and <b> have no common element
|
||||
template <class T>
|
||||
bool isDisjoint(const set<T> &a, const set<T> &b) {
|
||||
set<T>::const_iterator ita, itb;
|
||||
template <class T> bool isDisjoint(const set<T> &a, const set<T> &b) {
|
||||
set<T>::const_iterator ita, itb;
|
||||
|
||||
for(ita = a.begin(), itb = b.begin(); ita != a.end() && itb != b.end();) {
|
||||
const T &ta = *ita, &tb = *itb;
|
||||
if(ta < tb)
|
||||
++ita;
|
||||
else if (tb < ta)
|
||||
++itb;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
for (ita = a.begin(), itb = b.begin(); ita != a.end() && itb != b.end();) {
|
||||
const T &ta = *ita, &tb = *itb;
|
||||
if (ta < tb)
|
||||
++ita;
|
||||
else if (tb < ta)
|
||||
++itb;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* precondition: <defined> and <undefined> are arrays with <nTotal> elements where
|
||||
<nTotal> >= <nExternal>. The first <nExternal> elements correspond to the external object
|
||||
files and the rest correspond to the internal object files.
|
||||
postcondition: file x is said to depend on file y if undefined[x] and defined[y] are not
|
||||
disjoint. Returns the transitive closure of the set of internal object files, as a set of
|
||||
file indexes, under the 'depends on' relation, minus the set of internal object files.
|
||||
*/
|
||||
set<int> *findRequiredExternal(int nExternal, int nTotal, set<string> *defined, set<string> *undefined) {
|
||||
set<int> *required = new set<int>;
|
||||
set<int> fresh[2];
|
||||
int i, cur = 0;
|
||||
bool changed;
|
||||
// PRE: <defined> and <undefined> are arrays with <nTotal> elements where
|
||||
// <nTotal> >= <nExternal>. The first <nExternal> elements correspond to the
|
||||
// external object files and the rest correspond to the internal object files.
|
||||
// POST: file x is said to depend on file y if undefined[x] and defined[y] are
|
||||
// not disjoint. Returns the transitive closure of the set of internal object
|
||||
// files, as a set of file indexes, under the 'depends on' relation, minus the
|
||||
// set of internal object files.
|
||||
set<int> *findRequiredExternal(int nExternal, int nTotal, set<string> *defined,
|
||||
set<string> *undefined) {
|
||||
set<int> *required = new set<int>;
|
||||
set<int> fresh[2];
|
||||
int i, cur = 0;
|
||||
bool changed;
|
||||
|
||||
for(i = nTotal - 1; i >= nExternal; --i)
|
||||
fresh[cur].insert(i);
|
||||
do {
|
||||
changed = false;
|
||||
for(set<int>::iterator it = fresh[cur].begin(); it != fresh[cur].end(); ++it) {
|
||||
set<string> &s = undefined[*it];
|
||||
for (i = nTotal - 1; i >= nExternal; --i)
|
||||
fresh[cur].insert(i);
|
||||
do {
|
||||
changed = false;
|
||||
for (set<int>::iterator it = fresh[cur].begin(); it != fresh[cur].end();
|
||||
++it) {
|
||||
set<string> &s = undefined[*it];
|
||||
|
||||
for(i = 0; i < nExternal; ++i) {
|
||||
if(required->find(i) == required->end()) {
|
||||
if(!isDisjoint(defined[i], s)) {
|
||||
// found a new qualifying element
|
||||
required->insert(i);
|
||||
fresh[1 - cur].insert(i);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fresh[cur].clear();
|
||||
cur = 1 - cur;
|
||||
} while(changed);
|
||||
return required;
|
||||
for (i = 0; i < nExternal; ++i) {
|
||||
if (required->find(i) == required->end()) {
|
||||
if (!isDisjoint(defined[i], s)) {
|
||||
// found a new qualifying element
|
||||
required->insert(i);
|
||||
fresh[1 - cur].insert(i);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fresh[cur].clear();
|
||||
cur = 1 - cur;
|
||||
} while (changed);
|
||||
return required;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int nExternal, nInternal, i;
|
||||
set<string> *defined, *undefined;
|
||||
set<int>::iterator it;
|
||||
int nExternal, nInternal, i;
|
||||
set<string> *defined, *undefined;
|
||||
set<int>::iterator it;
|
||||
|
||||
if(argc < 3)
|
||||
stop("Please specify a positive integer followed by a list of object filenames");
|
||||
nExternal = atoi(argv[1]);
|
||||
if(nExternal <= 0)
|
||||
stop("Please specify a positive integer followed by a list of object filenames");
|
||||
if(nExternal + 2 > argc)
|
||||
stop("Too few external objects");
|
||||
nInternal = argc - nExternal - 2;
|
||||
defined = new set<string>[argc - 2];
|
||||
undefined = new set<string>[argc - 2];
|
||||
if (argc < 3)
|
||||
stop("Please specify a positive integer followed by a list of object "
|
||||
"filenames");
|
||||
nExternal = atoi(argv[1]);
|
||||
if (nExternal <= 0)
|
||||
stop("Please specify a positive integer followed by a list of object "
|
||||
"filenames");
|
||||
if (nExternal + 2 > argc)
|
||||
stop("Too few external objects");
|
||||
nInternal = argc - nExternal - 2;
|
||||
defined = new set<string>[argc - 2];
|
||||
undefined = new set<string>[argc - 2];
|
||||
|
||||
// determine the set of defined and undefined external symbols
|
||||
for(i = 2; i < argc; ++i)
|
||||
computeExternalSymbols(argv[i], defined + i - 2, undefined + i - 2);
|
||||
// determine the set of defined and undefined external symbols
|
||||
for (i = 2; i < argc; ++i)
|
||||
computeExternalSymbols(argv[i], defined + i - 2, undefined + i - 2);
|
||||
|
||||
// determine the set of required external files
|
||||
set<int> *requiredExternal = findRequiredExternal(nExternal, argc - 2, defined, undefined);
|
||||
set<string> hide;
|
||||
// determine the set of required external files
|
||||
set<int> *requiredExternal =
|
||||
findRequiredExternal(nExternal, argc - 2, defined, undefined);
|
||||
set<string> hide;
|
||||
|
||||
/* determine the set of symbols to hide--namely defined external symbols of the
|
||||
required external files
|
||||
*/
|
||||
for(it = requiredExternal->begin(); it != requiredExternal->end(); ++it) {
|
||||
int idx = *it;
|
||||
set<string>::iterator it2;
|
||||
/* We have to insert one element at a time instead of inserting a range because
|
||||
the insert member function taking a range doesn't exist on Windows* OS, at least
|
||||
at the time of this writing.
|
||||
*/
|
||||
for(it2 = defined[idx].begin(); it2 != defined[idx].end(); ++it2)
|
||||
hide.insert(*it2);
|
||||
}
|
||||
// determine the set of symbols to hide--namely defined external symbols of
|
||||
// the required external files
|
||||
for (it = requiredExternal->begin(); it != requiredExternal->end(); ++it) {
|
||||
int idx = *it;
|
||||
set<string>::iterator it2;
|
||||
// We have to insert one element at a time instead of inserting a range
|
||||
// because the insert member function taking a range doesn't exist on
|
||||
// Windows* OS, at least at the time of this writing.
|
||||
for (it2 = defined[idx].begin(); it2 != defined[idx].end(); ++it2)
|
||||
hide.insert(*it2);
|
||||
}
|
||||
|
||||
/* process the external files--removing those that are not required and hiding
|
||||
the appropriate symbols in the others
|
||||
*/
|
||||
for(i = 0; i < nExternal; ++i)
|
||||
if(requiredExternal->find(i) != requiredExternal->end())
|
||||
hideSymbols(argv[2 + i], hide);
|
||||
else
|
||||
remove(argv[2 + i]);
|
||||
// hide the appropriate symbols in the internal files
|
||||
for(i = nExternal + 2; i < argc; ++i)
|
||||
hideSymbols(argv[i], hide);
|
||||
return 0;
|
||||
// process the external files--removing those that are not required and hiding
|
||||
// the appropriate symbols in the others
|
||||
for (i = 0; i < nExternal; ++i)
|
||||
if (requiredExternal->find(i) != requiredExternal->end())
|
||||
hideSymbols(argv[2 + i], hide);
|
||||
else
|
||||
remove(argv[2 + i]);
|
||||
// hide the appropriate symbols in the internal files
|
||||
for (i = nExternal + 2; i < argc; ++i)
|
||||
hideSymbols(argv[i], hide);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ Language "English"
|
||||
Country "USA"
|
||||
LangId "1033"
|
||||
Version "2"
|
||||
Revision "20160714"
|
||||
Revision "20161216"
|
||||
|
||||
|
||||
|
||||
@@ -388,15 +388,15 @@ OBSOLETE "%1$s: granularity=core will be used."
|
||||
EnvLockWarn "%1$s must be set prior to first OMP lock call or critical section; ignored."
|
||||
FutexNotSupported "futex system call not supported; %1$s=%2$s ignored."
|
||||
AffGranUsing "%1$s: granularity=%2$s will be used."
|
||||
AffHWSubsetInvalid "%1$s: invalid value \"%2$s\", valid format is \"Ns[@N],Nc[@N],Nt "
|
||||
"(nSockets@offset, nCores@offset, nTthreads per core)\"."
|
||||
AffHWSubsetInvalid "%1$s: invalid value \"%2$s\", valid format is \"N<item>[@N][,...][,Nt] "
|
||||
"(<item> can be S, N, L2, C, T for Socket, NUMA Node, L2 Cache, Core, Thread)\"."
|
||||
AffHWSubsetUnsupported "KMP_HW_SUBSET ignored: unsupported architecture."
|
||||
AffHWSubsetManyCores "KMP_HW_SUBSET ignored: too many cores requested."
|
||||
SyntaxErrorUsing "%1$s: syntax error, using %2$s."
|
||||
AdaptiveNotSupported "%1$s: Adaptive locks are not supported; using queuing."
|
||||
EnvSyntaxError "%1$s: Invalid symbols found. Check the value \"%2$s\"."
|
||||
EnvSpacesNotAllowed "%1$s: Spaces between digits are not allowed \"%2$s\"."
|
||||
BoundToOSProcSet "%1$s: pid %2$d thread %3$d bound to OS proc set %4$s"
|
||||
BoundToOSProcSet "%1$s: pid %2$d tid %3$d thread %4$d bound to OS proc set %5$s"
|
||||
CnsLoopIncrIllegal "%1$s error: parallel loop increment and condition are inconsistent."
|
||||
NoGompCancellation "libgomp cancellation is not currently supported."
|
||||
AffHWSubsetNonUniform "KMP_HW_SUBSET ignored: non-uniform topology."
|
||||
@@ -411,6 +411,10 @@ AffHwlocErrorOccurred "%1$s: Hwloc failed in %2$s. Relying on internal af
|
||||
EnvSerialWarn "%1$s must be set prior to OpenMP runtime library initialization; ignored."
|
||||
EnvVarDeprecated "%1$s variable deprecated, please use %2$s instead."
|
||||
RedMethodNotSupported "KMP_FORCE_REDUCTION: %1$s method is not supported; using critical."
|
||||
AffHWSubsetNoHWLOC "KMP_HW_SUBSET ignored: unsupported item requested for non-HWLOC topology method (KMP_TOPOLOGY_METHOD)"
|
||||
AffHWSubsetManyNodes "KMP_HW_SUBSET ignored: too many NUMA Nodes requested."
|
||||
AffHWSubsetManyTiles "KMP_HW_SUBSET ignored: too many L2 Caches requested."
|
||||
AffHWSubsetManyProcs "KMP_HW_SUBSET ignored: too many Procs requested."
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------------------------------
|
||||
@@ -425,7 +429,7 @@ SubmitBugReport "Please submit a bug report with this message, comp
|
||||
"compiler and operating system versions. Faster response will be "
|
||||
"obtained by including all program sources. For information on "
|
||||
"submitting this issue, please see "
|
||||
"http://www.intel.com/software/products/support/."
|
||||
"https://bugs.llvm.org/."
|
||||
OBSOLETE "Check NLSPATH environment variable, its value is \"%1$s\"."
|
||||
ChangeStackLimit "Please try changing the shell stack limit or adjusting the "
|
||||
"OMP_STACKSIZE environment variable."
|
||||
@@ -441,7 +445,7 @@ DuplicateLibrary "This means that multiple copies of the OpenMP runt
|
||||
"you can set the environment variable KMP_DUPLICATE_LIB_OK=TRUE to allow "
|
||||
"the program to continue to execute, but that may cause crashes or "
|
||||
"silently produce incorrect results. "
|
||||
"For more information, please see http://www.intel.com/software/products/support/."
|
||||
"For more information, please see http://openmp.llvm.org/"
|
||||
NameComesFrom_CPUINFO_FILE "This name is specified in environment variable KMP_CPUINFO_FILE."
|
||||
NotEnoughMemory "Seems application required too much memory."
|
||||
ValidBoolValues "Use \"0\", \"FALSE\". \".F.\", \"off\", \"no\" as false values, "
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* include/50/omp.h.var
|
||||
*/
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.txt for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
#ifndef __OMP_H
|
||||
# define __OMP_H
|
||||
|
||||
# define KMP_VERSION_MAJOR @LIBOMP_VERSION_MAJOR@
|
||||
# define KMP_VERSION_MINOR @LIBOMP_VERSION_MINOR@
|
||||
# define KMP_VERSION_BUILD @LIBOMP_VERSION_BUILD@
|
||||
# define KMP_BUILD_DATE "@LIBOMP_BUILD_DATE@"
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif
|
||||
|
||||
# if defined(_WIN32)
|
||||
# define __KAI_KMPC_CONVENTION __cdecl
|
||||
# else
|
||||
# define __KAI_KMPC_CONVENTION
|
||||
# endif
|
||||
|
||||
/* schedule kind constants */
|
||||
typedef enum omp_sched_t {
|
||||
omp_sched_static = 1,
|
||||
omp_sched_dynamic = 2,
|
||||
omp_sched_guided = 3,
|
||||
omp_sched_auto = 4
|
||||
} omp_sched_t;
|
||||
|
||||
/* set API functions */
|
||||
extern void __KAI_KMPC_CONVENTION omp_set_num_threads (int);
|
||||
extern void __KAI_KMPC_CONVENTION omp_set_dynamic (int);
|
||||
extern void __KAI_KMPC_CONVENTION omp_set_nested (int);
|
||||
extern void __KAI_KMPC_CONVENTION omp_set_max_active_levels (int);
|
||||
extern void __KAI_KMPC_CONVENTION omp_set_schedule (omp_sched_t, int);
|
||||
|
||||
/* query API functions */
|
||||
extern int __KAI_KMPC_CONVENTION omp_get_num_threads (void);
|
||||
extern int __KAI_KMPC_CONVENTION omp_get_dynamic (void);
|
||||
extern int __KAI_KMPC_CONVENTION omp_get_nested (void);
|
||||
extern int __KAI_KMPC_CONVENTION omp_get_max_threads (void);
|
||||
extern int __KAI_KMPC_CONVENTION omp_get_thread_num (void);
|
||||
extern int __KAI_KMPC_CONVENTION omp_get_num_procs (void);
|
||||
extern int __KAI_KMPC_CONVENTION omp_in_parallel (void);
|
||||
extern int __KAI_KMPC_CONVENTION omp_in_final (void);
|
||||
extern int __KAI_KMPC_CONVENTION omp_get_active_level (void);
|
||||
extern int __KAI_KMPC_CONVENTION omp_get_level (void);
|
||||
extern int __KAI_KMPC_CONVENTION omp_get_ancestor_thread_num (int);
|
||||
extern int __KAI_KMPC_CONVENTION omp_get_team_size (int);
|
||||
extern int __KAI_KMPC_CONVENTION omp_get_thread_limit (void);
|
||||
extern int __KAI_KMPC_CONVENTION omp_get_max_active_levels (void);
|
||||
extern void __KAI_KMPC_CONVENTION omp_get_schedule (omp_sched_t *, int *);
|
||||
extern int __KAI_KMPC_CONVENTION omp_get_max_task_priority (void);
|
||||
|
||||
/* lock API functions */
|
||||
typedef struct omp_lock_t {
|
||||
void * _lk;
|
||||
} omp_lock_t;
|
||||
|
||||
extern void __KAI_KMPC_CONVENTION omp_init_lock (omp_lock_t *);
|
||||
extern void __KAI_KMPC_CONVENTION omp_set_lock (omp_lock_t *);
|
||||
extern void __KAI_KMPC_CONVENTION omp_unset_lock (omp_lock_t *);
|
||||
extern void __KAI_KMPC_CONVENTION omp_destroy_lock (omp_lock_t *);
|
||||
extern int __KAI_KMPC_CONVENTION omp_test_lock (omp_lock_t *);
|
||||
|
||||
/* nested lock API functions */
|
||||
typedef struct omp_nest_lock_t {
|
||||
void * _lk;
|
||||
} omp_nest_lock_t;
|
||||
|
||||
extern void __KAI_KMPC_CONVENTION omp_init_nest_lock (omp_nest_lock_t *);
|
||||
extern void __KAI_KMPC_CONVENTION omp_set_nest_lock (omp_nest_lock_t *);
|
||||
extern void __KAI_KMPC_CONVENTION omp_unset_nest_lock (omp_nest_lock_t *);
|
||||
extern void __KAI_KMPC_CONVENTION omp_destroy_nest_lock (omp_nest_lock_t *);
|
||||
extern int __KAI_KMPC_CONVENTION omp_test_nest_lock (omp_nest_lock_t *);
|
||||
|
||||
/* lock hint type for dynamic user lock */
|
||||
typedef enum omp_lock_hint_t {
|
||||
omp_lock_hint_none = 0,
|
||||
omp_lock_hint_uncontended = 1,
|
||||
omp_lock_hint_contended = (1<<1 ),
|
||||
omp_lock_hint_nonspeculative = (1<<2 ),
|
||||
omp_lock_hint_speculative = (1<<3 ),
|
||||
kmp_lock_hint_hle = (1<<16),
|
||||
kmp_lock_hint_rtm = (1<<17),
|
||||
kmp_lock_hint_adaptive = (1<<18)
|
||||
} omp_lock_hint_t;
|
||||
|
||||
/* hinted lock initializers */
|
||||
extern void __KAI_KMPC_CONVENTION omp_init_lock_with_hint(omp_lock_t *, omp_lock_hint_t);
|
||||
extern void __KAI_KMPC_CONVENTION omp_init_nest_lock_with_hint(omp_nest_lock_t *, omp_lock_hint_t);
|
||||
|
||||
/* time API functions */
|
||||
extern double __KAI_KMPC_CONVENTION omp_get_wtime (void);
|
||||
extern double __KAI_KMPC_CONVENTION omp_get_wtick (void);
|
||||
|
||||
/* OpenMP 4.0 */
|
||||
extern int __KAI_KMPC_CONVENTION omp_get_default_device (void);
|
||||
extern void __KAI_KMPC_CONVENTION omp_set_default_device (int);
|
||||
extern int __KAI_KMPC_CONVENTION omp_is_initial_device (void);
|
||||
extern int __KAI_KMPC_CONVENTION omp_get_num_devices (void);
|
||||
extern int __KAI_KMPC_CONVENTION omp_get_num_teams (void);
|
||||
extern int __KAI_KMPC_CONVENTION omp_get_team_num (void);
|
||||
extern int __KAI_KMPC_CONVENTION omp_get_cancellation (void);
|
||||
|
||||
# include <stdlib.h>
|
||||
/* OpenMP 4.5 */
|
||||
extern int __KAI_KMPC_CONVENTION omp_get_initial_device (void);
|
||||
extern void* __KAI_KMPC_CONVENTION omp_target_alloc(size_t, int);
|
||||
extern void __KAI_KMPC_CONVENTION omp_target_free(void *, int);
|
||||
extern int __KAI_KMPC_CONVENTION omp_target_is_present(void *, int);
|
||||
extern int __KAI_KMPC_CONVENTION omp_target_memcpy(void *, void *, size_t, size_t, size_t, int, int);
|
||||
extern int __KAI_KMPC_CONVENTION omp_target_memcpy_rect(void *, void *, size_t, int, const size_t *,
|
||||
const size_t *, const size_t *, const size_t *, const size_t *, int, int);
|
||||
extern int __KAI_KMPC_CONVENTION omp_target_associate_ptr(void *, void *, size_t, size_t, int);
|
||||
extern int __KAI_KMPC_CONVENTION omp_target_disassociate_ptr(void *, int);
|
||||
|
||||
/* kmp API functions */
|
||||
extern int __KAI_KMPC_CONVENTION kmp_get_stacksize (void);
|
||||
extern void __KAI_KMPC_CONVENTION kmp_set_stacksize (int);
|
||||
extern size_t __KAI_KMPC_CONVENTION kmp_get_stacksize_s (void);
|
||||
extern void __KAI_KMPC_CONVENTION kmp_set_stacksize_s (size_t);
|
||||
extern int __KAI_KMPC_CONVENTION kmp_get_blocktime (void);
|
||||
extern int __KAI_KMPC_CONVENTION kmp_get_library (void);
|
||||
extern void __KAI_KMPC_CONVENTION kmp_set_blocktime (int);
|
||||
extern void __KAI_KMPC_CONVENTION kmp_set_library (int);
|
||||
extern void __KAI_KMPC_CONVENTION kmp_set_library_serial (void);
|
||||
extern void __KAI_KMPC_CONVENTION kmp_set_library_turnaround (void);
|
||||
extern void __KAI_KMPC_CONVENTION kmp_set_library_throughput (void);
|
||||
extern void __KAI_KMPC_CONVENTION kmp_set_defaults (char const *);
|
||||
extern void __KAI_KMPC_CONVENTION kmp_set_disp_num_buffers (int);
|
||||
|
||||
/* Intel affinity API */
|
||||
typedef void * kmp_affinity_mask_t;
|
||||
|
||||
extern int __KAI_KMPC_CONVENTION kmp_set_affinity (kmp_affinity_mask_t *);
|
||||
extern int __KAI_KMPC_CONVENTION kmp_get_affinity (kmp_affinity_mask_t *);
|
||||
extern int __KAI_KMPC_CONVENTION kmp_get_affinity_max_proc (void);
|
||||
extern void __KAI_KMPC_CONVENTION kmp_create_affinity_mask (kmp_affinity_mask_t *);
|
||||
extern void __KAI_KMPC_CONVENTION kmp_destroy_affinity_mask (kmp_affinity_mask_t *);
|
||||
extern int __KAI_KMPC_CONVENTION kmp_set_affinity_mask_proc (int, kmp_affinity_mask_t *);
|
||||
extern int __KAI_KMPC_CONVENTION kmp_unset_affinity_mask_proc (int, kmp_affinity_mask_t *);
|
||||
extern int __KAI_KMPC_CONVENTION kmp_get_affinity_mask_proc (int, kmp_affinity_mask_t *);
|
||||
|
||||
/* OpenMP 4.0 affinity API */
|
||||
typedef enum omp_proc_bind_t {
|
||||
omp_proc_bind_false = 0,
|
||||
omp_proc_bind_true = 1,
|
||||
omp_proc_bind_master = 2,
|
||||
omp_proc_bind_close = 3,
|
||||
omp_proc_bind_spread = 4
|
||||
} omp_proc_bind_t;
|
||||
|
||||
extern omp_proc_bind_t __KAI_KMPC_CONVENTION omp_get_proc_bind (void);
|
||||
|
||||
/* OpenMP 4.5 affinity API */
|
||||
extern int __KAI_KMPC_CONVENTION omp_get_num_places (void);
|
||||
extern int __KAI_KMPC_CONVENTION omp_get_place_num_procs (int);
|
||||
extern void __KAI_KMPC_CONVENTION omp_get_place_proc_ids (int, int *);
|
||||
extern int __KAI_KMPC_CONVENTION omp_get_place_num (void);
|
||||
extern int __KAI_KMPC_CONVENTION omp_get_partition_num_places (void);
|
||||
extern void __KAI_KMPC_CONVENTION omp_get_partition_place_nums (int *);
|
||||
|
||||
extern void * __KAI_KMPC_CONVENTION kmp_malloc (size_t);
|
||||
extern void * __KAI_KMPC_CONVENTION kmp_aligned_malloc (size_t, size_t);
|
||||
extern void * __KAI_KMPC_CONVENTION kmp_calloc (size_t, size_t);
|
||||
extern void * __KAI_KMPC_CONVENTION kmp_realloc (void *, size_t);
|
||||
extern void __KAI_KMPC_CONVENTION kmp_free (void *);
|
||||
|
||||
extern void __KAI_KMPC_CONVENTION kmp_set_warnings_on(void);
|
||||
extern void __KAI_KMPC_CONVENTION kmp_set_warnings_off(void);
|
||||
|
||||
# undef __KAI_KMPC_CONVENTION
|
||||
|
||||
/* Warning:
|
||||
The following typedefs are not standard, deprecated and will be removed in a future release.
|
||||
*/
|
||||
typedef int omp_int_t;
|
||||
typedef double omp_wtime_t;
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
|
||||
#endif /* __OMP_H */
|
||||
|
||||
@@ -0,0 +1,855 @@
|
||||
! include/50/omp_lib.f.var
|
||||
|
||||
!
|
||||
!//===----------------------------------------------------------------------===//
|
||||
!//
|
||||
!// The LLVM Compiler Infrastructure
|
||||
!//
|
||||
!// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
!// Source Licenses. See LICENSE.txt for details.
|
||||
!//
|
||||
!//===----------------------------------------------------------------------===//
|
||||
!
|
||||
|
||||
!***
|
||||
!*** Some of the directives for the following routine extend past column 72,
|
||||
!*** so process this file in 132-column mode.
|
||||
!***
|
||||
|
||||
!dec$ fixedformlinesize:132
|
||||
|
||||
module omp_lib_kinds
|
||||
|
||||
integer, parameter :: omp_integer_kind = 4
|
||||
integer, parameter :: omp_logical_kind = 4
|
||||
integer, parameter :: omp_real_kind = 4
|
||||
integer, parameter :: omp_lock_kind = int_ptr_kind()
|
||||
integer, parameter :: omp_nest_lock_kind = int_ptr_kind()
|
||||
integer, parameter :: omp_sched_kind = omp_integer_kind
|
||||
integer, parameter :: omp_proc_bind_kind = omp_integer_kind
|
||||
integer, parameter :: kmp_pointer_kind = int_ptr_kind()
|
||||
integer, parameter :: kmp_size_t_kind = int_ptr_kind()
|
||||
integer, parameter :: kmp_affinity_mask_kind = int_ptr_kind()
|
||||
integer, parameter :: kmp_cancel_kind = omp_integer_kind
|
||||
integer, parameter :: omp_lock_hint_kind = omp_integer_kind
|
||||
|
||||
end module omp_lib_kinds
|
||||
|
||||
module omp_lib
|
||||
|
||||
use omp_lib_kinds
|
||||
|
||||
integer (kind=omp_integer_kind), parameter :: kmp_version_major = @LIBOMP_VERSION_MAJOR@
|
||||
integer (kind=omp_integer_kind), parameter :: kmp_version_minor = @LIBOMP_VERSION_MINOR@
|
||||
integer (kind=omp_integer_kind), parameter :: kmp_version_build = @LIBOMP_VERSION_BUILD@
|
||||
character(*), parameter :: kmp_build_date = '@LIBOMP_BUILD_DATE@'
|
||||
integer (kind=omp_integer_kind), parameter :: openmp_version = @LIBOMP_OMP_YEAR_MONTH@
|
||||
|
||||
integer(kind=omp_sched_kind), parameter :: omp_sched_static = 1
|
||||
integer(kind=omp_sched_kind), parameter :: omp_sched_dynamic = 2
|
||||
integer(kind=omp_sched_kind), parameter :: omp_sched_guided = 3
|
||||
integer(kind=omp_sched_kind), parameter :: omp_sched_auto = 4
|
||||
|
||||
integer (kind=omp_proc_bind_kind), parameter :: omp_proc_bind_false = 0
|
||||
integer (kind=omp_proc_bind_kind), parameter :: omp_proc_bind_true = 1
|
||||
integer (kind=omp_proc_bind_kind), parameter :: omp_proc_bind_master = 2
|
||||
integer (kind=omp_proc_bind_kind), parameter :: omp_proc_bind_close = 3
|
||||
integer (kind=omp_proc_bind_kind), parameter :: omp_proc_bind_spread = 4
|
||||
|
||||
integer (kind=kmp_cancel_kind), parameter :: kmp_cancel_parallel = 1
|
||||
integer (kind=kmp_cancel_kind), parameter :: kmp_cancel_loop = 2
|
||||
integer (kind=kmp_cancel_kind), parameter :: kmp_cancel_sections = 3
|
||||
integer (kind=kmp_cancel_kind), parameter :: kmp_cancel_taskgroup = 4
|
||||
|
||||
integer (kind=omp_lock_hint_kind), parameter :: omp_lock_hint_none = 0
|
||||
integer (kind=omp_lock_hint_kind), parameter :: omp_lock_hint_uncontended = 1
|
||||
integer (kind=omp_lock_hint_kind), parameter :: omp_lock_hint_contended = 2
|
||||
integer (kind=omp_lock_hint_kind), parameter :: omp_lock_hint_nonspeculative = 4
|
||||
integer (kind=omp_lock_hint_kind), parameter :: omp_lock_hint_speculative = 8
|
||||
integer (kind=omp_lock_hint_kind), parameter :: kmp_lock_hint_hle = 65536
|
||||
integer (kind=omp_lock_hint_kind), parameter :: kmp_lock_hint_rtm = 131072
|
||||
integer (kind=omp_lock_hint_kind), parameter :: kmp_lock_hint_adaptive = 262144
|
||||
|
||||
interface
|
||||
|
||||
! ***
|
||||
! *** omp_* entry points
|
||||
! ***
|
||||
|
||||
subroutine omp_set_num_threads(num_threads)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) num_threads
|
||||
end subroutine omp_set_num_threads
|
||||
|
||||
subroutine omp_set_dynamic(dynamic_threads)
|
||||
use omp_lib_kinds
|
||||
logical (kind=omp_logical_kind) dynamic_threads
|
||||
end subroutine omp_set_dynamic
|
||||
|
||||
subroutine omp_set_nested(nested)
|
||||
use omp_lib_kinds
|
||||
logical (kind=omp_logical_kind) nested
|
||||
end subroutine omp_set_nested
|
||||
|
||||
function omp_get_num_threads()
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_get_num_threads
|
||||
end function omp_get_num_threads
|
||||
|
||||
function omp_get_max_threads()
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_get_max_threads
|
||||
end function omp_get_max_threads
|
||||
|
||||
function omp_get_thread_num()
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_get_thread_num
|
||||
end function omp_get_thread_num
|
||||
|
||||
function omp_get_num_procs()
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_get_num_procs
|
||||
end function omp_get_num_procs
|
||||
|
||||
function omp_in_parallel()
|
||||
use omp_lib_kinds
|
||||
logical (kind=omp_logical_kind) omp_in_parallel
|
||||
end function omp_in_parallel
|
||||
|
||||
function omp_in_final()
|
||||
use omp_lib_kinds
|
||||
logical (kind=omp_logical_kind) omp_in_final
|
||||
end function omp_in_final
|
||||
|
||||
function omp_get_dynamic()
|
||||
use omp_lib_kinds
|
||||
logical (kind=omp_logical_kind) omp_get_dynamic
|
||||
end function omp_get_dynamic
|
||||
|
||||
function omp_get_nested()
|
||||
use omp_lib_kinds
|
||||
logical (kind=omp_logical_kind) omp_get_nested
|
||||
end function omp_get_nested
|
||||
|
||||
function omp_get_thread_limit()
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_get_thread_limit
|
||||
end function omp_get_thread_limit
|
||||
|
||||
subroutine omp_set_max_active_levels(max_levels)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) max_levels
|
||||
end subroutine omp_set_max_active_levels
|
||||
|
||||
function omp_get_max_active_levels()
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_get_max_active_levels
|
||||
end function omp_get_max_active_levels
|
||||
|
||||
function omp_get_level()
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_get_level
|
||||
end function omp_get_level
|
||||
|
||||
function omp_get_active_level()
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_get_active_level
|
||||
end function omp_get_active_level
|
||||
|
||||
function omp_get_ancestor_thread_num(level)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) level
|
||||
integer (kind=omp_integer_kind) omp_get_ancestor_thread_num
|
||||
end function omp_get_ancestor_thread_num
|
||||
|
||||
function omp_get_team_size(level)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) level
|
||||
integer (kind=omp_integer_kind) omp_get_team_size
|
||||
end function omp_get_team_size
|
||||
|
||||
subroutine omp_set_schedule(kind, chunk_size)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_sched_kind) kind
|
||||
integer (kind=omp_integer_kind) chunk_size
|
||||
end subroutine omp_set_schedule
|
||||
|
||||
subroutine omp_get_schedule(kind, chunk_size)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_sched_kind) kind
|
||||
integer (kind=omp_integer_kind) chunk_size
|
||||
end subroutine omp_get_schedule
|
||||
|
||||
function omp_get_proc_bind()
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_proc_bind_kind) omp_get_proc_bind
|
||||
end function omp_get_proc_bind
|
||||
|
||||
function omp_get_num_places()
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_get_num_places
|
||||
end function omp_get_num_places
|
||||
|
||||
function omp_get_place_num_procs(place_num)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) place_num
|
||||
integer (kind=omp_integer_kind) omp_get_place_num_procs
|
||||
end function omp_get_place_num_procs
|
||||
|
||||
subroutine omp_get_place_proc_ids(place_num, ids)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) place_num
|
||||
integer (kind=kmp_pointer_kind) ids(*)
|
||||
end subroutine omp_get_place_proc_ids
|
||||
|
||||
function omp_get_place_num()
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_get_place_num
|
||||
end function omp_get_place_num
|
||||
|
||||
function omp_get_partition_num_places()
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_get_partition_num_places
|
||||
end function omp_get_partition_num_places
|
||||
|
||||
subroutine omp_get_partition_place_nums(place_nums)
|
||||
use omp_lib_kinds
|
||||
integer (kind=kmp_pointer_kind) place_nums(*)
|
||||
end subroutine omp_get_partition_place_nums
|
||||
|
||||
function omp_get_wtime()
|
||||
double precision omp_get_wtime
|
||||
end function omp_get_wtime
|
||||
|
||||
function omp_get_wtick ()
|
||||
double precision omp_get_wtick
|
||||
end function omp_get_wtick
|
||||
|
||||
function omp_get_default_device()
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_get_default_device
|
||||
end function omp_get_default_device
|
||||
|
||||
subroutine omp_set_default_device(device_num)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) device_num
|
||||
end subroutine omp_set_default_device
|
||||
|
||||
function omp_get_num_devices()
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_get_num_devices
|
||||
end function omp_get_num_devices
|
||||
|
||||
function omp_get_num_teams()
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_get_num_teams
|
||||
end function omp_get_num_teams
|
||||
|
||||
function omp_get_team_num()
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_get_team_num
|
||||
end function omp_get_team_num
|
||||
|
||||
function omp_get_cancellation()
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_get_cancellation
|
||||
end function omp_get_cancellation
|
||||
|
||||
function omp_is_initial_device()
|
||||
use omp_lib_kinds
|
||||
logical (kind=omp_logical_kind) omp_is_initial_device
|
||||
end function omp_is_initial_device
|
||||
|
||||
function omp_get_initial_device()
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_get_initial_device
|
||||
end function omp_get_initial_device
|
||||
|
||||
subroutine omp_init_lock(svar)
|
||||
!DIR$ IF(__INTEL_COMPILER.GE.1400)
|
||||
!DIR$ attributes known_intrinsic :: omp_init_lock
|
||||
!DIR$ ENDIF
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_lock_kind) svar
|
||||
end subroutine omp_init_lock
|
||||
|
||||
subroutine omp_destroy_lock(svar)
|
||||
!DIR$ IF(__INTEL_COMPILER.GE.1400)
|
||||
!DIR$ attributes known_intrinsic :: omp_destroy_lock
|
||||
!DIR$ ENDIF
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_lock_kind) svar
|
||||
end subroutine omp_destroy_lock
|
||||
|
||||
subroutine omp_set_lock(svar)
|
||||
!DIR$ IF(__INTEL_COMPILER.GE.1400)
|
||||
!DIR$ attributes known_intrinsic :: omp_set_lock
|
||||
!DIR$ ENDIF
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_lock_kind) svar
|
||||
end subroutine omp_set_lock
|
||||
|
||||
subroutine omp_unset_lock(svar)
|
||||
!DIR$ IF(__INTEL_COMPILER.GE.1400)
|
||||
!DIR$ attributes known_intrinsic :: omp_unset_lock
|
||||
!DIR$ ENDIF
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_lock_kind) svar
|
||||
end subroutine omp_unset_lock
|
||||
|
||||
function omp_test_lock(svar)
|
||||
!DIR$ IF(__INTEL_COMPILER.GE.1400)
|
||||
!DIR$ attributes known_intrinsic :: omp_test_lock
|
||||
!DIR$ ENDIF
|
||||
use omp_lib_kinds
|
||||
logical (kind=omp_logical_kind) omp_test_lock
|
||||
integer (kind=omp_lock_kind) svar
|
||||
end function omp_test_lock
|
||||
|
||||
subroutine omp_init_nest_lock(nvar)
|
||||
!DIR$ IF(__INTEL_COMPILER.GE.1400)
|
||||
!DIR$ attributes known_intrinsic :: omp_init_nest_lock
|
||||
!DIR$ ENDIF
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_nest_lock_kind) nvar
|
||||
end subroutine omp_init_nest_lock
|
||||
|
||||
subroutine omp_destroy_nest_lock(nvar)
|
||||
!DIR$ IF(__INTEL_COMPILER.GE.1400)
|
||||
!DIR$ attributes known_intrinsic :: omp_destroy_nest_lock
|
||||
!DIR$ ENDIF
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_nest_lock_kind) nvar
|
||||
end subroutine omp_destroy_nest_lock
|
||||
|
||||
subroutine omp_set_nest_lock(nvar)
|
||||
!DIR$ IF(__INTEL_COMPILER.GE.1400)
|
||||
!DIR$ attributes known_intrinsic :: omp_set_nest_lock
|
||||
!DIR$ ENDIF
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_nest_lock_kind) nvar
|
||||
end subroutine omp_set_nest_lock
|
||||
|
||||
subroutine omp_unset_nest_lock(nvar)
|
||||
!DIR$ IF(__INTEL_COMPILER.GE.1400)
|
||||
!DIR$ attributes known_intrinsic :: omp_unset_nest_lock
|
||||
!DIR$ ENDIF
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_nest_lock_kind) nvar
|
||||
end subroutine omp_unset_nest_lock
|
||||
|
||||
function omp_test_nest_lock(nvar)
|
||||
!DIR$ IF(__INTEL_COMPILER.GE.1400)
|
||||
!DIR$ attributes known_intrinsic :: omp_test_nest_lock
|
||||
!DIR$ ENDIF
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_test_nest_lock
|
||||
integer (kind=omp_nest_lock_kind) nvar
|
||||
end function omp_test_nest_lock
|
||||
|
||||
function omp_get_max_task_priority()
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_get_max_task_priority
|
||||
end function omp_get_max_task_priority
|
||||
|
||||
! ***
|
||||
! *** kmp_* entry points
|
||||
! ***
|
||||
|
||||
subroutine kmp_set_stacksize(size)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) size
|
||||
end subroutine kmp_set_stacksize
|
||||
|
||||
subroutine kmp_set_stacksize_s(size)
|
||||
use omp_lib_kinds
|
||||
integer (kind=kmp_size_t_kind) size
|
||||
end subroutine kmp_set_stacksize_s
|
||||
|
||||
subroutine kmp_set_blocktime(msec)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) msec
|
||||
end subroutine kmp_set_blocktime
|
||||
|
||||
subroutine kmp_set_library_serial()
|
||||
end subroutine kmp_set_library_serial
|
||||
|
||||
subroutine kmp_set_library_turnaround()
|
||||
end subroutine kmp_set_library_turnaround
|
||||
|
||||
subroutine kmp_set_library_throughput()
|
||||
end subroutine kmp_set_library_throughput
|
||||
|
||||
subroutine kmp_set_library(libnum)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) libnum
|
||||
end subroutine kmp_set_library
|
||||
|
||||
subroutine kmp_set_defaults(string)
|
||||
character*(*) string
|
||||
end subroutine kmp_set_defaults
|
||||
|
||||
function kmp_get_stacksize()
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) kmp_get_stacksize
|
||||
end function kmp_get_stacksize
|
||||
|
||||
function kmp_get_stacksize_s()
|
||||
use omp_lib_kinds
|
||||
integer (kind=kmp_size_t_kind) kmp_get_stacksize_s
|
||||
end function kmp_get_stacksize_s
|
||||
|
||||
function kmp_get_blocktime()
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) kmp_get_blocktime
|
||||
end function kmp_get_blocktime
|
||||
|
||||
function kmp_get_library()
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) kmp_get_library
|
||||
end function kmp_get_library
|
||||
|
||||
subroutine kmp_set_disp_num_buffers(num)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) num
|
||||
end subroutine kmp_set_disp_num_buffers
|
||||
|
||||
function kmp_set_affinity(mask)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) kmp_set_affinity
|
||||
integer (kind=kmp_affinity_mask_kind) mask
|
||||
end function kmp_set_affinity
|
||||
|
||||
function kmp_get_affinity(mask)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) kmp_get_affinity
|
||||
integer (kind=kmp_affinity_mask_kind) mask
|
||||
end function kmp_get_affinity
|
||||
|
||||
function kmp_get_affinity_max_proc()
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) kmp_get_affinity_max_proc
|
||||
end function kmp_get_affinity_max_proc
|
||||
|
||||
subroutine kmp_create_affinity_mask(mask)
|
||||
use omp_lib_kinds
|
||||
integer (kind=kmp_affinity_mask_kind) mask
|
||||
end subroutine kmp_create_affinity_mask
|
||||
|
||||
subroutine kmp_destroy_affinity_mask(mask)
|
||||
use omp_lib_kinds
|
||||
integer (kind=kmp_affinity_mask_kind) mask
|
||||
end subroutine kmp_destroy_affinity_mask
|
||||
|
||||
function kmp_set_affinity_mask_proc(proc, mask)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) kmp_set_affinity_mask_proc
|
||||
integer (kind=omp_integer_kind) proc
|
||||
integer (kind=kmp_affinity_mask_kind) mask
|
||||
end function kmp_set_affinity_mask_proc
|
||||
|
||||
function kmp_unset_affinity_mask_proc(proc, mask)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) kmp_unset_affinity_mask_proc
|
||||
integer (kind=omp_integer_kind) proc
|
||||
integer (kind=kmp_affinity_mask_kind) mask
|
||||
end function kmp_unset_affinity_mask_proc
|
||||
|
||||
function kmp_get_affinity_mask_proc(proc, mask)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) kmp_get_affinity_mask_proc
|
||||
integer (kind=omp_integer_kind) proc
|
||||
integer (kind=kmp_affinity_mask_kind) mask
|
||||
end function kmp_get_affinity_mask_proc
|
||||
|
||||
function kmp_malloc(size)
|
||||
use omp_lib_kinds
|
||||
integer (kind=kmp_pointer_kind) kmp_malloc
|
||||
integer (kind=kmp_size_t_kind) size
|
||||
end function kmp_malloc
|
||||
|
||||
function kmp_aligned_malloc(size, alignment)
|
||||
use omp_lib_kinds
|
||||
integer (kind=kmp_pointer_kind) kmp_aligned_malloc
|
||||
integer (kind=kmp_size_t_kind) size
|
||||
integer (kind=kmp_size_t_kind) alignment
|
||||
end function kmp_aligned_malloc
|
||||
|
||||
function kmp_calloc(nelem, elsize)
|
||||
use omp_lib_kinds
|
||||
integer (kind=kmp_pointer_kind) kmp_calloc
|
||||
integer (kind=kmp_size_t_kind) nelem
|
||||
integer (kind=kmp_size_t_kind) elsize
|
||||
end function kmp_calloc
|
||||
|
||||
function kmp_realloc(ptr, size)
|
||||
use omp_lib_kinds
|
||||
integer (kind=kmp_pointer_kind) kmp_realloc
|
||||
integer (kind=kmp_pointer_kind) ptr
|
||||
integer (kind=kmp_size_t_kind) size
|
||||
end function kmp_realloc
|
||||
|
||||
subroutine kmp_free(ptr)
|
||||
use omp_lib_kinds
|
||||
integer (kind=kmp_pointer_kind) ptr
|
||||
end subroutine kmp_free
|
||||
|
||||
subroutine kmp_set_warnings_on()
|
||||
end subroutine kmp_set_warnings_on
|
||||
|
||||
subroutine kmp_set_warnings_off()
|
||||
end subroutine kmp_set_warnings_off
|
||||
|
||||
function kmp_get_cancellation_status(cancelkind)
|
||||
use omp_lib_kinds
|
||||
integer (kind=kmp_cancel_kind) cancelkind
|
||||
logical (kind=omp_logical_kind) kmp_get_cancellation_status
|
||||
end function kmp_get_cancellation_status
|
||||
|
||||
subroutine omp_init_lock_with_hint(svar, hint)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_lock_kind) svar
|
||||
integer (kind=omp_lock_hint_kind) hint
|
||||
end subroutine omp_init_lock_with_hint
|
||||
|
||||
subroutine omp_init_nest_lock_with_hint(nvar, hint)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_nest_lock_kind) nvar
|
||||
integer (kind=omp_lock_hint_kind) hint
|
||||
end subroutine omp_init_nest_lock_with_hint
|
||||
|
||||
end interface
|
||||
|
||||
!dec$ if defined(_WIN32)
|
||||
!dec$ if defined(_WIN64) .or. defined(_M_AMD64)
|
||||
|
||||
!***
|
||||
!*** The Fortran entry points must be in uppercase, even if the /Qlowercase
|
||||
!*** option is specified. The alias attribute ensures that the specified
|
||||
!*** string is used as the entry point.
|
||||
!***
|
||||
!*** On the Windows* OS IA-32 architecture, the Fortran entry points have an
|
||||
!*** underscore prepended. On the Windows* OS Intel(R) 64
|
||||
!*** architecture, no underscore is prepended.
|
||||
!***
|
||||
|
||||
!dec$ attributes alias:'OMP_SET_NUM_THREADS' :: omp_set_num_threads
|
||||
!dec$ attributes alias:'OMP_SET_DYNAMIC' :: omp_set_dynamic
|
||||
!dec$ attributes alias:'OMP_SET_NESTED' :: omp_set_nested
|
||||
!dec$ attributes alias:'OMP_GET_NUM_THREADS' :: omp_get_num_threads
|
||||
!dec$ attributes alias:'OMP_GET_MAX_THREADS' :: omp_get_max_threads
|
||||
!dec$ attributes alias:'OMP_GET_THREAD_NUM' :: omp_get_thread_num
|
||||
!dec$ attributes alias:'OMP_GET_NUM_PROCS' :: omp_get_num_procs
|
||||
!dec$ attributes alias:'OMP_IN_PARALLEL' :: omp_in_parallel
|
||||
!dec$ attributes alias:'OMP_GET_DYNAMIC' :: omp_get_dynamic
|
||||
!dec$ attributes alias:'OMP_GET_NESTED' :: omp_get_nested
|
||||
!dec$ attributes alias:'OMP_GET_THREAD_LIMIT' :: omp_get_thread_limit
|
||||
!dec$ attributes alias:'OMP_SET_MAX_ACTIVE_LEVELS' :: omp_set_max_active_levels
|
||||
!dec$ attributes alias:'OMP_GET_MAX_ACTIVE_LEVELS' :: omp_get_max_active_levels
|
||||
!dec$ attributes alias:'OMP_GET_LEVEL' :: omp_get_level
|
||||
!dec$ attributes alias:'OMP_GET_ACTIVE_LEVEL' :: omp_get_active_level
|
||||
!dec$ attributes alias:'OMP_GET_ANCESTOR_THREAD_NUM' :: omp_get_ancestor_thread_num
|
||||
!dec$ attributes alias:'OMP_GET_TEAM_SIZE' :: omp_get_team_size
|
||||
!dec$ attributes alias:'OMP_SET_SCHEDULE' :: omp_set_schedule
|
||||
!dec$ attributes alias:'OMP_GET_SCHEDULE' :: omp_get_schedule
|
||||
!dec$ attributes alias:'OMP_GET_PROC_BIND' :: omp_get_proc_bind
|
||||
!dec$ attributes alias:'OMP_GET_WTIME' :: omp_get_wtime
|
||||
!dec$ attributes alias:'OMP_GET_WTICK' :: omp_get_wtick
|
||||
!dec$ attributes alias:'OMP_GET_DEFAULT_DEVICE' :: omp_get_default_device
|
||||
!dec$ attributes alias:'OMP_SET_DEFAULT_DEVICE' :: omp_set_default_device
|
||||
!dec$ attributes alias:'OMP_GET_NUM_DEVICES' :: omp_get_num_devices
|
||||
!dec$ attributes alias:'OMP_GET_NUM_TEAMS' :: omp_get_num_teams
|
||||
!dec$ attributes alias:'OMP_GET_TEAM_NUM' :: omp_get_team_num
|
||||
!dec$ attributes alias:'OMP_GET_CANCELLATION' :: omp_get_cancellation
|
||||
!dec$ attributes alias:'OMP_IS_INITIAL_DEVICE' :: omp_is_initial_device
|
||||
!dec$ attributes alias:'OMP_GET_MAX_TASK_PRIORITY' :: omp_get_max_task_priority
|
||||
|
||||
!dec$ attributes alias:'omp_init_lock' :: omp_init_lock
|
||||
!dec$ attributes alias:'omp_init_lock_with_hint' :: omp_init_lock_with_hint
|
||||
!dec$ attributes alias:'omp_destroy_lock' :: omp_destroy_lock
|
||||
!dec$ attributes alias:'omp_set_lock' :: omp_set_lock
|
||||
!dec$ attributes alias:'omp_unset_lock' :: omp_unset_lock
|
||||
!dec$ attributes alias:'omp_test_lock' :: omp_test_lock
|
||||
!dec$ attributes alias:'omp_init_nest_lock' :: omp_init_nest_lock
|
||||
!dec$ attributes alias:'omp_init_nest_lock_with_hint' :: omp_init_nest_lock_with_hint
|
||||
!dec$ attributes alias:'omp_destroy_nest_lock' :: omp_destroy_nest_lock
|
||||
!dec$ attributes alias:'omp_set_nest_lock' :: omp_set_nest_lock
|
||||
!dec$ attributes alias:'omp_unset_nest_lock' :: omp_unset_nest_lock
|
||||
!dec$ attributes alias:'omp_test_nest_lock' :: omp_test_nest_lock
|
||||
|
||||
!dec$ attributes alias:'KMP_SET_STACKSIZE'::kmp_set_stacksize
|
||||
!dec$ attributes alias:'KMP_SET_STACKSIZE_S'::kmp_set_stacksize_s
|
||||
!dec$ attributes alias:'KMP_SET_BLOCKTIME'::kmp_set_blocktime
|
||||
!dec$ attributes alias:'KMP_SET_LIBRARY_SERIAL'::kmp_set_library_serial
|
||||
!dec$ attributes alias:'KMP_SET_LIBRARY_TURNAROUND'::kmp_set_library_turnaround
|
||||
!dec$ attributes alias:'KMP_SET_LIBRARY_THROUGHPUT'::kmp_set_library_throughput
|
||||
!dec$ attributes alias:'KMP_SET_LIBRARY'::kmp_set_library
|
||||
!dec$ attributes alias:'KMP_GET_STACKSIZE'::kmp_get_stacksize
|
||||
!dec$ attributes alias:'KMP_GET_STACKSIZE_S'::kmp_get_stacksize_s
|
||||
!dec$ attributes alias:'KMP_GET_BLOCKTIME'::kmp_get_blocktime
|
||||
!dec$ attributes alias:'KMP_GET_LIBRARY'::kmp_get_library
|
||||
!dec$ attributes alias:'KMP_SET_AFFINITY'::kmp_set_affinity
|
||||
!dec$ attributes alias:'KMP_GET_AFFINITY'::kmp_get_affinity
|
||||
!dec$ attributes alias:'KMP_GET_AFFINITY_MAX_PROC'::kmp_get_affinity_max_proc
|
||||
!dec$ attributes alias:'KMP_CREATE_AFFINITY_MASK'::kmp_create_affinity_mask
|
||||
!dec$ attributes alias:'KMP_DESTROY_AFFINITY_MASK'::kmp_destroy_affinity_mask
|
||||
!dec$ attributes alias:'KMP_SET_AFFINITY_MASK_PROC'::kmp_set_affinity_mask_proc
|
||||
!dec$ attributes alias:'KMP_UNSET_AFFINITY_MASK_PROC'::kmp_unset_affinity_mask_proc
|
||||
!dec$ attributes alias:'KMP_GET_AFFINITY_MASK_PROC'::kmp_get_affinity_mask_proc
|
||||
!dec$ attributes alias:'KMP_MALLOC'::kmp_malloc
|
||||
!dec$ attributes alias:'KMP_ALIGNED_MALLOC'::kmp_aligned_malloc
|
||||
!dec$ attributes alias:'KMP_CALLOC'::kmp_calloc
|
||||
!dec$ attributes alias:'KMP_REALLOC'::kmp_realloc
|
||||
!dec$ attributes alias:'KMP_FREE'::kmp_free
|
||||
|
||||
!dec$ attributes alias:'KMP_SET_WARNINGS_ON'::kmp_set_warnings_on
|
||||
!dec$ attributes alias:'KMP_SET_WARNINGS_OFF'::kmp_set_warnings_off
|
||||
|
||||
!dec$ attributes alias:'KMP_GET_CANCELLATION_STATUS' :: kmp_get_cancellation_status
|
||||
|
||||
!dec$ else
|
||||
|
||||
!***
|
||||
!*** On Windows* OS IA-32 architecture, the Fortran entry points have an underscore prepended.
|
||||
!***
|
||||
|
||||
!dec$ attributes alias:'_OMP_SET_NUM_THREADS' :: omp_set_num_threads
|
||||
!dec$ attributes alias:'_OMP_SET_DYNAMIC' :: omp_set_dynamic
|
||||
!dec$ attributes alias:'_OMP_SET_NESTED' :: omp_set_nested
|
||||
!dec$ attributes alias:'_OMP_GET_NUM_THREADS' :: omp_get_num_threads
|
||||
!dec$ attributes alias:'_OMP_GET_MAX_THREADS' :: omp_get_max_threads
|
||||
!dec$ attributes alias:'_OMP_GET_THREAD_NUM' :: omp_get_thread_num
|
||||
!dec$ attributes alias:'_OMP_GET_NUM_PROCS' :: omp_get_num_procs
|
||||
!dec$ attributes alias:'_OMP_IN_PARALLEL' :: omp_in_parallel
|
||||
!dec$ attributes alias:'_OMP_GET_DYNAMIC' :: omp_get_dynamic
|
||||
!dec$ attributes alias:'_OMP_GET_NESTED' :: omp_get_nested
|
||||
!dec$ attributes alias:'_OMP_GET_THREAD_LIMIT' :: omp_get_thread_limit
|
||||
!dec$ attributes alias:'_OMP_SET_MAX_ACTIVE_LEVELS' :: omp_set_max_active_levels
|
||||
!dec$ attributes alias:'_OMP_GET_MAX_ACTIVE_LEVELS' :: omp_get_max_active_levels
|
||||
!dec$ attributes alias:'_OMP_GET_LEVEL' :: omp_get_level
|
||||
!dec$ attributes alias:'_OMP_GET_ACTIVE_LEVEL' :: omp_get_active_level
|
||||
!dec$ attributes alias:'_OMP_GET_ANCESTOR_THREAD_NUM' :: omp_get_ancestor_thread_num
|
||||
!dec$ attributes alias:'_OMP_GET_TEAM_SIZE' :: omp_get_team_size
|
||||
!dec$ attributes alias:'_OMP_SET_SCHEDULE' :: omp_set_schedule
|
||||
!dec$ attributes alias:'_OMP_GET_SCHEDULE' :: omp_get_schedule
|
||||
!dec$ attributes alias:'_OMP_GET_PROC_BIND' :: omp_get_proc_bind
|
||||
!dec$ attributes alias:'_OMP_GET_WTIME' :: omp_get_wtime
|
||||
!dec$ attributes alias:'_OMP_GET_WTICK' :: omp_get_wtick
|
||||
!dec$ attributes alias:'_OMP_GET_DEFAULT_DEVICE' :: omp_get_default_device
|
||||
!dec$ attributes alias:'_OMP_SET_DEFAULT_DEVICE' :: omp_set_default_device
|
||||
!dec$ attributes alias:'_OMP_GET_NUM_DEVICES' :: omp_get_num_devices
|
||||
!dec$ attributes alias:'_OMP_GET_NUM_TEAMS' :: omp_get_num_teams
|
||||
!dec$ attributes alias:'_OMP_GET_TEAM_NUM' :: omp_get_team_num
|
||||
!dec$ attributes alias:'_OMP_GET_CANCELLATION' :: omp_get_cancellation
|
||||
!dec$ attributes alias:'_OMP_IS_INITIAL_DEVICE' :: omp_is_initial_device
|
||||
!dec$ attributes alias:'_OMP_GET_MAX_TASK_PRIORTY' :: omp_get_max_task_priority
|
||||
|
||||
!dec$ attributes alias:'_omp_init_lock' :: omp_init_lock
|
||||
!dec$ attributes alias:'_omp_init_lock_with_hint' :: omp_init_lock_with_hint
|
||||
!dec$ attributes alias:'_omp_destroy_lock' :: omp_destroy_lock
|
||||
!dec$ attributes alias:'_omp_set_lock' :: omp_set_lock
|
||||
!dec$ attributes alias:'_omp_unset_lock' :: omp_unset_lock
|
||||
!dec$ attributes alias:'_omp_test_lock' :: omp_test_lock
|
||||
!dec$ attributes alias:'_omp_init_nest_lock' :: omp_init_nest_lock
|
||||
!dec$ attributes alias:'_omp_init_nest_lock_with_hint' :: omp_init_nest_lock_with_hint
|
||||
!dec$ attributes alias:'_omp_destroy_nest_lock' :: omp_destroy_nest_lock
|
||||
!dec$ attributes alias:'_omp_set_nest_lock' :: omp_set_nest_lock
|
||||
!dec$ attributes alias:'_omp_unset_nest_lock' :: omp_unset_nest_lock
|
||||
!dec$ attributes alias:'_omp_test_nest_lock' :: omp_test_nest_lock
|
||||
|
||||
!dec$ attributes alias:'_KMP_SET_STACKSIZE'::kmp_set_stacksize
|
||||
!dec$ attributes alias:'_KMP_SET_STACKSIZE_S'::kmp_set_stacksize_s
|
||||
!dec$ attributes alias:'_KMP_SET_BLOCKTIME'::kmp_set_blocktime
|
||||
!dec$ attributes alias:'_KMP_SET_LIBRARY_SERIAL'::kmp_set_library_serial
|
||||
!dec$ attributes alias:'_KMP_SET_LIBRARY_TURNAROUND'::kmp_set_library_turnaround
|
||||
!dec$ attributes alias:'_KMP_SET_LIBRARY_THROUGHPUT'::kmp_set_library_throughput
|
||||
!dec$ attributes alias:'_KMP_SET_LIBRARY'::kmp_set_library
|
||||
!dec$ attributes alias:'_KMP_GET_STACKSIZE'::kmp_get_stacksize
|
||||
!dec$ attributes alias:'_KMP_GET_STACKSIZE_S'::kmp_get_stacksize_s
|
||||
!dec$ attributes alias:'_KMP_GET_BLOCKTIME'::kmp_get_blocktime
|
||||
!dec$ attributes alias:'_KMP_GET_LIBRARY'::kmp_get_library
|
||||
!dec$ attributes alias:'_KMP_SET_AFFINITY'::kmp_set_affinity
|
||||
!dec$ attributes alias:'_KMP_GET_AFFINITY'::kmp_get_affinity
|
||||
!dec$ attributes alias:'_KMP_GET_AFFINITY_MAX_PROC'::kmp_get_affinity_max_proc
|
||||
!dec$ attributes alias:'_KMP_CREATE_AFFINITY_MASK'::kmp_create_affinity_mask
|
||||
!dec$ attributes alias:'_KMP_DESTROY_AFFINITY_MASK'::kmp_destroy_affinity_mask
|
||||
!dec$ attributes alias:'_KMP_SET_AFFINITY_MASK_PROC'::kmp_set_affinity_mask_proc
|
||||
!dec$ attributes alias:'_KMP_UNSET_AFFINITY_MASK_PROC'::kmp_unset_affinity_mask_proc
|
||||
!dec$ attributes alias:'_KMP_GET_AFFINITY_MASK_PROC'::kmp_get_affinity_mask_proc
|
||||
!dec$ attributes alias:'_KMP_MALLOC'::kmp_malloc
|
||||
!dec$ attributes alias:'_KMP_ALIGNED_MALLOC'::kmp_aligned_malloc
|
||||
!dec$ attributes alias:'_KMP_CALLOC'::kmp_calloc
|
||||
!dec$ attributes alias:'_KMP_REALLOC'::kmp_realloc
|
||||
!dec$ attributes alias:'_KMP_FREE'::kmp_free
|
||||
|
||||
!dec$ attributes alias:'_KMP_SET_WARNINGS_ON'::kmp_set_warnings_on
|
||||
!dec$ attributes alias:'_KMP_SET_WARNINGS_OFF'::kmp_set_warnings_off
|
||||
|
||||
!dec$ attributes alias:'_KMP_GET_CANCELLATION_STATUS' :: kmp_get_cancellation_status
|
||||
|
||||
!dec$ endif
|
||||
!dec$ endif
|
||||
|
||||
!dec$ if defined(__linux)
|
||||
|
||||
!***
|
||||
!*** The Linux* OS entry points are in lowercase, with an underscore appended.
|
||||
!***
|
||||
|
||||
!dec$ attributes alias:'omp_set_num_threads_'::omp_set_num_threads
|
||||
!dec$ attributes alias:'omp_set_dynamic_'::omp_set_dynamic
|
||||
!dec$ attributes alias:'omp_set_nested_'::omp_set_nested
|
||||
!dec$ attributes alias:'omp_get_num_threads_'::omp_get_num_threads
|
||||
!dec$ attributes alias:'omp_get_max_threads_'::omp_get_max_threads
|
||||
!dec$ attributes alias:'omp_get_thread_num_'::omp_get_thread_num
|
||||
!dec$ attributes alias:'omp_get_num_procs_'::omp_get_num_procs
|
||||
!dec$ attributes alias:'omp_in_parallel_'::omp_in_parallel
|
||||
!dec$ attributes alias:'omp_get_dynamic_'::omp_get_dynamic
|
||||
!dec$ attributes alias:'omp_get_nested_'::omp_get_nested
|
||||
!dec$ attributes alias:'omp_get_thread_limit_'::omp_get_thread_limit
|
||||
!dec$ attributes alias:'omp_set_max_active_levels_'::omp_set_max_active_levels
|
||||
!dec$ attributes alias:'omp_get_max_active_levels_'::omp_get_max_active_levels
|
||||
!dec$ attributes alias:'omp_get_level_'::omp_get_level
|
||||
!dec$ attributes alias:'omp_get_active_level_'::omp_get_active_level
|
||||
!dec$ attributes alias:'omp_get_ancestor_thread_num_'::omp_get_ancestor_thread_num
|
||||
!dec$ attributes alias:'omp_get_team_size_'::omp_get_team_size
|
||||
!dec$ attributes alias:'omp_set_schedule_'::omp_set_schedule
|
||||
!dec$ attributes alias:'omp_get_schedule_'::omp_get_schedule
|
||||
!dec$ attributes alias:'omp_get_proc_bind_' :: omp_get_proc_bind
|
||||
!dec$ attributes alias:'omp_get_wtime_'::omp_get_wtime
|
||||
!dec$ attributes alias:'omp_get_wtick_'::omp_get_wtick
|
||||
!dec$ attributes alias:'omp_get_default_device_'::omp_get_default_device
|
||||
!dec$ attributes alias:'omp_set_default_device_'::omp_set_default_device
|
||||
!dec$ attributes alias:'omp_get_num_devices_'::omp_get_num_devices
|
||||
!dec$ attributes alias:'omp_get_num_teams_'::omp_get_num_teams
|
||||
!dec$ attributes alias:'omp_get_team_num_'::omp_get_team_num
|
||||
!dec$ attributes alias:'omp_get_cancellation_'::omp_get_cancellation
|
||||
!dec$ attributes alias:'omp_is_initial_device_'::omp_is_initial_device
|
||||
!dec$ attributes alias:'omp_get_max_task_priority_'::omp_get_max_task_priority
|
||||
|
||||
!dec$ attributes alias:'omp_init_lock_'::omp_init_lock
|
||||
!dec$ attributes alias:'omp_init_lock_with_hint_'::omp_init_lock_with_hint
|
||||
!dec$ attributes alias:'omp_destroy_lock_'::omp_destroy_lock
|
||||
!dec$ attributes alias:'omp_set_lock_'::omp_set_lock
|
||||
!dec$ attributes alias:'omp_unset_lock_'::omp_unset_lock
|
||||
!dec$ attributes alias:'omp_test_lock_'::omp_test_lock
|
||||
!dec$ attributes alias:'omp_init_nest_lock_'::omp_init_nest_lock
|
||||
!dec$ attributes alias:'omp_init_nest_lock_with_hint_'::omp_init_nest_lock_with_hint
|
||||
!dec$ attributes alias:'omp_destroy_nest_lock_'::omp_destroy_nest_lock
|
||||
!dec$ attributes alias:'omp_set_nest_lock_'::omp_set_nest_lock
|
||||
!dec$ attributes alias:'omp_unset_nest_lock_'::omp_unset_nest_lock
|
||||
!dec$ attributes alias:'omp_test_nest_lock_'::omp_test_nest_lock
|
||||
|
||||
!dec$ attributes alias:'kmp_set_stacksize_'::kmp_set_stacksize
|
||||
!dec$ attributes alias:'kmp_set_stacksize_s_'::kmp_set_stacksize_s
|
||||
!dec$ attributes alias:'kmp_set_blocktime_'::kmp_set_blocktime
|
||||
!dec$ attributes alias:'kmp_set_library_serial_'::kmp_set_library_serial
|
||||
!dec$ attributes alias:'kmp_set_library_turnaround_'::kmp_set_library_turnaround
|
||||
!dec$ attributes alias:'kmp_set_library_throughput_'::kmp_set_library_throughput
|
||||
!dec$ attributes alias:'kmp_set_library_'::kmp_set_library
|
||||
!dec$ attributes alias:'kmp_get_stacksize_'::kmp_get_stacksize
|
||||
!dec$ attributes alias:'kmp_get_stacksize_s_'::kmp_get_stacksize_s
|
||||
!dec$ attributes alias:'kmp_get_blocktime_'::kmp_get_blocktime
|
||||
!dec$ attributes alias:'kmp_get_library_'::kmp_get_library
|
||||
!dec$ attributes alias:'kmp_set_affinity_'::kmp_set_affinity
|
||||
!dec$ attributes alias:'kmp_get_affinity_'::kmp_get_affinity
|
||||
!dec$ attributes alias:'kmp_get_affinity_max_proc_'::kmp_get_affinity_max_proc
|
||||
!dec$ attributes alias:'kmp_create_affinity_mask_'::kmp_create_affinity_mask
|
||||
!dec$ attributes alias:'kmp_destroy_affinity_mask_'::kmp_destroy_affinity_mask
|
||||
!dec$ attributes alias:'kmp_set_affinity_mask_proc_'::kmp_set_affinity_mask_proc
|
||||
!dec$ attributes alias:'kmp_unset_affinity_mask_proc_'::kmp_unset_affinity_mask_proc
|
||||
!dec$ attributes alias:'kmp_get_affinity_mask_proc_'::kmp_get_affinity_mask_proc
|
||||
!dec$ attributes alias:'kmp_malloc_'::kmp_malloc
|
||||
!dec$ attributes alias:'kmp_aligned_malloc_'::kmp_aligned_malloc
|
||||
!dec$ attributes alias:'kmp_calloc_'::kmp_calloc
|
||||
!dec$ attributes alias:'kmp_realloc_'::kmp_realloc
|
||||
!dec$ attributes alias:'kmp_free_'::kmp_free
|
||||
|
||||
!dec$ attributes alias:'kmp_set_warnings_on_'::kmp_set_warnings_on
|
||||
!dec$ attributes alias:'kmp_set_warnings_off_'::kmp_set_warnings_off
|
||||
!dec$ attributes alias:'kmp_get_cancellation_status_'::kmp_get_cancellation_status
|
||||
|
||||
!dec$ endif
|
||||
|
||||
!dec$ if defined(__APPLE__)
|
||||
|
||||
!***
|
||||
!*** The Mac entry points are in lowercase, with an both an underscore
|
||||
!*** appended and an underscore prepended.
|
||||
!***
|
||||
|
||||
!dec$ attributes alias:'_omp_set_num_threads_'::omp_set_num_threads
|
||||
!dec$ attributes alias:'_omp_set_dynamic_'::omp_set_dynamic
|
||||
!dec$ attributes alias:'_omp_set_nested_'::omp_set_nested
|
||||
!dec$ attributes alias:'_omp_get_num_threads_'::omp_get_num_threads
|
||||
!dec$ attributes alias:'_omp_get_max_threads_'::omp_get_max_threads
|
||||
!dec$ attributes alias:'_omp_get_thread_num_'::omp_get_thread_num
|
||||
!dec$ attributes alias:'_omp_get_num_procs_'::omp_get_num_procs
|
||||
!dec$ attributes alias:'_omp_in_parallel_'::omp_in_parallel
|
||||
!dec$ attributes alias:'_omp_get_dynamic_'::omp_get_dynamic
|
||||
!dec$ attributes alias:'_omp_get_nested_'::omp_get_nested
|
||||
!dec$ attributes alias:'_omp_get_thread_limit_'::omp_get_thread_limit
|
||||
!dec$ attributes alias:'_omp_set_max_active_levels_'::omp_set_max_active_levels
|
||||
!dec$ attributes alias:'_omp_get_max_active_levels_'::omp_get_max_active_levels
|
||||
!dec$ attributes alias:'_omp_get_level_'::omp_get_level
|
||||
!dec$ attributes alias:'_omp_get_active_level_'::omp_get_active_level
|
||||
!dec$ attributes alias:'_omp_get_ancestor_thread_num_'::omp_get_ancestor_thread_num
|
||||
!dec$ attributes alias:'_omp_get_team_size_'::omp_get_team_size
|
||||
!dec$ attributes alias:'_omp_set_schedule_'::omp_set_schedule
|
||||
!dec$ attributes alias:'_omp_get_schedule_'::omp_get_schedule
|
||||
!dec$ attributes alias:'_omp_get_proc_bind_' :: omp_get_proc_bind
|
||||
!dec$ attributes alias:'_omp_get_wtime_'::omp_get_wtime
|
||||
!dec$ attributes alias:'_omp_get_wtick_'::omp_get_wtick
|
||||
!dec$ attributes alias:'_omp_get_num_teams_'::omp_get_num_teams
|
||||
!dec$ attributes alias:'_omp_get_team_num_'::omp_get_team_num
|
||||
!dec$ attributes alias:'_omp_get_cancellation_'::omp_get_cancellation
|
||||
!dec$ attributes alias:'_omp_is_initial_device_'::omp_is_initial_device
|
||||
!dec$ attributes alias:'_omp_get_max_task_priorty_'::omp_get_max_task_priority
|
||||
|
||||
!dec$ attributes alias:'_omp_init_lock_'::omp_init_lock
|
||||
!dec$ attributes alias:'_omp_init_lock_with_hint_'::omp_init_lock_with_hint
|
||||
!dec$ attributes alias:'_omp_destroy_lock_'::omp_destroy_lock
|
||||
!dec$ attributes alias:'_omp_set_lock_'::omp_set_lock
|
||||
!dec$ attributes alias:'_omp_unset_lock_'::omp_unset_lock
|
||||
!dec$ attributes alias:'_omp_test_lock_'::omp_test_lock
|
||||
!dec$ attributes alias:'_omp_init_nest_lock_'::omp_init_nest_lock
|
||||
!dec$ attributes alias:'_omp_init_nest_lock_with_hint_'::omp_init_nest_lock_with_hint
|
||||
!dec$ attributes alias:'_omp_destroy_nest_lock_'::omp_destroy_nest_lock
|
||||
!dec$ attributes alias:'_omp_set_nest_lock_'::omp_set_nest_lock
|
||||
!dec$ attributes alias:'_omp_unset_nest_lock_'::omp_unset_nest_lock
|
||||
!dec$ attributes alias:'_omp_test_nest_lock_'::omp_test_nest_lock
|
||||
|
||||
!dec$ attributes alias:'_kmp_set_stacksize_'::kmp_set_stacksize
|
||||
!dec$ attributes alias:'_kmp_set_stacksize_s_'::kmp_set_stacksize_s
|
||||
!dec$ attributes alias:'_kmp_set_blocktime_'::kmp_set_blocktime
|
||||
!dec$ attributes alias:'_kmp_set_library_serial_'::kmp_set_library_serial
|
||||
!dec$ attributes alias:'_kmp_set_library_turnaround_'::kmp_set_library_turnaround
|
||||
!dec$ attributes alias:'_kmp_set_library_throughput_'::kmp_set_library_throughput
|
||||
!dec$ attributes alias:'_kmp_set_library_'::kmp_set_library
|
||||
!dec$ attributes alias:'_kmp_get_stacksize_'::kmp_get_stacksize
|
||||
!dec$ attributes alias:'_kmp_get_stacksize_s_'::kmp_get_stacksize_s
|
||||
!dec$ attributes alias:'_kmp_get_blocktime_'::kmp_get_blocktime
|
||||
!dec$ attributes alias:'_kmp_get_library_'::kmp_get_library
|
||||
!dec$ attributes alias:'_kmp_set_affinity_'::kmp_set_affinity
|
||||
!dec$ attributes alias:'_kmp_get_affinity_'::kmp_get_affinity
|
||||
!dec$ attributes alias:'_kmp_get_affinity_max_proc_'::kmp_get_affinity_max_proc
|
||||
!dec$ attributes alias:'_kmp_create_affinity_mask_'::kmp_create_affinity_mask
|
||||
!dec$ attributes alias:'_kmp_destroy_affinity_mask_'::kmp_destroy_affinity_mask
|
||||
!dec$ attributes alias:'_kmp_set_affinity_mask_proc_'::kmp_set_affinity_mask_proc
|
||||
!dec$ attributes alias:'_kmp_unset_affinity_mask_proc_'::kmp_unset_affinity_mask_proc
|
||||
!dec$ attributes alias:'_kmp_get_affinity_mask_proc_'::kmp_get_affinity_mask_proc
|
||||
!dec$ attributes alias:'_kmp_malloc_'::kmp_malloc
|
||||
!dec$ attributes alias:'_kmp_aligned_malloc_'::kmp_aligned_malloc
|
||||
!dec$ attributes alias:'_kmp_calloc_'::kmp_calloc
|
||||
!dec$ attributes alias:'_kmp_realloc_'::kmp_realloc
|
||||
!dec$ attributes alias:'_kmp_free_'::kmp_free
|
||||
|
||||
!dec$ attributes alias:'_kmp_set_warnings_on_'::kmp_set_warnings_on
|
||||
!dec$ attributes alias:'_kmp_set_warnings_off_'::kmp_set_warnings_off
|
||||
|
||||
!dec$ attributes alias:'_kmp_get_cancellation_status_'::kmp_get_cancellation_status
|
||||
|
||||
!dec$ endif
|
||||
|
||||
end module omp_lib
|
||||
|
||||
@@ -0,0 +1,524 @@
|
||||
! include/50/omp_lib.f90.var
|
||||
|
||||
!
|
||||
!//===----------------------------------------------------------------------===//
|
||||
!//
|
||||
!// The LLVM Compiler Infrastructure
|
||||
!//
|
||||
!// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
!// Source Licenses. See LICENSE.txt for details.
|
||||
!//
|
||||
!//===----------------------------------------------------------------------===//
|
||||
!
|
||||
|
||||
module omp_lib_kinds
|
||||
|
||||
use, intrinsic :: iso_c_binding
|
||||
|
||||
integer, parameter :: omp_integer_kind = c_int
|
||||
integer, parameter :: omp_logical_kind = 4
|
||||
integer, parameter :: omp_real_kind = c_float
|
||||
integer, parameter :: kmp_double_kind = c_double
|
||||
integer, parameter :: omp_lock_kind = c_intptr_t
|
||||
integer, parameter :: omp_nest_lock_kind = c_intptr_t
|
||||
integer, parameter :: omp_sched_kind = omp_integer_kind
|
||||
integer, parameter :: omp_proc_bind_kind = omp_integer_kind
|
||||
integer, parameter :: kmp_pointer_kind = c_intptr_t
|
||||
integer, parameter :: kmp_size_t_kind = c_size_t
|
||||
integer, parameter :: kmp_affinity_mask_kind = c_intptr_t
|
||||
integer, parameter :: kmp_cancel_kind = omp_integer_kind
|
||||
integer, parameter :: omp_lock_hint_kind = omp_integer_kind
|
||||
|
||||
end module omp_lib_kinds
|
||||
|
||||
module omp_lib
|
||||
|
||||
use omp_lib_kinds
|
||||
|
||||
integer (kind=omp_integer_kind), parameter :: openmp_version = @LIBOMP_OMP_YEAR_MONTH@
|
||||
integer (kind=omp_integer_kind), parameter :: kmp_version_major = @LIBOMP_VERSION_MAJOR@
|
||||
integer (kind=omp_integer_kind), parameter :: kmp_version_minor = @LIBOMP_VERSION_MINOR@
|
||||
integer (kind=omp_integer_kind), parameter :: kmp_version_build = @LIBOMP_VERSION_BUILD@
|
||||
character(*) kmp_build_date
|
||||
parameter( kmp_build_date = '@LIBOMP_BUILD_DATE@' )
|
||||
|
||||
integer(kind=omp_sched_kind), parameter :: omp_sched_static = 1
|
||||
integer(kind=omp_sched_kind), parameter :: omp_sched_dynamic = 2
|
||||
integer(kind=omp_sched_kind), parameter :: omp_sched_guided = 3
|
||||
integer(kind=omp_sched_kind), parameter :: omp_sched_auto = 4
|
||||
|
||||
|
||||
integer (kind=omp_proc_bind_kind), parameter :: omp_proc_bind_false = 0
|
||||
integer (kind=omp_proc_bind_kind), parameter :: omp_proc_bind_true = 1
|
||||
integer (kind=omp_proc_bind_kind), parameter :: omp_proc_bind_master = 2
|
||||
integer (kind=omp_proc_bind_kind), parameter :: omp_proc_bind_close = 3
|
||||
integer (kind=omp_proc_bind_kind), parameter :: omp_proc_bind_spread = 4
|
||||
|
||||
integer (kind=kmp_cancel_kind), parameter :: kmp_cancel_parallel = 1
|
||||
integer (kind=kmp_cancel_kind), parameter :: kmp_cancel_loop = 2
|
||||
integer (kind=kmp_cancel_kind), parameter :: kmp_cancel_sections = 3
|
||||
integer (kind=kmp_cancel_kind), parameter :: kmp_cancel_taskgroup = 4
|
||||
|
||||
integer (kind=omp_lock_hint_kind), parameter :: omp_lock_hint_none = 0
|
||||
integer (kind=omp_lock_hint_kind), parameter :: omp_lock_hint_uncontended = 1
|
||||
integer (kind=omp_lock_hint_kind), parameter :: omp_lock_hint_contended = 2
|
||||
integer (kind=omp_lock_hint_kind), parameter :: omp_lock_hint_nonspeculative = 4
|
||||
integer (kind=omp_lock_hint_kind), parameter :: omp_lock_hint_speculative = 8
|
||||
integer (kind=omp_lock_hint_kind), parameter :: kmp_lock_hint_hle = 65536
|
||||
integer (kind=omp_lock_hint_kind), parameter :: kmp_lock_hint_rtm = 131072
|
||||
integer (kind=omp_lock_hint_kind), parameter :: kmp_lock_hint_adaptive = 262144
|
||||
|
||||
interface
|
||||
|
||||
! ***
|
||||
! *** omp_* entry points
|
||||
! ***
|
||||
|
||||
subroutine omp_set_num_threads(num_threads) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind), value :: num_threads
|
||||
end subroutine omp_set_num_threads
|
||||
|
||||
subroutine omp_set_dynamic(dynamic_threads) bind(c)
|
||||
use omp_lib_kinds
|
||||
logical (kind=omp_logical_kind), value :: dynamic_threads
|
||||
end subroutine omp_set_dynamic
|
||||
|
||||
subroutine omp_set_nested(nested) bind(c)
|
||||
use omp_lib_kinds
|
||||
logical (kind=omp_logical_kind), value :: nested
|
||||
end subroutine omp_set_nested
|
||||
|
||||
function omp_get_num_threads() bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_get_num_threads
|
||||
end function omp_get_num_threads
|
||||
|
||||
function omp_get_max_threads() bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_get_max_threads
|
||||
end function omp_get_max_threads
|
||||
|
||||
function omp_get_thread_num() bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_get_thread_num
|
||||
end function omp_get_thread_num
|
||||
|
||||
function omp_get_num_procs() bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_get_num_procs
|
||||
end function omp_get_num_procs
|
||||
|
||||
function omp_in_parallel() bind(c)
|
||||
use omp_lib_kinds
|
||||
logical (kind=omp_logical_kind) omp_in_parallel
|
||||
end function omp_in_parallel
|
||||
|
||||
function omp_in_final() bind(c)
|
||||
use omp_lib_kinds
|
||||
logical (kind=omp_logical_kind) omp_in_final
|
||||
end function omp_in_final
|
||||
|
||||
function omp_get_dynamic() bind(c)
|
||||
use omp_lib_kinds
|
||||
logical (kind=omp_logical_kind) omp_get_dynamic
|
||||
end function omp_get_dynamic
|
||||
|
||||
function omp_get_nested() bind(c)
|
||||
use omp_lib_kinds
|
||||
logical (kind=omp_logical_kind) omp_get_nested
|
||||
end function omp_get_nested
|
||||
|
||||
function omp_get_thread_limit() bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_get_thread_limit
|
||||
end function omp_get_thread_limit
|
||||
|
||||
subroutine omp_set_max_active_levels(max_levels) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind), value :: max_levels
|
||||
end subroutine omp_set_max_active_levels
|
||||
|
||||
function omp_get_max_active_levels() bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_get_max_active_levels
|
||||
end function omp_get_max_active_levels
|
||||
|
||||
function omp_get_level() bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_get_level
|
||||
end function omp_get_level
|
||||
|
||||
function omp_get_active_level() bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_get_active_level
|
||||
end function omp_get_active_level
|
||||
|
||||
function omp_get_ancestor_thread_num(level) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_get_ancestor_thread_num
|
||||
integer (kind=omp_integer_kind), value :: level
|
||||
end function omp_get_ancestor_thread_num
|
||||
|
||||
function omp_get_team_size(level) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_get_team_size
|
||||
integer (kind=omp_integer_kind), value :: level
|
||||
end function omp_get_team_size
|
||||
|
||||
subroutine omp_set_schedule(kind, chunk_size) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_sched_kind), value :: kind
|
||||
integer (kind=omp_integer_kind), value :: chunk_size
|
||||
end subroutine omp_set_schedule
|
||||
|
||||
subroutine omp_get_schedule(kind, chunk_size) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_sched_kind) kind
|
||||
integer (kind=omp_integer_kind) chunk_size
|
||||
end subroutine omp_get_schedule
|
||||
|
||||
function omp_get_proc_bind() bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_proc_bind_kind) omp_get_proc_bind
|
||||
end function omp_get_proc_bind
|
||||
|
||||
function omp_get_num_places() bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_get_num_places
|
||||
end function omp_get_num_places
|
||||
|
||||
function omp_get_place_num_procs(place_num) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind), value :: place_num
|
||||
integer (kind=omp_integer_kind) omp_get_place_num_procs
|
||||
end function omp_get_place_num_procs
|
||||
|
||||
subroutine omp_get_place_proc_ids(place_num, ids) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind), value :: place_num
|
||||
integer (kind=kmp_pointer_kind) ids(*)
|
||||
end subroutine omp_get_place_proc_ids
|
||||
|
||||
function omp_get_place_num() bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_get_place_num
|
||||
end function omp_get_place_num
|
||||
|
||||
function omp_get_partition_num_places() bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_get_partition_num_places
|
||||
end function omp_get_partition_num_places
|
||||
|
||||
subroutine omp_get_partition_place_nums(place_nums) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=kmp_pointer_kind) place_nums(*)
|
||||
end subroutine omp_get_partition_place_nums
|
||||
|
||||
function omp_get_wtime() bind(c)
|
||||
use omp_lib_kinds
|
||||
real (kind=kmp_double_kind) omp_get_wtime
|
||||
end function omp_get_wtime
|
||||
|
||||
function omp_get_wtick() bind(c)
|
||||
use omp_lib_kinds
|
||||
real (kind=kmp_double_kind) omp_get_wtick
|
||||
end function omp_get_wtick
|
||||
|
||||
function omp_get_default_device() bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_get_default_device
|
||||
end function omp_get_default_device
|
||||
|
||||
subroutine omp_set_default_device(device_num) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind), value :: device_num
|
||||
end subroutine omp_set_default_device
|
||||
|
||||
function omp_get_num_devices() bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_get_num_devices
|
||||
end function omp_get_num_devices
|
||||
|
||||
function omp_get_num_teams() bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_get_num_teams
|
||||
end function omp_get_num_teams
|
||||
|
||||
function omp_get_team_num() bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_get_team_num
|
||||
end function omp_get_team_num
|
||||
|
||||
function omp_get_cancellation() bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_get_cancellation
|
||||
end function omp_get_cancellation
|
||||
|
||||
function omp_is_initial_device() bind(c)
|
||||
use omp_lib_kinds
|
||||
logical (kind=omp_logical_kind) omp_is_initial_device
|
||||
end function omp_is_initial_device
|
||||
|
||||
function omp_get_initial_device() bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_get_initial_device
|
||||
end function omp_get_initial_device
|
||||
|
||||
subroutine omp_init_lock(svar) bind(c)
|
||||
!DIR$ IF(__INTEL_COMPILER.GE.1400)
|
||||
!DIR$ attributes known_intrinsic :: omp_init_lock
|
||||
!DIR$ ENDIF
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_lock_kind) svar
|
||||
end subroutine omp_init_lock
|
||||
|
||||
subroutine omp_destroy_lock(svar) bind(c)
|
||||
!DIR$ IF(__INTEL_COMPILER.GE.1400)
|
||||
!DIR$ attributes known_intrinsic :: omp_destroy_lock
|
||||
!DIR$ ENDIF
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_lock_kind) svar
|
||||
end subroutine omp_destroy_lock
|
||||
|
||||
subroutine omp_set_lock(svar) bind(c)
|
||||
!DIR$ IF(__INTEL_COMPILER.GE.1400)
|
||||
!DIR$ attributes known_intrinsic :: omp_set_lock
|
||||
!DIR$ ENDIF
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_lock_kind) svar
|
||||
end subroutine omp_set_lock
|
||||
|
||||
subroutine omp_unset_lock(svar) bind(c)
|
||||
!DIR$ IF(__INTEL_COMPILER.GE.1400)
|
||||
!DIR$ attributes known_intrinsic :: omp_unset_lock
|
||||
!DIR$ ENDIF
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_lock_kind) svar
|
||||
end subroutine omp_unset_lock
|
||||
|
||||
function omp_test_lock(svar) bind(c)
|
||||
!DIR$ IF(__INTEL_COMPILER.GE.1400)
|
||||
!DIR$ attributes known_intrinsic :: omp_test_lock
|
||||
!DIR$ ENDIF
|
||||
use omp_lib_kinds
|
||||
logical (kind=omp_logical_kind) omp_test_lock
|
||||
integer (kind=omp_lock_kind) svar
|
||||
end function omp_test_lock
|
||||
|
||||
subroutine omp_init_nest_lock(nvar) bind(c)
|
||||
!DIR$ IF(__INTEL_COMPILER.GE.1400)
|
||||
!DIR$ attributes known_intrinsic :: omp_init_nest_lock
|
||||
!DIR$ ENDIF
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_nest_lock_kind) nvar
|
||||
end subroutine omp_init_nest_lock
|
||||
|
||||
subroutine omp_destroy_nest_lock(nvar) bind(c)
|
||||
!DIR$ IF(__INTEL_COMPILER.GE.1400)
|
||||
!DIR$ attributes known_intrinsic :: omp_destroy_nest_lock
|
||||
!DIR$ ENDIF
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_nest_lock_kind) nvar
|
||||
end subroutine omp_destroy_nest_lock
|
||||
|
||||
subroutine omp_set_nest_lock(nvar) bind(c)
|
||||
!DIR$ IF(__INTEL_COMPILER.GE.1400)
|
||||
!DIR$ attributes known_intrinsic :: omp_set_nest_lock
|
||||
!DIR$ ENDIF
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_nest_lock_kind) nvar
|
||||
end subroutine omp_set_nest_lock
|
||||
|
||||
subroutine omp_unset_nest_lock(nvar) bind(c)
|
||||
!DIR$ IF(__INTEL_COMPILER.GE.1400)
|
||||
!DIR$ attributes known_intrinsic :: omp_unset_nest_lock
|
||||
!DIR$ ENDIF
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_nest_lock_kind) nvar
|
||||
end subroutine omp_unset_nest_lock
|
||||
|
||||
function omp_test_nest_lock(nvar) bind(c)
|
||||
!DIR$ IF(__INTEL_COMPILER.GE.1400)
|
||||
!DIR$ attributes known_intrinsic :: omp_test_nest_lock
|
||||
!DIR$ ENDIF
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_test_nest_lock
|
||||
integer (kind=omp_nest_lock_kind) nvar
|
||||
end function omp_test_nest_lock
|
||||
|
||||
function omp_get_max_task_priority() bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_get_max_task_priority
|
||||
end function omp_get_max_task_priority
|
||||
|
||||
! ***
|
||||
! *** kmp_* entry points
|
||||
! ***
|
||||
|
||||
subroutine kmp_set_stacksize(size) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind), value :: size
|
||||
end subroutine kmp_set_stacksize
|
||||
|
||||
subroutine kmp_set_stacksize_s(size) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=kmp_size_t_kind), value :: size
|
||||
end subroutine kmp_set_stacksize_s
|
||||
|
||||
subroutine kmp_set_blocktime(msec) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind), value :: msec
|
||||
end subroutine kmp_set_blocktime
|
||||
|
||||
subroutine kmp_set_library_serial() bind(c)
|
||||
end subroutine kmp_set_library_serial
|
||||
|
||||
subroutine kmp_set_library_turnaround() bind(c)
|
||||
end subroutine kmp_set_library_turnaround
|
||||
|
||||
subroutine kmp_set_library_throughput() bind(c)
|
||||
end subroutine kmp_set_library_throughput
|
||||
|
||||
subroutine kmp_set_library(libnum) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind), value :: libnum
|
||||
end subroutine kmp_set_library
|
||||
|
||||
subroutine kmp_set_defaults(string) bind(c)
|
||||
use, intrinsic :: iso_c_binding
|
||||
character (kind=c_char) :: string(*)
|
||||
end subroutine kmp_set_defaults
|
||||
|
||||
function kmp_get_stacksize() bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) kmp_get_stacksize
|
||||
end function kmp_get_stacksize
|
||||
|
||||
function kmp_get_stacksize_s() bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=kmp_size_t_kind) kmp_get_stacksize_s
|
||||
end function kmp_get_stacksize_s
|
||||
|
||||
function kmp_get_blocktime() bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) kmp_get_blocktime
|
||||
end function kmp_get_blocktime
|
||||
|
||||
function kmp_get_library() bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) kmp_get_library
|
||||
end function kmp_get_library
|
||||
|
||||
subroutine kmp_set_disp_num_buffers(num) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind), value :: num
|
||||
end subroutine kmp_set_disp_num_buffers
|
||||
|
||||
function kmp_set_affinity(mask) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) kmp_set_affinity
|
||||
integer (kind=kmp_affinity_mask_kind) mask
|
||||
end function kmp_set_affinity
|
||||
|
||||
function kmp_get_affinity(mask) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) kmp_get_affinity
|
||||
integer (kind=kmp_affinity_mask_kind) mask
|
||||
end function kmp_get_affinity
|
||||
|
||||
function kmp_get_affinity_max_proc() bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) kmp_get_affinity_max_proc
|
||||
end function kmp_get_affinity_max_proc
|
||||
|
||||
subroutine kmp_create_affinity_mask(mask) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=kmp_affinity_mask_kind) mask
|
||||
end subroutine kmp_create_affinity_mask
|
||||
|
||||
subroutine kmp_destroy_affinity_mask(mask) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=kmp_affinity_mask_kind) mask
|
||||
end subroutine kmp_destroy_affinity_mask
|
||||
|
||||
function kmp_set_affinity_mask_proc(proc, mask) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) kmp_set_affinity_mask_proc
|
||||
integer (kind=omp_integer_kind), value :: proc
|
||||
integer (kind=kmp_affinity_mask_kind) mask
|
||||
end function kmp_set_affinity_mask_proc
|
||||
|
||||
function kmp_unset_affinity_mask_proc(proc, mask) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) kmp_unset_affinity_mask_proc
|
||||
integer (kind=omp_integer_kind), value :: proc
|
||||
integer (kind=kmp_affinity_mask_kind) mask
|
||||
end function kmp_unset_affinity_mask_proc
|
||||
|
||||
function kmp_get_affinity_mask_proc(proc, mask) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) kmp_get_affinity_mask_proc
|
||||
integer (kind=omp_integer_kind), value :: proc
|
||||
integer (kind=kmp_affinity_mask_kind) mask
|
||||
end function kmp_get_affinity_mask_proc
|
||||
|
||||
function kmp_malloc(size) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=kmp_pointer_kind) kmp_malloc
|
||||
integer (kind=kmp_size_t_kind), value :: size
|
||||
end function kmp_malloc
|
||||
|
||||
function kmp_aligned_malloc(size, alignment) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=kmp_pointer_kind) kmp_aligned_malloc
|
||||
integer (kind=kmp_size_t_kind), value :: size
|
||||
integer (kind=kmp_size_t_kind), value :: alignment
|
||||
end function kmp_aligned_malloc
|
||||
|
||||
function kmp_calloc(nelem, elsize) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=kmp_pointer_kind) kmp_calloc
|
||||
integer (kind=kmp_size_t_kind), value :: nelem
|
||||
integer (kind=kmp_size_t_kind), value :: elsize
|
||||
end function kmp_calloc
|
||||
|
||||
function kmp_realloc(ptr, size) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=kmp_pointer_kind) kmp_realloc
|
||||
integer (kind=kmp_pointer_kind), value :: ptr
|
||||
integer (kind=kmp_size_t_kind), value :: size
|
||||
end function kmp_realloc
|
||||
|
||||
subroutine kmp_free(ptr) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=kmp_pointer_kind), value :: ptr
|
||||
end subroutine kmp_free
|
||||
|
||||
subroutine kmp_set_warnings_on() bind(c)
|
||||
end subroutine kmp_set_warnings_on
|
||||
|
||||
subroutine kmp_set_warnings_off() bind(c)
|
||||
end subroutine kmp_set_warnings_off
|
||||
|
||||
function kmp_get_cancellation_status(cancelkind) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=kmp_cancel_kind), value :: cancelkind
|
||||
logical (kind=omp_logical_kind) kmp_get_cancellation_status
|
||||
end function kmp_get_cancellation_status
|
||||
|
||||
subroutine omp_init_lock_with_hint(svar, hint) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_lock_kind) svar
|
||||
integer (kind=omp_lock_hint_kind), value :: hint
|
||||
end subroutine omp_init_lock_with_hint
|
||||
|
||||
subroutine omp_init_nest_lock_with_hint(nvar, hint) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_nest_lock_kind) nvar
|
||||
integer (kind=omp_lock_hint_kind), value :: hint
|
||||
end subroutine omp_init_nest_lock_with_hint
|
||||
|
||||
end interface
|
||||
|
||||
end module omp_lib
|
||||
@@ -0,0 +1,644 @@
|
||||
! include/50/omp_lib.h.var
|
||||
|
||||
!
|
||||
!//===----------------------------------------------------------------------===//
|
||||
!//
|
||||
!// The LLVM Compiler Infrastructure
|
||||
!//
|
||||
!// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
!// Source Licenses. See LICENSE.txt for details.
|
||||
!//
|
||||
!//===----------------------------------------------------------------------===//
|
||||
!
|
||||
|
||||
!***
|
||||
!*** Some of the directives for the following routine extend past column 72,
|
||||
!*** so process this file in 132-column mode.
|
||||
!***
|
||||
|
||||
!DIR$ fixedformlinesize:132
|
||||
|
||||
integer, parameter :: omp_integer_kind = 4
|
||||
integer, parameter :: omp_logical_kind = 4
|
||||
integer, parameter :: omp_real_kind = 4
|
||||
integer, parameter :: omp_lock_kind = int_ptr_kind()
|
||||
integer, parameter :: omp_nest_lock_kind = int_ptr_kind()
|
||||
integer, parameter :: omp_sched_kind = omp_integer_kind
|
||||
integer, parameter :: omp_proc_bind_kind = omp_integer_kind
|
||||
integer, parameter :: kmp_pointer_kind = int_ptr_kind()
|
||||
integer, parameter :: kmp_size_t_kind = int_ptr_kind()
|
||||
integer, parameter :: kmp_affinity_mask_kind = int_ptr_kind()
|
||||
integer, parameter :: omp_lock_hint_kind = omp_integer_kind
|
||||
|
||||
integer (kind=omp_integer_kind), parameter :: openmp_version = @LIBOMP_OMP_YEAR_MONTH@
|
||||
integer (kind=omp_integer_kind), parameter :: kmp_version_major = @LIBOMP_VERSION_MAJOR@
|
||||
integer (kind=omp_integer_kind), parameter :: kmp_version_minor = @LIBOMP_VERSION_MINOR@
|
||||
integer (kind=omp_integer_kind), parameter :: kmp_version_build = @LIBOMP_VERSION_BUILD@
|
||||
character(*) kmp_build_date
|
||||
parameter( kmp_build_date = '@LIBOMP_BUILD_DATE@' )
|
||||
|
||||
integer(kind=omp_sched_kind), parameter :: omp_sched_static = 1
|
||||
integer(kind=omp_sched_kind), parameter :: omp_sched_dynamic = 2
|
||||
integer(kind=omp_sched_kind), parameter :: omp_sched_guided = 3
|
||||
integer(kind=omp_sched_kind), parameter :: omp_sched_auto = 4
|
||||
|
||||
integer (kind=omp_proc_bind_kind), parameter :: omp_proc_bind_false = 0
|
||||
integer (kind=omp_proc_bind_kind), parameter :: omp_proc_bind_true = 1
|
||||
integer (kind=omp_proc_bind_kind), parameter :: omp_proc_bind_master = 2
|
||||
integer (kind=omp_proc_bind_kind), parameter :: omp_proc_bind_close = 3
|
||||
integer (kind=omp_proc_bind_kind), parameter :: omp_proc_bind_spread = 4
|
||||
|
||||
integer (kind=omp_lock_hint_kind), parameter :: omp_lock_hint_none = 0
|
||||
integer (kind=omp_lock_hint_kind), parameter :: omp_lock_hint_uncontended = 1
|
||||
integer (kind=omp_lock_hint_kind), parameter :: omp_lock_hint_contended = 2
|
||||
integer (kind=omp_lock_hint_kind), parameter :: omp_lock_hint_nonspeculative = 4
|
||||
integer (kind=omp_lock_hint_kind), parameter :: omp_lock_hint_speculative = 8
|
||||
integer (kind=omp_lock_hint_kind), parameter :: kmp_lock_hint_hle = 65536
|
||||
integer (kind=omp_lock_hint_kind), parameter :: kmp_lock_hint_rtm = 131072
|
||||
integer (kind=omp_lock_hint_kind), parameter :: kmp_lock_hint_adaptive = 262144
|
||||
|
||||
interface
|
||||
|
||||
! ***
|
||||
! *** omp_* entry points
|
||||
! ***
|
||||
|
||||
subroutine omp_set_num_threads(num_threads) bind(c)
|
||||
import
|
||||
integer (kind=omp_integer_kind), value :: num_threads
|
||||
end subroutine omp_set_num_threads
|
||||
|
||||
subroutine omp_set_dynamic(dynamic_threads) bind(c)
|
||||
import
|
||||
logical (kind=omp_logical_kind), value :: dynamic_threads
|
||||
end subroutine omp_set_dynamic
|
||||
|
||||
subroutine omp_set_nested(nested) bind(c)
|
||||
import
|
||||
logical (kind=omp_logical_kind), value :: nested
|
||||
end subroutine omp_set_nested
|
||||
|
||||
function omp_get_num_threads() bind(c)
|
||||
import
|
||||
integer (kind=omp_integer_kind) omp_get_num_threads
|
||||
end function omp_get_num_threads
|
||||
|
||||
function omp_get_max_threads() bind(c)
|
||||
import
|
||||
integer (kind=omp_integer_kind) omp_get_max_threads
|
||||
end function omp_get_max_threads
|
||||
|
||||
function omp_get_thread_num() bind(c)
|
||||
import
|
||||
integer (kind=omp_integer_kind) omp_get_thread_num
|
||||
end function omp_get_thread_num
|
||||
|
||||
function omp_get_num_procs() bind(c)
|
||||
import
|
||||
integer (kind=omp_integer_kind) omp_get_num_procs
|
||||
end function omp_get_num_procs
|
||||
|
||||
function omp_in_parallel() bind(c)
|
||||
import
|
||||
logical (kind=omp_logical_kind) omp_in_parallel
|
||||
end function omp_in_parallel
|
||||
|
||||
function omp_in_final() bind(c)
|
||||
import
|
||||
logical (kind=omp_logical_kind) omp_in_final
|
||||
end function omp_in_final
|
||||
|
||||
function omp_get_dynamic() bind(c)
|
||||
import
|
||||
logical (kind=omp_logical_kind) omp_get_dynamic
|
||||
end function omp_get_dynamic
|
||||
|
||||
function omp_get_nested() bind(c)
|
||||
import
|
||||
logical (kind=omp_logical_kind) omp_get_nested
|
||||
end function omp_get_nested
|
||||
|
||||
function omp_get_thread_limit() bind(c)
|
||||
import
|
||||
integer (kind=omp_integer_kind) omp_get_thread_limit
|
||||
end function omp_get_thread_limit
|
||||
|
||||
subroutine omp_set_max_active_levels(max_levels) bind(c)
|
||||
import
|
||||
integer (kind=omp_integer_kind), value :: max_levels
|
||||
end subroutine omp_set_max_active_levels
|
||||
|
||||
function omp_get_max_active_levels() bind(c)
|
||||
import
|
||||
integer (kind=omp_integer_kind) omp_get_max_active_levels
|
||||
end function omp_get_max_active_levels
|
||||
|
||||
function omp_get_level() bind(c)
|
||||
import
|
||||
integer (kind=omp_integer_kind) omp_get_level
|
||||
end function omp_get_level
|
||||
|
||||
function omp_get_active_level() bind(c)
|
||||
import
|
||||
integer (kind=omp_integer_kind) omp_get_active_level
|
||||
end function omp_get_active_level
|
||||
|
||||
function omp_get_ancestor_thread_num(level) bind(c)
|
||||
import
|
||||
integer (kind=omp_integer_kind) omp_get_ancestor_thread_num
|
||||
integer (kind=omp_integer_kind), value :: level
|
||||
end function omp_get_ancestor_thread_num
|
||||
|
||||
function omp_get_team_size(level) bind(c)
|
||||
import
|
||||
integer (kind=omp_integer_kind) omp_get_team_size
|
||||
integer (kind=omp_integer_kind), value :: level
|
||||
end function omp_get_team_size
|
||||
|
||||
subroutine omp_set_schedule(kind, chunk_size) bind(c)
|
||||
import
|
||||
integer (kind=omp_sched_kind), value :: kind
|
||||
integer (kind=omp_integer_kind), value :: chunk_size
|
||||
end subroutine omp_set_schedule
|
||||
|
||||
subroutine omp_get_schedule(kind, chunk_size) bind(c)
|
||||
import
|
||||
integer (kind=omp_sched_kind) kind
|
||||
integer (kind=omp_integer_kind) chunk_size
|
||||
end subroutine omp_get_schedule
|
||||
|
||||
function omp_get_proc_bind() bind(c)
|
||||
import
|
||||
integer (kind=omp_proc_bind_kind) omp_get_proc_bind
|
||||
end function omp_get_proc_bind
|
||||
|
||||
function omp_get_num_places() bind(c)
|
||||
import
|
||||
integer (kind=omp_integer_kind) omp_get_num_places
|
||||
end function omp_get_num_places
|
||||
|
||||
function omp_get_place_num_procs(place_num) bind(c)
|
||||
import
|
||||
integer (kind=omp_integer_kind), value :: place_num
|
||||
integer (kind=omp_integer_kind) omp_get_place_num_procs
|
||||
end function omp_get_place_num_procs
|
||||
|
||||
subroutine omp_get_place_proc_ids(place_num, ids) bind(c)
|
||||
import
|
||||
integer (kind=omp_integer_kind), value :: place_num
|
||||
integer (kind=kmp_pointer_kind) ids(*)
|
||||
end subroutine omp_get_place_proc_ids
|
||||
|
||||
function omp_get_place_num() bind(c)
|
||||
import
|
||||
integer (kind=omp_integer_kind) omp_get_place_num
|
||||
end function omp_get_place_num
|
||||
|
||||
function omp_get_partition_num_places() bind(c)
|
||||
import
|
||||
integer (kind=omp_integer_kind) omp_get_partition_num_places
|
||||
end function omp_get_partition_num_places
|
||||
|
||||
subroutine omp_get_partition_place_nums(place_nums) bind(c)
|
||||
import
|
||||
integer (kind=kmp_pointer_kind) place_nums(*)
|
||||
end subroutine omp_get_partition_place_nums
|
||||
|
||||
function omp_get_wtime() bind(c)
|
||||
double precision omp_get_wtime
|
||||
end function omp_get_wtime
|
||||
|
||||
function omp_get_wtick() bind(c)
|
||||
double precision omp_get_wtick
|
||||
end function omp_get_wtick
|
||||
|
||||
function omp_get_default_device() bind(c)
|
||||
import
|
||||
integer (kind=omp_integer_kind) omp_get_default_device
|
||||
end function omp_get_default_device
|
||||
|
||||
subroutine omp_set_default_device(device_num) bind(c)
|
||||
import
|
||||
integer (kind=omp_integer_kind), value :: device_num
|
||||
end subroutine omp_set_default_device
|
||||
|
||||
function omp_get_num_devices() bind(c)
|
||||
import
|
||||
integer (kind=omp_integer_kind) omp_get_num_devices
|
||||
end function omp_get_num_devices
|
||||
|
||||
function omp_get_num_teams() bind(c)
|
||||
import
|
||||
integer (kind=omp_integer_kind) omp_get_num_teams
|
||||
end function omp_get_num_teams
|
||||
|
||||
function omp_get_team_num() bind(c)
|
||||
import
|
||||
integer (kind=omp_integer_kind) omp_get_team_num
|
||||
end function omp_get_team_num
|
||||
|
||||
function omp_is_initial_device() bind(c)
|
||||
import
|
||||
logical (kind=omp_logical_kind) omp_is_initial_device
|
||||
end function omp_is_initial_device
|
||||
|
||||
function omp_get_initial_device() bind(c)
|
||||
import
|
||||
integer (kind=omp_integer_kind) omp_get_initial_device
|
||||
end function omp_get_initial_device
|
||||
|
||||
subroutine omp_init_lock(svar) bind(c)
|
||||
!DIR$ IF(__INTEL_COMPILER.GE.1400)
|
||||
!DIR$ attributes known_intrinsic :: omp_init_lock
|
||||
!DIR$ ENDIF
|
||||
import
|
||||
integer (kind=omp_lock_kind) svar
|
||||
end subroutine omp_init_lock
|
||||
|
||||
subroutine omp_destroy_lock(svar) bind(c)
|
||||
!DIR$ IF(__INTEL_COMPILER.GE.1400)
|
||||
!DIR$ attributes known_intrinsic :: omp_destroy_lock
|
||||
!DIR$ ENDIF
|
||||
import
|
||||
integer (kind=omp_lock_kind) svar
|
||||
end subroutine omp_destroy_lock
|
||||
|
||||
subroutine omp_set_lock(svar) bind(c)
|
||||
!DIR$ IF(__INTEL_COMPILER.GE.1400)
|
||||
!DIR$ attributes known_intrinsic :: omp_set_lock
|
||||
!DIR$ ENDIF
|
||||
import
|
||||
integer (kind=omp_lock_kind) svar
|
||||
end subroutine omp_set_lock
|
||||
|
||||
subroutine omp_unset_lock(svar) bind(c)
|
||||
!DIR$ IF(__INTEL_COMPILER.GE.1400)
|
||||
!DIR$ attributes known_intrinsic :: omp_unset_lock
|
||||
!DIR$ ENDIF
|
||||
import
|
||||
integer (kind=omp_lock_kind) svar
|
||||
end subroutine omp_unset_lock
|
||||
|
||||
function omp_test_lock(svar) bind(c)
|
||||
!DIR$ IF(__INTEL_COMPILER.GE.1400)
|
||||
!DIR$ attributes known_intrinsic :: omp_test_lock
|
||||
!DIR$ ENDIF
|
||||
import
|
||||
logical (kind=omp_logical_kind) omp_test_lock
|
||||
integer (kind=omp_lock_kind) svar
|
||||
end function omp_test_lock
|
||||
|
||||
subroutine omp_init_nest_lock(nvar) bind(c)
|
||||
!DIR$ IF(__INTEL_COMPILER.GE.1400)
|
||||
!DIR$ attributes known_intrinsic :: omp_init_nest_lock
|
||||
!DIR$ ENDIF
|
||||
import
|
||||
integer (kind=omp_nest_lock_kind) nvar
|
||||
end subroutine omp_init_nest_lock
|
||||
|
||||
subroutine omp_destroy_nest_lock(nvar) bind(c)
|
||||
!DIR$ IF(__INTEL_COMPILER.GE.1400)
|
||||
!DIR$ attributes known_intrinsic :: omp_destroy_nest_lock
|
||||
!DIR$ ENDIF
|
||||
import
|
||||
integer (kind=omp_nest_lock_kind) nvar
|
||||
end subroutine omp_destroy_nest_lock
|
||||
|
||||
subroutine omp_set_nest_lock(nvar) bind(c)
|
||||
!DIR$ IF(__INTEL_COMPILER.GE.1400)
|
||||
!DIR$ attributes known_intrinsic :: omp_set_nest_lock
|
||||
!DIR$ ENDIF
|
||||
import
|
||||
integer (kind=omp_nest_lock_kind) nvar
|
||||
end subroutine omp_set_nest_lock
|
||||
|
||||
subroutine omp_unset_nest_lock(nvar) bind(c)
|
||||
!DIR$ IF(__INTEL_COMPILER.GE.1400)
|
||||
!DIR$ attributes known_intrinsic :: omp_unset_nest_lock
|
||||
!DIR$ ENDIF
|
||||
import
|
||||
integer (kind=omp_nest_lock_kind) nvar
|
||||
end subroutine omp_unset_nest_lock
|
||||
|
||||
function omp_test_nest_lock(nvar) bind(c)
|
||||
!DIR$ IF(__INTEL_COMPILER.GE.1400)
|
||||
!DIR$ attributes known_intrinsic :: omp_test_nest_lock
|
||||
!DIR$ ENDIF
|
||||
import
|
||||
integer (kind=omp_integer_kind) omp_test_nest_lock
|
||||
integer (kind=omp_nest_lock_kind) nvar
|
||||
end function omp_test_nest_lock
|
||||
|
||||
function omp_get_max_task_priority() bind(c)
|
||||
import
|
||||
integer (kind=omp_integer_kind) omp_get_max_task_priority
|
||||
end function omp_get_max_task_priority
|
||||
|
||||
! ***
|
||||
! *** kmp_* entry points
|
||||
! ***
|
||||
|
||||
subroutine kmp_set_stacksize(size) bind(c)
|
||||
import
|
||||
integer (kind=omp_integer_kind), value :: size
|
||||
end subroutine kmp_set_stacksize
|
||||
|
||||
subroutine kmp_set_stacksize_s(size) bind(c)
|
||||
import
|
||||
integer (kind=kmp_size_t_kind), value :: size
|
||||
end subroutine kmp_set_stacksize_s
|
||||
|
||||
subroutine kmp_set_blocktime(msec) bind(c)
|
||||
import
|
||||
integer (kind=omp_integer_kind), value :: msec
|
||||
end subroutine kmp_set_blocktime
|
||||
|
||||
subroutine kmp_set_library_serial() bind(c)
|
||||
end subroutine kmp_set_library_serial
|
||||
|
||||
subroutine kmp_set_library_turnaround() bind(c)
|
||||
end subroutine kmp_set_library_turnaround
|
||||
|
||||
subroutine kmp_set_library_throughput() bind(c)
|
||||
end subroutine kmp_set_library_throughput
|
||||
|
||||
subroutine kmp_set_library(libnum) bind(c)
|
||||
import
|
||||
integer (kind=omp_integer_kind), value :: libnum
|
||||
end subroutine kmp_set_library
|
||||
|
||||
subroutine kmp_set_defaults(string) bind(c)
|
||||
character string(*)
|
||||
end subroutine kmp_set_defaults
|
||||
|
||||
function kmp_get_stacksize() bind(c)
|
||||
import
|
||||
integer (kind=omp_integer_kind) kmp_get_stacksize
|
||||
end function kmp_get_stacksize
|
||||
|
||||
function kmp_get_stacksize_s() bind(c)
|
||||
import
|
||||
integer (kind=kmp_size_t_kind) kmp_get_stacksize_s
|
||||
end function kmp_get_stacksize_s
|
||||
|
||||
function kmp_get_blocktime() bind(c)
|
||||
import
|
||||
integer (kind=omp_integer_kind) kmp_get_blocktime
|
||||
end function kmp_get_blocktime
|
||||
|
||||
function kmp_get_library() bind(c)
|
||||
import
|
||||
integer (kind=omp_integer_kind) kmp_get_library
|
||||
end function kmp_get_library
|
||||
|
||||
subroutine kmp_set_disp_num_buffers(num) bind(c)
|
||||
import
|
||||
integer (kind=omp_integer_kind), value :: num
|
||||
end subroutine kmp_set_disp_num_buffers
|
||||
|
||||
function kmp_set_affinity(mask) bind(c)
|
||||
import
|
||||
integer (kind=omp_integer_kind) kmp_set_affinity
|
||||
integer (kind=kmp_affinity_mask_kind) mask
|
||||
end function kmp_set_affinity
|
||||
|
||||
function kmp_get_affinity(mask) bind(c)
|
||||
import
|
||||
integer (kind=omp_integer_kind) kmp_get_affinity
|
||||
integer (kind=kmp_affinity_mask_kind) mask
|
||||
end function kmp_get_affinity
|
||||
|
||||
function kmp_get_affinity_max_proc() bind(c)
|
||||
import
|
||||
integer (kind=omp_integer_kind) kmp_get_affinity_max_proc
|
||||
end function kmp_get_affinity_max_proc
|
||||
|
||||
subroutine kmp_create_affinity_mask(mask) bind(c)
|
||||
import
|
||||
integer (kind=kmp_affinity_mask_kind) mask
|
||||
end subroutine kmp_create_affinity_mask
|
||||
|
||||
subroutine kmp_destroy_affinity_mask(mask) bind(c)
|
||||
import
|
||||
integer (kind=kmp_affinity_mask_kind) mask
|
||||
end subroutine kmp_destroy_affinity_mask
|
||||
|
||||
function kmp_set_affinity_mask_proc(proc, mask) bind(c)
|
||||
import
|
||||
integer (kind=omp_integer_kind) kmp_set_affinity_mask_proc
|
||||
integer (kind=omp_integer_kind), value :: proc
|
||||
integer (kind=kmp_affinity_mask_kind) mask
|
||||
end function kmp_set_affinity_mask_proc
|
||||
|
||||
function kmp_unset_affinity_mask_proc(proc, mask) bind(c)
|
||||
import
|
||||
integer (kind=omp_integer_kind) kmp_unset_affinity_mask_proc
|
||||
integer (kind=omp_integer_kind), value :: proc
|
||||
integer (kind=kmp_affinity_mask_kind) mask
|
||||
end function kmp_unset_affinity_mask_proc
|
||||
|
||||
function kmp_get_affinity_mask_proc(proc, mask) bind(c)
|
||||
import
|
||||
integer (kind=omp_integer_kind) kmp_get_affinity_mask_proc
|
||||
integer (kind=omp_integer_kind), value :: proc
|
||||
integer (kind=kmp_affinity_mask_kind) mask
|
||||
end function kmp_get_affinity_mask_proc
|
||||
|
||||
function kmp_malloc(size) bind(c)
|
||||
import
|
||||
integer (kind=kmp_pointer_kind) kmp_malloc
|
||||
integer (kind=kmp_size_t_kind), value :: size
|
||||
end function kmp_malloc
|
||||
|
||||
function kmp_aligned_malloc(size, alignment) bind(c)
|
||||
import
|
||||
integer (kind=kmp_pointer_kind) kmp_aligned_malloc
|
||||
integer (kind=kmp_size_t_kind), value :: size
|
||||
integer (kind=kmp_size_t_kind), value :: alignment
|
||||
end function kmp_aligned_malloc
|
||||
|
||||
function kmp_calloc(nelem, elsize) bind(c)
|
||||
import
|
||||
integer (kind=kmp_pointer_kind) kmp_calloc
|
||||
integer (kind=kmp_size_t_kind), value :: nelem
|
||||
integer (kind=kmp_size_t_kind), value :: elsize
|
||||
end function kmp_calloc
|
||||
|
||||
function kmp_realloc(ptr, size) bind(c)
|
||||
import
|
||||
integer (kind=kmp_pointer_kind) kmp_realloc
|
||||
integer (kind=kmp_pointer_kind), value :: ptr
|
||||
integer (kind=kmp_size_t_kind), value :: size
|
||||
end function kmp_realloc
|
||||
|
||||
subroutine kmp_free(ptr) bind(c)
|
||||
import
|
||||
integer (kind=kmp_pointer_kind), value :: ptr
|
||||
end subroutine kmp_free
|
||||
|
||||
subroutine kmp_set_warnings_on() bind(c)
|
||||
end subroutine kmp_set_warnings_on
|
||||
|
||||
subroutine kmp_set_warnings_off() bind(c)
|
||||
end subroutine kmp_set_warnings_off
|
||||
|
||||
subroutine omp_init_lock_with_hint(svar, hint) bind(c)
|
||||
import
|
||||
integer (kind=omp_lock_kind) svar
|
||||
integer (kind=omp_lock_hint_kind), value :: hint
|
||||
end subroutine omp_init_lock_with_hint
|
||||
|
||||
subroutine omp_init_nest_lock_with_hint(nvar, hint) bind(c)
|
||||
import
|
||||
integer (kind=omp_nest_lock_kind) nvar
|
||||
integer (kind=omp_lock_hint_kind), value :: hint
|
||||
end subroutine omp_init_nest_lock_with_hint
|
||||
|
||||
end interface
|
||||
|
||||
!DIR$ IF DEFINED (__INTEL_OFFLOAD)
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_set_num_threads
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_set_dynamic
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_set_nested
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_get_num_threads
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_get_max_threads
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_get_thread_num
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_get_num_procs
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_in_parallel
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_in_final
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_get_dynamic
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_get_nested
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_get_thread_limit
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_set_max_active_levels
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_get_max_active_levels
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_get_level
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_get_active_level
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_get_ancestor_thread_num
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_get_team_size
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_set_schedule
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_get_schedule
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_get_proc_bind
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_get_wtime
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_get_wtick
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_get_default_device
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_set_default_device
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_is_initial_device
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_get_num_devices
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_get_num_teams
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_get_team_num
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_init_lock
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_destroy_lock
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_set_lock
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_unset_lock
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_test_lock
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_init_nest_lock
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_destroy_nest_lock
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_set_nest_lock
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_unset_nest_lock
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_test_nest_lock
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_get_max_task_priority
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_set_stacksize
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_set_stacksize_s
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_set_blocktime
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_set_library_serial
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_set_library_turnaround
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_set_library_throughput
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_set_library
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_set_defaults
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_get_stacksize
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_get_stacksize_s
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_get_blocktime
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_get_library
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_set_disp_num_buffers
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_set_affinity
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_get_affinity
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_get_affinity_max_proc
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_create_affinity_mask
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_destroy_affinity_mask
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_set_affinity_mask_proc
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_unset_affinity_mask_proc
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_get_affinity_mask_proc
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_malloc
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_aligned_malloc
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_calloc
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_realloc
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_free
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_set_warnings_on
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: kmp_set_warnings_off
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_init_lock_with_hint
|
||||
!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_init_nest_lock_with_hint
|
||||
|
||||
!DIR$ IF(__INTEL_COMPILER.GE.1400)
|
||||
!$omp declare target(omp_set_num_threads )
|
||||
!$omp declare target(omp_set_dynamic )
|
||||
!$omp declare target(omp_set_nested )
|
||||
!$omp declare target(omp_get_num_threads )
|
||||
!$omp declare target(omp_get_max_threads )
|
||||
!$omp declare target(omp_get_thread_num )
|
||||
!$omp declare target(omp_get_num_procs )
|
||||
!$omp declare target(omp_in_parallel )
|
||||
!$omp declare target(omp_in_final )
|
||||
!$omp declare target(omp_get_dynamic )
|
||||
!$omp declare target(omp_get_nested )
|
||||
!$omp declare target(omp_get_thread_limit )
|
||||
!$omp declare target(omp_set_max_active_levels )
|
||||
!$omp declare target(omp_get_max_active_levels )
|
||||
!$omp declare target(omp_get_level )
|
||||
!$omp declare target(omp_get_active_level )
|
||||
!$omp declare target(omp_get_ancestor_thread_num )
|
||||
!$omp declare target(omp_get_team_size )
|
||||
!$omp declare target(omp_set_schedule )
|
||||
!$omp declare target(omp_get_schedule )
|
||||
!$omp declare target(omp_get_proc_bind )
|
||||
!$omp declare target(omp_get_wtime )
|
||||
!$omp declare target(omp_get_wtick )
|
||||
!$omp declare target(omp_get_default_device )
|
||||
!$omp declare target(omp_set_default_device )
|
||||
!$omp declare target(omp_is_initial_device )
|
||||
!$omp declare target(omp_get_num_devices )
|
||||
!$omp declare target(omp_get_num_teams )
|
||||
!$omp declare target(omp_get_team_num )
|
||||
!$omp declare target(omp_init_lock )
|
||||
!$omp declare target(omp_destroy_lock )
|
||||
!$omp declare target(omp_set_lock )
|
||||
!$omp declare target(omp_unset_lock )
|
||||
!$omp declare target(omp_test_lock )
|
||||
!$omp declare target(omp_init_nest_lock )
|
||||
!$omp declare target(omp_destroy_nest_lock )
|
||||
!$omp declare target(omp_set_nest_lock )
|
||||
!$omp declare target(omp_unset_nest_lock )
|
||||
!$omp declare target(omp_test_nest_lock )
|
||||
!$omp declare target(omp_get_max_task_priority )
|
||||
!$omp declare target(kmp_set_stacksize )
|
||||
!$omp declare target(kmp_set_stacksize_s )
|
||||
!$omp declare target(kmp_set_blocktime )
|
||||
!$omp declare target(kmp_set_library_serial )
|
||||
!$omp declare target(kmp_set_library_turnaround )
|
||||
!$omp declare target(kmp_set_library_throughput )
|
||||
!$omp declare target(kmp_set_library )
|
||||
!$omp declare target(kmp_set_defaults )
|
||||
!$omp declare target(kmp_get_stacksize )
|
||||
!$omp declare target(kmp_get_stacksize_s )
|
||||
!$omp declare target(kmp_get_blocktime )
|
||||
!$omp declare target(kmp_get_library )
|
||||
!$omp declare target(kmp_set_disp_num_buffers )
|
||||
!$omp declare target(kmp_set_affinity )
|
||||
!$omp declare target(kmp_get_affinity )
|
||||
!$omp declare target(kmp_get_affinity_max_proc )
|
||||
!$omp declare target(kmp_create_affinity_mask )
|
||||
!$omp declare target(kmp_destroy_affinity_mask )
|
||||
!$omp declare target(kmp_set_affinity_mask_proc )
|
||||
!$omp declare target(kmp_unset_affinity_mask_proc )
|
||||
!$omp declare target(kmp_get_affinity_mask_proc )
|
||||
!$omp declare target(kmp_malloc )
|
||||
!$omp declare target(kmp_aligned_malloc )
|
||||
!$omp declare target(kmp_calloc )
|
||||
!$omp declare target(kmp_realloc )
|
||||
!$omp declare target(kmp_free )
|
||||
!$omp declare target(kmp_set_warnings_on )
|
||||
!$omp declare target(kmp_set_warnings_off )
|
||||
!$omp declare target(omp_init_lock_with_hint )
|
||||
!$omp declare target(omp_init_nest_lock_with_hint )
|
||||
!DIR$ ENDIF
|
||||
!DIR$ ENDIF
|
||||
|
||||
@@ -0,0 +1,515 @@
|
||||
/*
|
||||
* include/50/ompt.h.var
|
||||
*/
|
||||
|
||||
#ifndef __OMPT__
|
||||
#define __OMPT__
|
||||
|
||||
/*****************************************************************************
|
||||
* system include files
|
||||
*****************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* iteration macros
|
||||
*****************************************************************************/
|
||||
|
||||
#define FOREACH_OMPT_INQUIRY_FN(macro) \
|
||||
macro (ompt_enumerate_state) \
|
||||
\
|
||||
macro (ompt_set_callback) \
|
||||
macro (ompt_get_callback) \
|
||||
\
|
||||
macro (ompt_get_idle_frame) \
|
||||
macro (ompt_get_task_frame) \
|
||||
\
|
||||
macro (ompt_get_state) \
|
||||
\
|
||||
macro (ompt_get_parallel_id) \
|
||||
macro (ompt_get_parallel_team_size) \
|
||||
macro (ompt_get_task_id) \
|
||||
macro (ompt_get_thread_id)
|
||||
|
||||
#define FOREACH_OMPT_PLACEHOLDER_FN(macro) \
|
||||
macro (ompt_idle) \
|
||||
macro (ompt_overhead) \
|
||||
macro (ompt_barrier_wait) \
|
||||
macro (ompt_task_wait) \
|
||||
macro (ompt_mutex_wait)
|
||||
|
||||
#define FOREACH_OMPT_STATE(macro) \
|
||||
\
|
||||
/* first */ \
|
||||
macro (ompt_state_first, 0x71) /* initial enumeration state */ \
|
||||
\
|
||||
/* work states (0..15) */ \
|
||||
macro (ompt_state_work_serial, 0x00) /* working outside parallel */ \
|
||||
macro (ompt_state_work_parallel, 0x01) /* working within parallel */ \
|
||||
macro (ompt_state_work_reduction, 0x02) /* performing a reduction */ \
|
||||
\
|
||||
/* idle (16..31) */ \
|
||||
macro (ompt_state_idle, 0x10) /* waiting for work */ \
|
||||
\
|
||||
/* overhead states (32..63) */ \
|
||||
macro (ompt_state_overhead, 0x20) /* overhead excluding wait states */ \
|
||||
\
|
||||
/* barrier wait states (64..79) */ \
|
||||
macro (ompt_state_wait_barrier, 0x40) /* waiting at a barrier */ \
|
||||
macro (ompt_state_wait_barrier_implicit, 0x41) /* implicit barrier */ \
|
||||
macro (ompt_state_wait_barrier_explicit, 0x42) /* explicit barrier */ \
|
||||
\
|
||||
/* task wait states (80..95) */ \
|
||||
macro (ompt_state_wait_taskwait, 0x50) /* waiting at a taskwait */ \
|
||||
macro (ompt_state_wait_taskgroup, 0x51) /* waiting at a taskgroup */ \
|
||||
\
|
||||
/* mutex wait states (96..111) */ \
|
||||
macro (ompt_state_wait_lock, 0x60) /* waiting for lock */ \
|
||||
macro (ompt_state_wait_nest_lock, 0x61) /* waiting for nest lock */ \
|
||||
macro (ompt_state_wait_critical, 0x62) /* waiting for critical */ \
|
||||
macro (ompt_state_wait_atomic, 0x63) /* waiting for atomic */ \
|
||||
macro (ompt_state_wait_ordered, 0x64) /* waiting for ordered */ \
|
||||
macro (ompt_state_wait_single, 0x6F) /* waiting for single region (non-standard!) */ \
|
||||
\
|
||||
/* misc (112..127) */ \
|
||||
macro (ompt_state_undefined, 0x70) /* undefined thread state */
|
||||
|
||||
|
||||
#define FOREACH_OMPT_EVENT(macro) \
|
||||
\
|
||||
/*--- Mandatory Events ---*/ \
|
||||
macro (ompt_event_parallel_begin, ompt_new_parallel_callback_t, 1) /* parallel begin */ \
|
||||
macro (ompt_event_parallel_end, ompt_end_parallel_callback_t, 2) /* parallel end */ \
|
||||
\
|
||||
macro (ompt_event_task_begin, ompt_new_task_callback_t, 3) /* task begin */ \
|
||||
macro (ompt_event_task_end, ompt_task_callback_t, 4) /* task destroy */ \
|
||||
\
|
||||
macro (ompt_event_thread_begin, ompt_thread_type_callback_t, 5) /* thread begin */ \
|
||||
macro (ompt_event_thread_end, ompt_thread_type_callback_t, 6) /* thread end */ \
|
||||
\
|
||||
macro (ompt_event_control, ompt_control_callback_t, 7) /* support control calls */ \
|
||||
\
|
||||
macro (ompt_event_runtime_shutdown, ompt_callback_t, 8) /* runtime shutdown */ \
|
||||
\
|
||||
/*--- Optional Events (blame shifting, ompt_event_unimplemented) ---*/ \
|
||||
macro (ompt_event_idle_begin, ompt_thread_callback_t, 9) /* begin idle state */ \
|
||||
macro (ompt_event_idle_end, ompt_thread_callback_t, 10) /* end idle state */ \
|
||||
\
|
||||
macro (ompt_event_wait_barrier_begin, ompt_parallel_callback_t, 11) /* begin wait at barrier */ \
|
||||
macro (ompt_event_wait_barrier_end, ompt_parallel_callback_t, 12) /* end wait at barrier */ \
|
||||
\
|
||||
macro (ompt_event_wait_taskwait_begin, ompt_parallel_callback_t, 13) /* begin wait at taskwait */ \
|
||||
macro (ompt_event_wait_taskwait_end, ompt_parallel_callback_t, 14) /* end wait at taskwait */ \
|
||||
\
|
||||
macro (ompt_event_wait_taskgroup_begin, ompt_parallel_callback_t, 15) /* begin wait at taskgroup */\
|
||||
macro (ompt_event_wait_taskgroup_end, ompt_parallel_callback_t, 16) /* end wait at taskgroup */ \
|
||||
\
|
||||
macro (ompt_event_release_lock, ompt_wait_callback_t, 17) /* lock release */ \
|
||||
macro (ompt_event_release_nest_lock_last, ompt_wait_callback_t, 18) /* last nest lock release */ \
|
||||
macro (ompt_event_release_critical, ompt_wait_callback_t, 19) /* critical release */ \
|
||||
\
|
||||
macro (ompt_event_release_atomic, ompt_wait_callback_t, 20) /* atomic release */ \
|
||||
\
|
||||
macro (ompt_event_release_ordered, ompt_wait_callback_t, 21) /* ordered release */ \
|
||||
\
|
||||
/*--- Optional Events (synchronous events, ompt_event_unimplemented) --- */ \
|
||||
macro (ompt_event_implicit_task_begin, ompt_parallel_callback_t, 22) /* implicit task begin */ \
|
||||
macro (ompt_event_implicit_task_end, ompt_parallel_callback_t, 23) /* implicit task end */ \
|
||||
\
|
||||
macro (ompt_event_initial_task_begin, ompt_parallel_callback_t, 24) /* initial task begin */ \
|
||||
macro (ompt_event_initial_task_end, ompt_parallel_callback_t, 25) /* initial task end */ \
|
||||
\
|
||||
macro (ompt_event_task_switch, ompt_task_pair_callback_t, 26) /* task switch */ \
|
||||
\
|
||||
macro (ompt_event_loop_begin, ompt_new_workshare_callback_t, 27) /* task at loop begin */ \
|
||||
macro (ompt_event_loop_end, ompt_parallel_callback_t, 28) /* task at loop end */ \
|
||||
\
|
||||
macro (ompt_event_sections_begin, ompt_new_workshare_callback_t, 29) /* task at sections begin */\
|
||||
macro (ompt_event_sections_end, ompt_parallel_callback_t, 30) /* task at sections end */ \
|
||||
\
|
||||
macro (ompt_event_single_in_block_begin, ompt_new_workshare_callback_t, 31) /* task at single begin*/ \
|
||||
macro (ompt_event_single_in_block_end, ompt_parallel_callback_t, 32) /* task at single end */ \
|
||||
\
|
||||
macro (ompt_event_single_others_begin, ompt_parallel_callback_t, 33) /* task at single begin */ \
|
||||
macro (ompt_event_single_others_end, ompt_parallel_callback_t, 34) /* task at single end */ \
|
||||
\
|
||||
macro (ompt_event_workshare_begin, ompt_new_workshare_callback_t, 35) /* task at workshare begin */\
|
||||
macro (ompt_event_workshare_end, ompt_parallel_callback_t, 36) /* task at workshare end */ \
|
||||
\
|
||||
macro (ompt_event_master_begin, ompt_parallel_callback_t, 37) /* task at master begin */ \
|
||||
macro (ompt_event_master_end, ompt_parallel_callback_t, 38) /* task at master end */ \
|
||||
\
|
||||
macro (ompt_event_barrier_begin, ompt_parallel_callback_t, 39) /* task at barrier begin */ \
|
||||
macro (ompt_event_barrier_end, ompt_parallel_callback_t, 40) /* task at barrier end */ \
|
||||
\
|
||||
macro (ompt_event_taskwait_begin, ompt_parallel_callback_t, 41) /* task at taskwait begin */ \
|
||||
macro (ompt_event_taskwait_end, ompt_parallel_callback_t, 42) /* task at task wait end */ \
|
||||
\
|
||||
macro (ompt_event_taskgroup_begin, ompt_parallel_callback_t, 43) /* task at taskgroup begin */\
|
||||
macro (ompt_event_taskgroup_end, ompt_parallel_callback_t, 44) /* task at taskgroup end */ \
|
||||
\
|
||||
macro (ompt_event_release_nest_lock_prev, ompt_wait_callback_t, 45) /* prev nest lock release */ \
|
||||
\
|
||||
macro (ompt_event_wait_lock, ompt_wait_callback_t, 46) /* lock wait */ \
|
||||
macro (ompt_event_wait_nest_lock, ompt_wait_callback_t, 47) /* nest lock wait */ \
|
||||
macro (ompt_event_wait_critical, ompt_wait_callback_t, 48) /* critical wait */ \
|
||||
macro (ompt_event_wait_atomic, ompt_wait_callback_t, 49) /* atomic wait */ \
|
||||
macro (ompt_event_wait_ordered, ompt_wait_callback_t, 50) /* ordered wait */ \
|
||||
\
|
||||
macro (ompt_event_acquired_lock, ompt_wait_callback_t, 51) /* lock acquired */ \
|
||||
macro (ompt_event_acquired_nest_lock_first, ompt_wait_callback_t, 52) /* 1st nest lock acquired */ \
|
||||
macro (ompt_event_acquired_nest_lock_next, ompt_wait_callback_t, 53) /* next nest lock acquired*/ \
|
||||
macro (ompt_event_acquired_critical, ompt_wait_callback_t, 54) /* critical acquired */ \
|
||||
macro (ompt_event_acquired_atomic, ompt_wait_callback_t, 55) /* atomic acquired */ \
|
||||
macro (ompt_event_acquired_ordered, ompt_wait_callback_t, 56) /* ordered acquired */ \
|
||||
\
|
||||
macro (ompt_event_init_lock, ompt_wait_callback_t, 57) /* lock init */ \
|
||||
macro (ompt_event_init_nest_lock, ompt_wait_callback_t, 58) /* nest lock init */ \
|
||||
\
|
||||
macro (ompt_event_destroy_lock, ompt_wait_callback_t, 59) /* lock destruction */ \
|
||||
macro (ompt_event_destroy_nest_lock, ompt_wait_callback_t, 60) /* nest lock destruction */ \
|
||||
\
|
||||
macro (ompt_event_flush, ompt_callback_t, 61) /* after executing flush */ \
|
||||
\
|
||||
macro (ompt_event_task_dependences, ompt_task_dependences_callback_t, 69) /* report task dependences */\
|
||||
macro (ompt_event_task_dependence_pair, ompt_task_pair_callback_t, 70) /* report task dependence pair */
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* data types
|
||||
*****************************************************************************/
|
||||
|
||||
/*---------------------
|
||||
* identifiers
|
||||
*---------------------*/
|
||||
|
||||
typedef uint64_t ompt_thread_id_t;
|
||||
#define ompt_thread_id_none ((ompt_thread_id_t) 0) /* non-standard */
|
||||
|
||||
typedef uint64_t ompt_task_id_t;
|
||||
#define ompt_task_id_none ((ompt_task_id_t) 0) /* non-standard */
|
||||
|
||||
typedef uint64_t ompt_parallel_id_t;
|
||||
#define ompt_parallel_id_none ((ompt_parallel_id_t) 0) /* non-standard */
|
||||
|
||||
typedef uint64_t ompt_wait_id_t;
|
||||
#define ompt_wait_id_none ((ompt_wait_id_t) 0) /* non-standard */
|
||||
|
||||
|
||||
/*---------------------
|
||||
* ompt_frame_t
|
||||
*---------------------*/
|
||||
|
||||
typedef struct ompt_frame_s {
|
||||
void *exit_runtime_frame; /* next frame is user code */
|
||||
void *reenter_runtime_frame; /* previous frame is user code */
|
||||
} ompt_frame_t;
|
||||
|
||||
|
||||
/*---------------------
|
||||
* dependences types
|
||||
*---------------------*/
|
||||
|
||||
typedef enum ompt_task_dependence_flag_e {
|
||||
// a two bit field for the dependence type
|
||||
ompt_task_dependence_type_out = 1,
|
||||
ompt_task_dependence_type_in = 2,
|
||||
ompt_task_dependence_type_inout = 3,
|
||||
} ompt_task_dependence_flag_t;
|
||||
|
||||
typedef struct ompt_task_dependence_s {
|
||||
void *variable_addr;
|
||||
uint32_t dependence_flags;
|
||||
} ompt_task_dependence_t;
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* enumerations for thread states and runtime events
|
||||
*****************************************************************************/
|
||||
|
||||
/*---------------------
|
||||
* runtime states
|
||||
*---------------------*/
|
||||
|
||||
typedef enum {
|
||||
#define ompt_state_macro(state, code) state = code,
|
||||
FOREACH_OMPT_STATE(ompt_state_macro)
|
||||
#undef ompt_state_macro
|
||||
} ompt_state_t;
|
||||
|
||||
|
||||
/*---------------------
|
||||
* runtime events
|
||||
*---------------------*/
|
||||
|
||||
typedef enum {
|
||||
#define ompt_event_macro(event, callback, eventid) event = eventid,
|
||||
FOREACH_OMPT_EVENT(ompt_event_macro)
|
||||
#undef ompt_event_macro
|
||||
} ompt_event_t;
|
||||
|
||||
|
||||
/*---------------------
|
||||
* set callback results
|
||||
*---------------------*/
|
||||
typedef enum {
|
||||
ompt_set_result_registration_error = 0,
|
||||
ompt_set_result_event_may_occur_no_callback = 1,
|
||||
ompt_set_result_event_never_occurs = 2,
|
||||
ompt_set_result_event_may_occur_callback_some = 3,
|
||||
ompt_set_result_event_may_occur_callback_always = 4,
|
||||
} ompt_set_result_t;
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* callback signatures
|
||||
*****************************************************************************/
|
||||
|
||||
/* initialization */
|
||||
typedef void (*ompt_interface_fn_t)(void);
|
||||
|
||||
typedef ompt_interface_fn_t (*ompt_function_lookup_t)(
|
||||
const char * /* entry point to look up */
|
||||
);
|
||||
|
||||
/* threads */
|
||||
typedef void (*ompt_thread_callback_t) (
|
||||
ompt_thread_id_t thread_id /* ID of thread */
|
||||
);
|
||||
|
||||
typedef enum {
|
||||
ompt_thread_initial = 1, // start the enumeration at 1
|
||||
ompt_thread_worker = 2,
|
||||
ompt_thread_other = 3
|
||||
} ompt_thread_type_t;
|
||||
|
||||
typedef enum {
|
||||
ompt_invoker_program = 0, /* program invokes master task */
|
||||
ompt_invoker_runtime = 1 /* runtime invokes master task */
|
||||
} ompt_invoker_t;
|
||||
|
||||
typedef void (*ompt_thread_type_callback_t) (
|
||||
ompt_thread_type_t thread_type, /* type of thread */
|
||||
ompt_thread_id_t thread_id /* ID of thread */
|
||||
);
|
||||
|
||||
typedef void (*ompt_wait_callback_t) (
|
||||
ompt_wait_id_t wait_id /* wait id */
|
||||
);
|
||||
|
||||
/* parallel and workshares */
|
||||
typedef void (*ompt_parallel_callback_t) (
|
||||
ompt_parallel_id_t parallel_id, /* id of parallel region */
|
||||
ompt_task_id_t task_id /* id of task */
|
||||
);
|
||||
|
||||
typedef void (*ompt_new_workshare_callback_t) (
|
||||
ompt_parallel_id_t parallel_id, /* id of parallel region */
|
||||
ompt_task_id_t parent_task_id, /* id of parent task */
|
||||
void *workshare_function /* pointer to outlined function */
|
||||
);
|
||||
|
||||
typedef void (*ompt_new_parallel_callback_t) (
|
||||
ompt_task_id_t parent_task_id, /* id of parent task */
|
||||
ompt_frame_t *parent_task_frame, /* frame data of parent task */
|
||||
ompt_parallel_id_t parallel_id, /* id of parallel region */
|
||||
uint32_t requested_team_size, /* number of threads in team */
|
||||
void *parallel_function, /* pointer to outlined function */
|
||||
ompt_invoker_t invoker /* who invokes master task? */
|
||||
);
|
||||
|
||||
typedef void (*ompt_end_parallel_callback_t) (
|
||||
ompt_parallel_id_t parallel_id, /* id of parallel region */
|
||||
ompt_task_id_t task_id, /* id of task */
|
||||
ompt_invoker_t invoker /* who invokes master task? */
|
||||
);
|
||||
|
||||
/* tasks */
|
||||
typedef void (*ompt_task_callback_t) (
|
||||
ompt_task_id_t task_id /* id of task */
|
||||
);
|
||||
|
||||
typedef void (*ompt_task_pair_callback_t) (
|
||||
ompt_task_id_t first_task_id,
|
||||
ompt_task_id_t second_task_id
|
||||
);
|
||||
|
||||
typedef void (*ompt_new_task_callback_t) (
|
||||
ompt_task_id_t parent_task_id, /* id of parent task */
|
||||
ompt_frame_t *parent_task_frame, /* frame data for parent task */
|
||||
ompt_task_id_t new_task_id, /* id of created task */
|
||||
void *task_function /* pointer to outlined function */
|
||||
);
|
||||
|
||||
/* task dependences */
|
||||
typedef void (*ompt_task_dependences_callback_t) (
|
||||
ompt_task_id_t task_id, /* ID of task with dependences */
|
||||
const ompt_task_dependence_t *deps,/* vector of task dependences */
|
||||
int ndeps /* number of dependences */
|
||||
);
|
||||
|
||||
/* program */
|
||||
typedef void (*ompt_control_callback_t) (
|
||||
uint64_t command, /* command of control call */
|
||||
uint64_t modifier /* modifier of control call */
|
||||
);
|
||||
|
||||
typedef void (*ompt_callback_t)(void);
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* ompt API
|
||||
***************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define OMPT_API_FNTYPE(fn) fn##_t
|
||||
|
||||
#define OMPT_API_FUNCTION(return_type, fn, args) \
|
||||
typedef return_type (*OMPT_API_FNTYPE(fn)) args
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* INQUIRY FUNCTIONS
|
||||
***************************************************************************/
|
||||
|
||||
/* state */
|
||||
OMPT_API_FUNCTION(ompt_state_t, ompt_get_state, (
|
||||
ompt_wait_id_t *ompt_wait_id
|
||||
));
|
||||
|
||||
/* thread */
|
||||
OMPT_API_FUNCTION(ompt_thread_id_t, ompt_get_thread_id, (void));
|
||||
|
||||
OMPT_API_FUNCTION(void *, ompt_get_idle_frame, (void));
|
||||
|
||||
/* parallel region */
|
||||
OMPT_API_FUNCTION(ompt_parallel_id_t, ompt_get_parallel_id, (
|
||||
int ancestor_level
|
||||
));
|
||||
|
||||
OMPT_API_FUNCTION(int, ompt_get_parallel_team_size, (
|
||||
int ancestor_level
|
||||
));
|
||||
|
||||
/* task */
|
||||
OMPT_API_FUNCTION(ompt_task_id_t, ompt_get_task_id, (
|
||||
int depth
|
||||
));
|
||||
|
||||
OMPT_API_FUNCTION(ompt_frame_t *, ompt_get_task_frame, (
|
||||
int depth
|
||||
));
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* PLACEHOLDERS FOR PERFORMANCE REPORTING
|
||||
***************************************************************************/
|
||||
|
||||
/* idle */
|
||||
OMPT_API_FUNCTION(void, ompt_idle, (
|
||||
void
|
||||
));
|
||||
|
||||
/* overhead */
|
||||
OMPT_API_FUNCTION(void, ompt_overhead, (
|
||||
void
|
||||
));
|
||||
|
||||
/* barrier wait */
|
||||
OMPT_API_FUNCTION(void, ompt_barrier_wait, (
|
||||
void
|
||||
));
|
||||
|
||||
/* task wait */
|
||||
OMPT_API_FUNCTION(void, ompt_task_wait, (
|
||||
void
|
||||
));
|
||||
|
||||
/* mutex wait */
|
||||
OMPT_API_FUNCTION(void, ompt_mutex_wait, (
|
||||
void
|
||||
));
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* INITIALIZATION FUNCTIONS
|
||||
***************************************************************************/
|
||||
|
||||
OMPT_API_FUNCTION(void, ompt_initialize, (
|
||||
ompt_function_lookup_t ompt_fn_lookup,
|
||||
const char *runtime_version,
|
||||
unsigned int ompt_version
|
||||
));
|
||||
|
||||
|
||||
/* initialization interface to be defined by tool */
|
||||
ompt_initialize_t ompt_tool(void);
|
||||
|
||||
typedef enum opt_init_mode_e {
|
||||
ompt_init_mode_never = 0,
|
||||
ompt_init_mode_false = 1,
|
||||
ompt_init_mode_true = 2,
|
||||
ompt_init_mode_always = 3
|
||||
} ompt_init_mode_t;
|
||||
|
||||
OMPT_API_FUNCTION(int, ompt_set_callback, (
|
||||
ompt_event_t event,
|
||||
ompt_callback_t callback
|
||||
));
|
||||
|
||||
typedef enum ompt_set_callback_rc_e { /* non-standard */
|
||||
ompt_set_callback_error = 0,
|
||||
ompt_has_event_no_callback = 1,
|
||||
ompt_no_event_no_callback = 2,
|
||||
ompt_has_event_may_callback = 3,
|
||||
ompt_has_event_must_callback = 4,
|
||||
} ompt_set_callback_rc_t;
|
||||
|
||||
|
||||
OMPT_API_FUNCTION(int, ompt_get_callback, (
|
||||
ompt_event_t event,
|
||||
ompt_callback_t *callback
|
||||
));
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* MISCELLANEOUS FUNCTIONS
|
||||
***************************************************************************/
|
||||
|
||||
/* control */
|
||||
// FIXME: remove workaround for clang
|
||||
#if !defined(__clang__) && defined(_OPENMP) && (_OPENMP >= 201307)
|
||||
#pragma omp declare target
|
||||
#endif
|
||||
void ompt_control(
|
||||
uint64_t command,
|
||||
uint64_t modifier
|
||||
);
|
||||
#if !defined(__clang__) && defined(_OPENMP) && (_OPENMP >= 201307)
|
||||
#pragma omp end declare target
|
||||
#endif
|
||||
|
||||
/* state enumeration */
|
||||
OMPT_API_FUNCTION(int, ompt_enumerate_state, (
|
||||
int current_state,
|
||||
int *next_state,
|
||||
const char **next_state_name
|
||||
));
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
+2378
-2079
File diff suppressed because it is too large
Load Diff
+4528
-4409
File diff suppressed because it is too large
Load Diff
+760
-697
File diff suppressed because it is too large
Load Diff
+1405
-1580
File diff suppressed because it is too large
Load Diff
+2300
-1786
File diff suppressed because it is too large
Load Diff
+1498
-878
File diff suppressed because it is too large
Load Diff
+1723
-1512
File diff suppressed because it is too large
Load Diff
+194
-194
@@ -22,76 +22,80 @@
|
||||
@param gtid Global thread ID of encountering thread
|
||||
@param cncl_kind Cancellation kind (parallel, for, sections, taskgroup)
|
||||
|
||||
@return returns true if the cancellation request has been activated and the execution thread
|
||||
needs to proceed to the end of the canceled region.
|
||||
@return returns true if the cancellation request has been activated and the
|
||||
execution thread needs to proceed to the end of the canceled region.
|
||||
|
||||
Request cancellation of the binding OpenMP region.
|
||||
*/
|
||||
kmp_int32 __kmpc_cancel(ident_t* loc_ref, kmp_int32 gtid, kmp_int32 cncl_kind) {
|
||||
kmp_info_t *this_thr = __kmp_threads [ gtid ];
|
||||
kmp_int32 __kmpc_cancel(ident_t *loc_ref, kmp_int32 gtid, kmp_int32 cncl_kind) {
|
||||
kmp_info_t *this_thr = __kmp_threads[gtid];
|
||||
|
||||
KC_TRACE( 10, ("__kmpc_cancel: T#%d request %d OMP_CANCELLATION=%d\n", gtid, cncl_kind, __kmp_omp_cancellation) );
|
||||
KC_TRACE(10, ("__kmpc_cancel: T#%d request %d OMP_CANCELLATION=%d\n", gtid,
|
||||
cncl_kind, __kmp_omp_cancellation));
|
||||
|
||||
KMP_DEBUG_ASSERT(cncl_kind != cancel_noreq);
|
||||
KMP_DEBUG_ASSERT(cncl_kind == cancel_parallel || cncl_kind == cancel_loop ||
|
||||
cncl_kind == cancel_sections || cncl_kind == cancel_taskgroup);
|
||||
KMP_DEBUG_ASSERT(__kmp_get_gtid() == gtid);
|
||||
KMP_DEBUG_ASSERT(cncl_kind != cancel_noreq);
|
||||
KMP_DEBUG_ASSERT(cncl_kind == cancel_parallel || cncl_kind == cancel_loop ||
|
||||
cncl_kind == cancel_sections ||
|
||||
cncl_kind == cancel_taskgroup);
|
||||
KMP_DEBUG_ASSERT(__kmp_get_gtid() == gtid);
|
||||
|
||||
if (__kmp_omp_cancellation) {
|
||||
switch (cncl_kind) {
|
||||
case cancel_parallel:
|
||||
case cancel_loop:
|
||||
case cancel_sections:
|
||||
// cancellation requests for parallel and worksharing constructs
|
||||
// are handled through the team structure
|
||||
{
|
||||
kmp_team_t *this_team = this_thr->th.th_team;
|
||||
KMP_DEBUG_ASSERT(this_team);
|
||||
kmp_int32 old = KMP_COMPARE_AND_STORE_RET32(&(this_team->t.t_cancel_request), cancel_noreq, cncl_kind);
|
||||
if (old == cancel_noreq || old == cncl_kind) {
|
||||
//printf("__kmpc_cancel: this_team->t.t_cancel_request=%d @ %p\n",
|
||||
// this_team->t.t_cancel_request, &(this_team->t.t_cancel_request));
|
||||
// we do not have a cancellation request in this team or we do have one
|
||||
// that matches the current request -> cancel
|
||||
return 1 /* true */;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case cancel_taskgroup:
|
||||
// cancellation requests for a task group
|
||||
// are handled through the taskgroup structure
|
||||
{
|
||||
kmp_taskdata_t* task;
|
||||
kmp_taskgroup_t* taskgroup;
|
||||
|
||||
task = this_thr->th.th_current_task;
|
||||
KMP_DEBUG_ASSERT( task );
|
||||
|
||||
taskgroup = task->td_taskgroup;
|
||||
if (taskgroup) {
|
||||
kmp_int32 old = KMP_COMPARE_AND_STORE_RET32(&(taskgroup->cancel_request), cancel_noreq, cncl_kind);
|
||||
if (old == cancel_noreq || old == cncl_kind) {
|
||||
// we do not have a cancellation request in this taskgroup or we do have one
|
||||
// that matches the current request -> cancel
|
||||
return 1 /* true */;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// TODO: what needs to happen here?
|
||||
// the specification disallows cancellation w/o taskgroups
|
||||
// so we might do anything here, let's abort for now
|
||||
KMP_ASSERT( 0 /* false */);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
KMP_ASSERT (0 /* false */);
|
||||
if (__kmp_omp_cancellation) {
|
||||
switch (cncl_kind) {
|
||||
case cancel_parallel:
|
||||
case cancel_loop:
|
||||
case cancel_sections:
|
||||
// cancellation requests for parallel and worksharing constructs
|
||||
// are handled through the team structure
|
||||
{
|
||||
kmp_team_t *this_team = this_thr->th.th_team;
|
||||
KMP_DEBUG_ASSERT(this_team);
|
||||
kmp_int32 old = KMP_COMPARE_AND_STORE_RET32(
|
||||
&(this_team->t.t_cancel_request), cancel_noreq, cncl_kind);
|
||||
if (old == cancel_noreq || old == cncl_kind) {
|
||||
// printf("__kmpc_cancel: this_team->t.t_cancel_request=%d @ %p\n",
|
||||
// this_team->t.t_cancel_request,
|
||||
// &(this_team->t.t_cancel_request));
|
||||
// we do not have a cancellation request in this team or we do have
|
||||
// one that matches the current request -> cancel
|
||||
return 1 /* true */;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case cancel_taskgroup:
|
||||
// cancellation requests for a task group
|
||||
// are handled through the taskgroup structure
|
||||
{
|
||||
kmp_taskdata_t *task;
|
||||
kmp_taskgroup_t *taskgroup;
|
||||
|
||||
// ICV OMP_CANCELLATION=false, so we ignored this cancel request
|
||||
KMP_DEBUG_ASSERT(!__kmp_omp_cancellation);
|
||||
return 0 /* false */;
|
||||
task = this_thr->th.th_current_task;
|
||||
KMP_DEBUG_ASSERT(task);
|
||||
|
||||
taskgroup = task->td_taskgroup;
|
||||
if (taskgroup) {
|
||||
kmp_int32 old = KMP_COMPARE_AND_STORE_RET32(
|
||||
&(taskgroup->cancel_request), cancel_noreq, cncl_kind);
|
||||
if (old == cancel_noreq || old == cncl_kind) {
|
||||
// we do not have a cancellation request in this taskgroup or we do
|
||||
// have one that matches the current request -> cancel
|
||||
return 1 /* true */;
|
||||
}
|
||||
} else {
|
||||
// TODO: what needs to happen here?
|
||||
// the specification disallows cancellation w/o taskgroups
|
||||
// so we might do anything here, let's abort for now
|
||||
KMP_ASSERT(0 /* false */);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
KMP_ASSERT(0 /* false */);
|
||||
}
|
||||
}
|
||||
|
||||
// ICV OMP_CANCELLATION=false, so we ignored this cancel request
|
||||
KMP_DEBUG_ASSERT(!__kmp_omp_cancellation);
|
||||
return 0 /* false */;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -100,77 +104,77 @@ kmp_int32 __kmpc_cancel(ident_t* loc_ref, kmp_int32 gtid, kmp_int32 cncl_kind) {
|
||||
@param gtid Global thread ID of encountering thread
|
||||
@param cncl_kind Cancellation kind (parallel, for, sections, taskgroup)
|
||||
|
||||
@return returns true if a matching cancellation request has been flagged in the RTL and the
|
||||
encountering thread has to cancel..
|
||||
@return returns true if a matching cancellation request has been flagged in the
|
||||
RTL and the encountering thread has to cancel..
|
||||
|
||||
Cancellation point for the encountering thread.
|
||||
*/
|
||||
kmp_int32 __kmpc_cancellationpoint(ident_t* loc_ref, kmp_int32 gtid, kmp_int32 cncl_kind) {
|
||||
kmp_info_t *this_thr = __kmp_threads [ gtid ];
|
||||
kmp_int32 __kmpc_cancellationpoint(ident_t *loc_ref, kmp_int32 gtid,
|
||||
kmp_int32 cncl_kind) {
|
||||
kmp_info_t *this_thr = __kmp_threads[gtid];
|
||||
|
||||
KC_TRACE( 10, ("__kmpc_cancellationpoint: T#%d request %d OMP_CANCELLATION=%d\n", gtid, cncl_kind, __kmp_omp_cancellation) );
|
||||
KC_TRACE(10,
|
||||
("__kmpc_cancellationpoint: T#%d request %d OMP_CANCELLATION=%d\n",
|
||||
gtid, cncl_kind, __kmp_omp_cancellation));
|
||||
|
||||
KMP_DEBUG_ASSERT(cncl_kind != cancel_noreq);
|
||||
KMP_DEBUG_ASSERT(cncl_kind == cancel_parallel || cncl_kind == cancel_loop ||
|
||||
cncl_kind == cancel_sections || cncl_kind == cancel_taskgroup);
|
||||
KMP_DEBUG_ASSERT(__kmp_get_gtid() == gtid);
|
||||
KMP_DEBUG_ASSERT(cncl_kind != cancel_noreq);
|
||||
KMP_DEBUG_ASSERT(cncl_kind == cancel_parallel || cncl_kind == cancel_loop ||
|
||||
cncl_kind == cancel_sections ||
|
||||
cncl_kind == cancel_taskgroup);
|
||||
KMP_DEBUG_ASSERT(__kmp_get_gtid() == gtid);
|
||||
|
||||
if (__kmp_omp_cancellation) {
|
||||
switch (cncl_kind) {
|
||||
case cancel_parallel:
|
||||
case cancel_loop:
|
||||
case cancel_sections:
|
||||
// cancellation requests for parallel and worksharing constructs
|
||||
// are handled through the team structure
|
||||
{
|
||||
kmp_team_t *this_team = this_thr->th.th_team;
|
||||
KMP_DEBUG_ASSERT(this_team);
|
||||
if (this_team->t.t_cancel_request) {
|
||||
if (cncl_kind == this_team->t.t_cancel_request) {
|
||||
// the request in the team structure matches the type of
|
||||
// cancellation point so we can cancel
|
||||
return 1 /* true */;
|
||||
}
|
||||
KMP_ASSERT( 0 /* false */);
|
||||
}
|
||||
else {
|
||||
// we do not have a cancellation request pending, so we just
|
||||
// ignore this cancellation point
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case cancel_taskgroup:
|
||||
// cancellation requests for a task group
|
||||
// are handled through the taskgroup structure
|
||||
{
|
||||
kmp_taskdata_t* task;
|
||||
kmp_taskgroup_t* taskgroup;
|
||||
|
||||
task = this_thr->th.th_current_task;
|
||||
KMP_DEBUG_ASSERT( task );
|
||||
|
||||
taskgroup = task->td_taskgroup;
|
||||
if (taskgroup) {
|
||||
// return the current status of cancellation for the
|
||||
// taskgroup
|
||||
return !!taskgroup->cancel_request;
|
||||
}
|
||||
else {
|
||||
// if a cancellation point is encountered by a task
|
||||
// that does not belong to a taskgroup, it is OK
|
||||
// to ignore it
|
||||
return 0 /* false */;
|
||||
}
|
||||
}
|
||||
default:
|
||||
KMP_ASSERT (0 /* false */);
|
||||
if (__kmp_omp_cancellation) {
|
||||
switch (cncl_kind) {
|
||||
case cancel_parallel:
|
||||
case cancel_loop:
|
||||
case cancel_sections:
|
||||
// cancellation requests for parallel and worksharing constructs
|
||||
// are handled through the team structure
|
||||
{
|
||||
kmp_team_t *this_team = this_thr->th.th_team;
|
||||
KMP_DEBUG_ASSERT(this_team);
|
||||
if (this_team->t.t_cancel_request) {
|
||||
if (cncl_kind == this_team->t.t_cancel_request) {
|
||||
// the request in the team structure matches the type of
|
||||
// cancellation point so we can cancel
|
||||
return 1 /* true */;
|
||||
}
|
||||
KMP_ASSERT(0 /* false */);
|
||||
} else {
|
||||
// we do not have a cancellation request pending, so we just
|
||||
// ignore this cancellation point
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case cancel_taskgroup:
|
||||
// cancellation requests for a task group
|
||||
// are handled through the taskgroup structure
|
||||
{
|
||||
kmp_taskdata_t *task;
|
||||
kmp_taskgroup_t *taskgroup;
|
||||
|
||||
// ICV OMP_CANCELLATION=false, so we ignore the cancellation point
|
||||
KMP_DEBUG_ASSERT(!__kmp_omp_cancellation);
|
||||
return 0 /* false */;
|
||||
task = this_thr->th.th_current_task;
|
||||
KMP_DEBUG_ASSERT(task);
|
||||
|
||||
taskgroup = task->td_taskgroup;
|
||||
if (taskgroup) {
|
||||
// return the current status of cancellation for the taskgroup
|
||||
return !!taskgroup->cancel_request;
|
||||
} else {
|
||||
// if a cancellation point is encountered by a task that does not
|
||||
// belong to a taskgroup, it is OK to ignore it
|
||||
return 0 /* false */;
|
||||
}
|
||||
}
|
||||
default:
|
||||
KMP_ASSERT(0 /* false */);
|
||||
}
|
||||
}
|
||||
|
||||
// ICV OMP_CANCELLATION=false, so we ignore the cancellation point
|
||||
KMP_DEBUG_ASSERT(!__kmp_omp_cancellation);
|
||||
return 0 /* false */;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -178,63 +182,61 @@ kmp_int32 __kmpc_cancellationpoint(ident_t* loc_ref, kmp_int32 gtid, kmp_int32 c
|
||||
@param loc_ref location of the original task directive
|
||||
@param gtid Global thread ID of encountering thread
|
||||
|
||||
@return returns true if a matching cancellation request has been flagged in the RTL and the
|
||||
encountering thread has to cancel..
|
||||
@return returns true if a matching cancellation request has been flagged in the
|
||||
RTL and the encountering thread has to cancel..
|
||||
|
||||
Barrier with cancellation point to send threads from the barrier to the
|
||||
end of the parallel region. Needs a special code pattern as documented
|
||||
in the design document for the cancellation feature.
|
||||
*/
|
||||
kmp_int32
|
||||
__kmpc_cancel_barrier(ident_t *loc, kmp_int32 gtid) {
|
||||
int ret = 0 /* false */;
|
||||
kmp_info_t *this_thr = __kmp_threads [ gtid ];
|
||||
kmp_team_t *this_team = this_thr->th.th_team;
|
||||
kmp_int32 __kmpc_cancel_barrier(ident_t *loc, kmp_int32 gtid) {
|
||||
int ret = 0 /* false */;
|
||||
kmp_info_t *this_thr = __kmp_threads[gtid];
|
||||
kmp_team_t *this_team = this_thr->th.th_team;
|
||||
|
||||
KMP_DEBUG_ASSERT(__kmp_get_gtid() == gtid);
|
||||
KMP_DEBUG_ASSERT(__kmp_get_gtid() == gtid);
|
||||
|
||||
// call into the standard barrier
|
||||
__kmpc_barrier(loc, gtid);
|
||||
// call into the standard barrier
|
||||
__kmpc_barrier(loc, gtid);
|
||||
|
||||
// if cancellation is active, check cancellation flag
|
||||
if (__kmp_omp_cancellation) {
|
||||
// depending on which construct to cancel, check the flag and
|
||||
// reset the flag
|
||||
switch (this_team->t.t_cancel_request) {
|
||||
case cancel_parallel:
|
||||
ret = 1;
|
||||
// ensure that threads have checked the flag, when
|
||||
// leaving the above barrier
|
||||
__kmpc_barrier(loc, gtid);
|
||||
this_team->t.t_cancel_request = cancel_noreq;
|
||||
// the next barrier is the fork/join barrier, which
|
||||
// synchronizes the threads leaving here
|
||||
break;
|
||||
case cancel_loop:
|
||||
case cancel_sections:
|
||||
ret = 1;
|
||||
// ensure that threads have checked the flag, when
|
||||
// leaving the above barrier
|
||||
__kmpc_barrier(loc, gtid);
|
||||
this_team->t.t_cancel_request = cancel_noreq;
|
||||
// synchronize the threads again to make sure we
|
||||
// do not have any run-away threads that cause a race
|
||||
// on the cancellation flag
|
||||
__kmpc_barrier(loc, gtid);
|
||||
break;
|
||||
case cancel_taskgroup:
|
||||
// this case should not occur
|
||||
KMP_ASSERT (0 /* false */ );
|
||||
break;
|
||||
case cancel_noreq:
|
||||
// do nothing
|
||||
break;
|
||||
default:
|
||||
KMP_ASSERT ( 0 /* false */);
|
||||
}
|
||||
// if cancellation is active, check cancellation flag
|
||||
if (__kmp_omp_cancellation) {
|
||||
// depending on which construct to cancel, check the flag and
|
||||
// reset the flag
|
||||
switch (this_team->t.t_cancel_request) {
|
||||
case cancel_parallel:
|
||||
ret = 1;
|
||||
// ensure that threads have checked the flag, when
|
||||
// leaving the above barrier
|
||||
__kmpc_barrier(loc, gtid);
|
||||
this_team->t.t_cancel_request = cancel_noreq;
|
||||
// the next barrier is the fork/join barrier, which
|
||||
// synchronizes the threads leaving here
|
||||
break;
|
||||
case cancel_loop:
|
||||
case cancel_sections:
|
||||
ret = 1;
|
||||
// ensure that threads have checked the flag, when
|
||||
// leaving the above barrier
|
||||
__kmpc_barrier(loc, gtid);
|
||||
this_team->t.t_cancel_request = cancel_noreq;
|
||||
// synchronize the threads again to make sure we do not have any run-away
|
||||
// threads that cause a race on the cancellation flag
|
||||
__kmpc_barrier(loc, gtid);
|
||||
break;
|
||||
case cancel_taskgroup:
|
||||
// this case should not occur
|
||||
KMP_ASSERT(0 /* false */);
|
||||
break;
|
||||
case cancel_noreq:
|
||||
// do nothing
|
||||
break;
|
||||
default:
|
||||
KMP_ASSERT(0 /* false */);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -242,8 +244,8 @@ __kmpc_cancel_barrier(ident_t *loc, kmp_int32 gtid) {
|
||||
@param loc_ref location of the original task directive
|
||||
@param gtid Global thread ID of encountering thread
|
||||
|
||||
@return returns true if a matching cancellation request has been flagged in the RTL and the
|
||||
encountering thread has to cancel..
|
||||
@return returns true if a matching cancellation request has been flagged in the
|
||||
RTL and the encountering thread has to cancel..
|
||||
|
||||
Query function to query the current status of cancellation requests.
|
||||
Can be used to implement the following pattern:
|
||||
@@ -254,29 +256,27 @@ if (kmp_get_cancellation_status(kmp_cancel_parallel)) {
|
||||
}
|
||||
*/
|
||||
int __kmp_get_cancellation_status(int cancel_kind) {
|
||||
if (__kmp_omp_cancellation) {
|
||||
kmp_info_t *this_thr = __kmp_entry_thread();
|
||||
if (__kmp_omp_cancellation) {
|
||||
kmp_info_t *this_thr = __kmp_entry_thread();
|
||||
|
||||
switch (cancel_kind) {
|
||||
case cancel_parallel:
|
||||
case cancel_loop:
|
||||
case cancel_sections:
|
||||
{
|
||||
kmp_team_t *this_team = this_thr->th.th_team;
|
||||
return this_team->t.t_cancel_request == cancel_kind;
|
||||
}
|
||||
case cancel_taskgroup:
|
||||
{
|
||||
kmp_taskdata_t* task;
|
||||
kmp_taskgroup_t* taskgroup;
|
||||
task = this_thr->th.th_current_task;
|
||||
taskgroup = task->td_taskgroup;
|
||||
return taskgroup && taskgroup->cancel_request;
|
||||
}
|
||||
}
|
||||
switch (cancel_kind) {
|
||||
case cancel_parallel:
|
||||
case cancel_loop:
|
||||
case cancel_sections: {
|
||||
kmp_team_t *this_team = this_thr->th.th_team;
|
||||
return this_team->t.t_cancel_request == cancel_kind;
|
||||
}
|
||||
case cancel_taskgroup: {
|
||||
kmp_taskdata_t *task;
|
||||
kmp_taskgroup_t *taskgroup;
|
||||
task = this_thr->th.th_current_task;
|
||||
taskgroup = task->td_taskgroup;
|
||||
return taskgroup && taskgroup->cancel_request;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0 /* false */;
|
||||
return 0 /* false */;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+2141
-2165
File diff suppressed because it is too large
Load Diff
+86
-94
@@ -19,124 +19,116 @@
|
||||
#include "kmp_io.h"
|
||||
|
||||
#ifdef KMP_DEBUG
|
||||
void
|
||||
__kmp_debug_printf_stdout( char const * format, ... )
|
||||
{
|
||||
va_list ap;
|
||||
va_start( ap, format );
|
||||
void __kmp_debug_printf_stdout(char const *format, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
|
||||
__kmp_vprintf( kmp_out, format, ap );
|
||||
__kmp_vprintf(kmp_out, format, ap);
|
||||
|
||||
va_end(ap);
|
||||
va_end(ap);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
__kmp_debug_printf( char const * format, ... )
|
||||
{
|
||||
va_list ap;
|
||||
va_start( ap, format );
|
||||
void __kmp_debug_printf(char const *format, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
|
||||
__kmp_vprintf( kmp_err, format, ap );
|
||||
__kmp_vprintf(kmp_err, format, ap);
|
||||
|
||||
va_end( ap );
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
#ifdef KMP_USE_ASSERT
|
||||
int
|
||||
__kmp_debug_assert(
|
||||
char const * msg,
|
||||
char const * file,
|
||||
int line
|
||||
) {
|
||||
int __kmp_debug_assert(char const *msg, char const *file, int line) {
|
||||
|
||||
if ( file == NULL ) {
|
||||
file = KMP_I18N_STR( UnknownFile );
|
||||
} else {
|
||||
// Remove directories from path, leave only file name. File name is enough, there is no need
|
||||
// in bothering developers and customers with full paths.
|
||||
char const * slash = strrchr( file, '/' );
|
||||
if ( slash != NULL ) {
|
||||
file = slash + 1;
|
||||
}; // if
|
||||
}; // if
|
||||
if (file == NULL) {
|
||||
file = KMP_I18N_STR(UnknownFile);
|
||||
} else {
|
||||
// Remove directories from path, leave only file name. File name is enough,
|
||||
// there is no need in bothering developers and customers with full paths.
|
||||
char const *slash = strrchr(file, '/');
|
||||
if (slash != NULL) {
|
||||
file = slash + 1;
|
||||
}; // if
|
||||
}; // if
|
||||
|
||||
#ifdef KMP_DEBUG
|
||||
__kmp_acquire_bootstrap_lock( & __kmp_stdio_lock );
|
||||
__kmp_debug_printf( "Assertion failure at %s(%d): %s.\n", file, line, msg );
|
||||
__kmp_release_bootstrap_lock( & __kmp_stdio_lock );
|
||||
#ifdef USE_ASSERT_BREAK
|
||||
#if KMP_OS_WINDOWS
|
||||
DebugBreak();
|
||||
#endif
|
||||
#endif // USE_ASSERT_BREAK
|
||||
#ifdef USE_ASSERT_STALL
|
||||
/* __kmp_infinite_loop(); */
|
||||
for(;;);
|
||||
#endif // USE_ASSERT_STALL
|
||||
#ifdef USE_ASSERT_SEG
|
||||
{
|
||||
int volatile * ZERO = (int*) 0;
|
||||
++ (*ZERO);
|
||||
}
|
||||
#endif // USE_ASSERT_SEG
|
||||
#endif
|
||||
#ifdef KMP_DEBUG
|
||||
__kmp_acquire_bootstrap_lock(&__kmp_stdio_lock);
|
||||
__kmp_debug_printf("Assertion failure at %s(%d): %s.\n", file, line, msg);
|
||||
__kmp_release_bootstrap_lock(&__kmp_stdio_lock);
|
||||
#ifdef USE_ASSERT_BREAK
|
||||
#if KMP_OS_WINDOWS
|
||||
DebugBreak();
|
||||
#endif
|
||||
#endif // USE_ASSERT_BREAK
|
||||
#ifdef USE_ASSERT_STALL
|
||||
/* __kmp_infinite_loop(); */
|
||||
for (;;)
|
||||
;
|
||||
#endif // USE_ASSERT_STALL
|
||||
#ifdef USE_ASSERT_SEG
|
||||
{
|
||||
int volatile *ZERO = (int *)0;
|
||||
++(*ZERO);
|
||||
}
|
||||
#endif // USE_ASSERT_SEG
|
||||
#endif
|
||||
|
||||
__kmp_msg(
|
||||
kmp_ms_fatal,
|
||||
KMP_MSG( AssertionFailure, file, line ),
|
||||
KMP_HNT( SubmitBugReport ),
|
||||
__kmp_msg_null
|
||||
);
|
||||
__kmp_msg(kmp_ms_fatal, KMP_MSG(AssertionFailure, file, line),
|
||||
KMP_HNT(SubmitBugReport), __kmp_msg_null);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
|
||||
} // __kmp_debug_assert
|
||||
} // __kmp_debug_assert
|
||||
|
||||
#endif // KMP_USE_ASSERT
|
||||
|
||||
/* Dump debugging buffer to stderr */
|
||||
void
|
||||
__kmp_dump_debug_buffer( void )
|
||||
{
|
||||
if ( __kmp_debug_buffer != NULL ) {
|
||||
int i;
|
||||
int dc = __kmp_debug_count;
|
||||
char *db = & __kmp_debug_buffer[ (dc % __kmp_debug_buf_lines) * __kmp_debug_buf_chars ];
|
||||
char *db_end = & __kmp_debug_buffer[ __kmp_debug_buf_lines * __kmp_debug_buf_chars ];
|
||||
char *db2;
|
||||
void __kmp_dump_debug_buffer(void) {
|
||||
if (__kmp_debug_buffer != NULL) {
|
||||
int i;
|
||||
int dc = __kmp_debug_count;
|
||||
char *db = &__kmp_debug_buffer[(dc % __kmp_debug_buf_lines) *
|
||||
__kmp_debug_buf_chars];
|
||||
char *db_end =
|
||||
&__kmp_debug_buffer[__kmp_debug_buf_lines * __kmp_debug_buf_chars];
|
||||
char *db2;
|
||||
|
||||
__kmp_acquire_bootstrap_lock( & __kmp_stdio_lock );
|
||||
__kmp_printf_no_lock( "\nStart dump of debugging buffer (entry=%d):\n",
|
||||
dc % __kmp_debug_buf_lines );
|
||||
__kmp_acquire_bootstrap_lock(&__kmp_stdio_lock);
|
||||
__kmp_printf_no_lock("\nStart dump of debugging buffer (entry=%d):\n",
|
||||
dc % __kmp_debug_buf_lines);
|
||||
|
||||
for ( i = 0; i < __kmp_debug_buf_lines; i++ ) {
|
||||
for (i = 0; i < __kmp_debug_buf_lines; i++) {
|
||||
|
||||
if ( *db != '\0' ) {
|
||||
/* Fix up where no carriage return before string termination char */
|
||||
for ( db2 = db + 1; db2 < db + __kmp_debug_buf_chars - 1; db2 ++) {
|
||||
if ( *db2 == '\0' ) {
|
||||
if ( *(db2-1) != '\n' ) { *db2 = '\n'; *(db2+1) = '\0'; }
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Handle case at end by shortening the printed message by one char if necessary */
|
||||
if ( db2 == db + __kmp_debug_buf_chars - 1 &&
|
||||
*db2 == '\0' && *(db2-1) != '\n' ) {
|
||||
*(db2-1) = '\n';
|
||||
}
|
||||
|
||||
__kmp_printf_no_lock( "%4d: %.*s", i, __kmp_debug_buf_chars, db );
|
||||
*db = '\0'; /* only let it print once! */
|
||||
if (*db != '\0') {
|
||||
/* Fix up where no carriage return before string termination char */
|
||||
for (db2 = db + 1; db2 < db + __kmp_debug_buf_chars - 1; db2++) {
|
||||
if (*db2 == '\0') {
|
||||
if (*(db2 - 1) != '\n') {
|
||||
*db2 = '\n';
|
||||
*(db2 + 1) = '\0';
|
||||
}
|
||||
|
||||
db += __kmp_debug_buf_chars;
|
||||
if ( db >= db_end )
|
||||
db = __kmp_debug_buffer;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Handle case at end by shortening the printed message by one char if
|
||||
* necessary */
|
||||
if (db2 == db + __kmp_debug_buf_chars - 1 && *db2 == '\0' &&
|
||||
*(db2 - 1) != '\n') {
|
||||
*(db2 - 1) = '\n';
|
||||
}
|
||||
|
||||
__kmp_printf_no_lock( "End dump of debugging buffer (entry=%d).\n\n",
|
||||
( dc+i-1 ) % __kmp_debug_buf_lines );
|
||||
__kmp_release_bootstrap_lock( & __kmp_stdio_lock );
|
||||
__kmp_printf_no_lock("%4d: %.*s", i, __kmp_debug_buf_chars, db);
|
||||
*db = '\0'; /* only let it print once! */
|
||||
}
|
||||
|
||||
db += __kmp_debug_buf_chars;
|
||||
if (db >= db_end)
|
||||
db = __kmp_debug_buffer;
|
||||
}
|
||||
|
||||
__kmp_printf_no_lock("End dump of debugging buffer (entry=%d).\n\n",
|
||||
(dc + i - 1) % __kmp_debug_buf_lines);
|
||||
__kmp_release_bootstrap_lock(&__kmp_stdio_lock);
|
||||
}
|
||||
}
|
||||
|
||||
+122
-80
@@ -19,113 +19,155 @@
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------------
|
||||
// Build-time assertion.
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Build-time assertion can do compile-time checking of data structure sizes, etc. This works by
|
||||
declaring a negative-length array if the conditional expression evaluates to false. In that
|
||||
case, the compiler issues a syntax error and stops the compilation. If the expression is
|
||||
true, we get an extraneous static single character array in the scope of the macro.
|
||||
// New C++11 style build assert
|
||||
#define KMP_BUILD_ASSERT(expr) static_assert(expr, "Build condition error")
|
||||
|
||||
Usage:
|
||||
|
||||
KMP_BUILD_ASSERT( sizeof( some_t ) <= 32 );
|
||||
KMP_BUILD_ASSERT( offsetof( some_t, field ) % 8 == 0 );
|
||||
|
||||
Do not use _KMP_BUILD_ASSERT and __KMP_BUILD_ASSERT directly, it is working guts.
|
||||
*/
|
||||
|
||||
#define __KMP_BUILD_ASSERT( expr, suffix ) typedef char __kmp_build_check_##suffix[ (expr) ? 1 : -1 ]
|
||||
#define _KMP_BUILD_ASSERT( expr, suffix ) __KMP_BUILD_ASSERT( (expr), suffix )
|
||||
#ifdef KMP_USE_ASSERT
|
||||
#define KMP_BUILD_ASSERT( expr ) _KMP_BUILD_ASSERT( (expr), __LINE__ )
|
||||
#else
|
||||
#define KMP_BUILD_ASSERT( expr ) /* nothing to do */
|
||||
#endif
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------------
|
||||
// Run-time assertions.
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
|
||||
extern void __kmp_dump_debug_buffer( void );
|
||||
extern void __kmp_dump_debug_buffer(void);
|
||||
|
||||
#ifdef KMP_USE_ASSERT
|
||||
extern int __kmp_debug_assert( char const * expr, char const * file, int line );
|
||||
#ifdef KMP_DEBUG
|
||||
#define KMP_ASSERT( cond ) ( (cond) ? 0 : __kmp_debug_assert( #cond, __FILE__, __LINE__ ) )
|
||||
#define KMP_ASSERT2( cond, msg ) ( (cond) ? 0 : __kmp_debug_assert( (msg), __FILE__, __LINE__ ) )
|
||||
#define KMP_DEBUG_ASSERT( cond ) KMP_ASSERT( cond )
|
||||
#define KMP_DEBUG_ASSERT2( cond, msg ) KMP_ASSERT2( cond, msg )
|
||||
#else
|
||||
// Do not expose condition in release build. Use "assertion failure".
|
||||
#define KMP_ASSERT( cond ) ( (cond) ? 0 : __kmp_debug_assert( "assertion failure", __FILE__, __LINE__ ) )
|
||||
#define KMP_ASSERT2( cond, msg ) KMP_ASSERT( cond )
|
||||
#define KMP_DEBUG_ASSERT( cond ) 0
|
||||
#define KMP_DEBUG_ASSERT2( cond, msg ) 0
|
||||
#endif // KMP_DEBUG
|
||||
extern int __kmp_debug_assert(char const *expr, char const *file, int line);
|
||||
#ifdef KMP_DEBUG
|
||||
#define KMP_ASSERT(cond) \
|
||||
((cond) ? 0 : __kmp_debug_assert(#cond, __FILE__, __LINE__))
|
||||
#define KMP_ASSERT2(cond, msg) \
|
||||
((cond) ? 0 : __kmp_debug_assert((msg), __FILE__, __LINE__))
|
||||
#define KMP_DEBUG_ASSERT(cond) KMP_ASSERT(cond)
|
||||
#define KMP_DEBUG_ASSERT2(cond, msg) KMP_ASSERT2(cond, msg)
|
||||
#else
|
||||
#define KMP_ASSERT( cond ) 0
|
||||
#define KMP_ASSERT2( cond, msg ) 0
|
||||
#define KMP_DEBUG_ASSERT( cond ) 0
|
||||
#define KMP_DEBUG_ASSERT2( cond, msg ) 0
|
||||
// Do not expose condition in release build. Use "assertion failure".
|
||||
#define KMP_ASSERT(cond) \
|
||||
((cond) ? 0 : __kmp_debug_assert("assertion failure", __FILE__, __LINE__))
|
||||
#define KMP_ASSERT2(cond, msg) KMP_ASSERT(cond)
|
||||
#define KMP_DEBUG_ASSERT(cond) 0
|
||||
#define KMP_DEBUG_ASSERT2(cond, msg) 0
|
||||
#endif // KMP_DEBUG
|
||||
#else
|
||||
#define KMP_ASSERT(cond) 0
|
||||
#define KMP_ASSERT2(cond, msg) 0
|
||||
#define KMP_DEBUG_ASSERT(cond) 0
|
||||
#define KMP_DEBUG_ASSERT2(cond, msg) 0
|
||||
#endif // KMP_USE_ASSERT
|
||||
|
||||
#ifdef KMP_DEBUG
|
||||
extern void __kmp_debug_printf_stdout( char const * format, ... );
|
||||
extern void __kmp_debug_printf_stdout(char const *format, ...);
|
||||
#endif
|
||||
extern void __kmp_debug_printf( char const * format, ... );
|
||||
extern void __kmp_debug_printf(char const *format, ...);
|
||||
|
||||
#ifdef KMP_DEBUG
|
||||
|
||||
extern int kmp_a_debug;
|
||||
extern int kmp_b_debug;
|
||||
extern int kmp_c_debug;
|
||||
extern int kmp_d_debug;
|
||||
extern int kmp_e_debug;
|
||||
extern int kmp_f_debug;
|
||||
extern int kmp_diag;
|
||||
extern int kmp_a_debug;
|
||||
extern int kmp_b_debug;
|
||||
extern int kmp_c_debug;
|
||||
extern int kmp_d_debug;
|
||||
extern int kmp_e_debug;
|
||||
extern int kmp_f_debug;
|
||||
extern int kmp_diag;
|
||||
|
||||
#define KA_TRACE(d,x) if (kmp_a_debug >= d) { __kmp_debug_printf x ; }
|
||||
#define KB_TRACE(d,x) if (kmp_b_debug >= d) { __kmp_debug_printf x ; }
|
||||
#define KC_TRACE(d,x) if (kmp_c_debug >= d) { __kmp_debug_printf x ; }
|
||||
#define KD_TRACE(d,x) if (kmp_d_debug >= d) { __kmp_debug_printf x ; }
|
||||
#define KE_TRACE(d,x) if (kmp_e_debug >= d) { __kmp_debug_printf x ; }
|
||||
#define KF_TRACE(d,x) if (kmp_f_debug >= d) { __kmp_debug_printf x ; }
|
||||
#define K_DIAG(d,x) {if (kmp_diag == d) { __kmp_debug_printf_stdout x ; } }
|
||||
#define KA_TRACE(d, x) \
|
||||
if (kmp_a_debug >= d) { \
|
||||
__kmp_debug_printf x; \
|
||||
}
|
||||
#define KB_TRACE(d, x) \
|
||||
if (kmp_b_debug >= d) { \
|
||||
__kmp_debug_printf x; \
|
||||
}
|
||||
#define KC_TRACE(d, x) \
|
||||
if (kmp_c_debug >= d) { \
|
||||
__kmp_debug_printf x; \
|
||||
}
|
||||
#define KD_TRACE(d, x) \
|
||||
if (kmp_d_debug >= d) { \
|
||||
__kmp_debug_printf x; \
|
||||
}
|
||||
#define KE_TRACE(d, x) \
|
||||
if (kmp_e_debug >= d) { \
|
||||
__kmp_debug_printf x; \
|
||||
}
|
||||
#define KF_TRACE(d, x) \
|
||||
if (kmp_f_debug >= d) { \
|
||||
__kmp_debug_printf x; \
|
||||
}
|
||||
#define K_DIAG(d, x) \
|
||||
{ \
|
||||
if (kmp_diag == d) { \
|
||||
__kmp_debug_printf_stdout x; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define KA_DUMP(d,x) if (kmp_a_debug >= d) { int ks; __kmp_disable(&ks); (x) ; __kmp_enable(ks); }
|
||||
#define KB_DUMP(d,x) if (kmp_b_debug >= d) { int ks; __kmp_disable(&ks); (x) ; __kmp_enable(ks); }
|
||||
#define KC_DUMP(d,x) if (kmp_c_debug >= d) { int ks; __kmp_disable(&ks); (x) ; __kmp_enable(ks); }
|
||||
#define KD_DUMP(d,x) if (kmp_d_debug >= d) { int ks; __kmp_disable(&ks); (x) ; __kmp_enable(ks); }
|
||||
#define KE_DUMP(d,x) if (kmp_e_debug >= d) { int ks; __kmp_disable(&ks); (x) ; __kmp_enable(ks); }
|
||||
#define KF_DUMP(d,x) if (kmp_f_debug >= d) { int ks; __kmp_disable(&ks); (x) ; __kmp_enable(ks); }
|
||||
#define KA_DUMP(d, x) \
|
||||
if (kmp_a_debug >= d) { \
|
||||
int ks; \
|
||||
__kmp_disable(&ks); \
|
||||
(x); \
|
||||
__kmp_enable(ks); \
|
||||
}
|
||||
#define KB_DUMP(d, x) \
|
||||
if (kmp_b_debug >= d) { \
|
||||
int ks; \
|
||||
__kmp_disable(&ks); \
|
||||
(x); \
|
||||
__kmp_enable(ks); \
|
||||
}
|
||||
#define KC_DUMP(d, x) \
|
||||
if (kmp_c_debug >= d) { \
|
||||
int ks; \
|
||||
__kmp_disable(&ks); \
|
||||
(x); \
|
||||
__kmp_enable(ks); \
|
||||
}
|
||||
#define KD_DUMP(d, x) \
|
||||
if (kmp_d_debug >= d) { \
|
||||
int ks; \
|
||||
__kmp_disable(&ks); \
|
||||
(x); \
|
||||
__kmp_enable(ks); \
|
||||
}
|
||||
#define KE_DUMP(d, x) \
|
||||
if (kmp_e_debug >= d) { \
|
||||
int ks; \
|
||||
__kmp_disable(&ks); \
|
||||
(x); \
|
||||
__kmp_enable(ks); \
|
||||
}
|
||||
#define KF_DUMP(d, x) \
|
||||
if (kmp_f_debug >= d) { \
|
||||
int ks; \
|
||||
__kmp_disable(&ks); \
|
||||
(x); \
|
||||
__kmp_enable(ks); \
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define KA_TRACE(d,x) /* nothing to do */
|
||||
#define KB_TRACE(d,x) /* nothing to do */
|
||||
#define KC_TRACE(d,x) /* nothing to do */
|
||||
#define KD_TRACE(d,x) /* nothing to do */
|
||||
#define KE_TRACE(d,x) /* nothing to do */
|
||||
#define KF_TRACE(d,x) /* nothing to do */
|
||||
#define K_DIAG(d,x) {}/* nothing to do */
|
||||
#define KA_TRACE(d, x) /* nothing to do */
|
||||
#define KB_TRACE(d, x) /* nothing to do */
|
||||
#define KC_TRACE(d, x) /* nothing to do */
|
||||
#define KD_TRACE(d, x) /* nothing to do */
|
||||
#define KE_TRACE(d, x) /* nothing to do */
|
||||
#define KF_TRACE(d, x) /* nothing to do */
|
||||
#define K_DIAG(d, x) \
|
||||
{} /* nothing to do */
|
||||
|
||||
#define KA_DUMP(d,x) /* nothing to do */
|
||||
#define KB_DUMP(d,x) /* nothing to do */
|
||||
#define KC_DUMP(d,x) /* nothing to do */
|
||||
#define KD_DUMP(d,x) /* nothing to do */
|
||||
#define KE_DUMP(d,x) /* nothing to do */
|
||||
#define KF_DUMP(d,x) /* nothing to do */
|
||||
#define KA_DUMP(d, x) /* nothing to do */
|
||||
#define KB_DUMP(d, x) /* nothing to do */
|
||||
#define KC_DUMP(d, x) /* nothing to do */
|
||||
#define KD_DUMP(d, x) /* nothing to do */
|
||||
#define KE_DUMP(d, x) /* nothing to do */
|
||||
#define KF_DUMP(d, x) /* nothing to do */
|
||||
|
||||
#endif // KMP_DEBUG
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif /* KMP_DEBUG_H */
|
||||
|
||||
+185
-209
@@ -1,6 +1,6 @@
|
||||
#if USE_DEBUGGER
|
||||
/*
|
||||
* kmp_debugger.c -- debugger support.
|
||||
* kmp_debugger.cpp -- debugger support.
|
||||
*/
|
||||
|
||||
|
||||
@@ -19,47 +19,36 @@
|
||||
#include "kmp_omp.h"
|
||||
#include "kmp_str.h"
|
||||
|
||||
/*
|
||||
NOTE: All variable names are known to the debugger, do not change!
|
||||
*/
|
||||
// NOTE: All variable names are known to the debugger, do not change!
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern kmp_omp_struct_info_t __kmp_omp_debug_struct_info;
|
||||
} // extern "C"
|
||||
extern "C" {
|
||||
extern kmp_omp_struct_info_t __kmp_omp_debug_struct_info;
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
||||
int __kmp_debugging = FALSE; // Boolean whether currently debugging OpenMP RTL.
|
||||
int __kmp_debugging = FALSE; // Boolean whether currently debugging OpenMP RTL.
|
||||
|
||||
#define offset_and_size_of( structure, field ) \
|
||||
{ \
|
||||
offsetof( structure, field ), \
|
||||
sizeof( ( (structure *) NULL)->field ) \
|
||||
}
|
||||
#define offset_and_size_of(structure, field) \
|
||||
{ offsetof(structure, field), sizeof(((structure *)NULL)->field) }
|
||||
|
||||
#define offset_and_size_not_available \
|
||||
{ -1, -1 }
|
||||
#define offset_and_size_not_available \
|
||||
{ -1, -1 }
|
||||
|
||||
#define addr_and_size_of( var ) \
|
||||
{ \
|
||||
(kmp_uint64)( & var ), \
|
||||
sizeof( var ) \
|
||||
}
|
||||
#define addr_and_size_of(var) \
|
||||
{ (kmp_uint64)(&var), sizeof(var) }
|
||||
|
||||
#define nthr_buffer_size 1024
|
||||
static kmp_int32
|
||||
kmp_omp_nthr_info_buffer[ nthr_buffer_size ] =
|
||||
{ nthr_buffer_size * sizeof( kmp_int32 ) };
|
||||
static kmp_int32 kmp_omp_nthr_info_buffer[nthr_buffer_size] = {
|
||||
nthr_buffer_size * sizeof(kmp_int32)};
|
||||
|
||||
/* TODO: Check punctuation for various platforms here */
|
||||
static char func_microtask[] = "__kmp_invoke_microtask";
|
||||
static char func_fork[] = "__kmpc_fork_call";
|
||||
static char func_fork_teams[] = "__kmpc_fork_teams";
|
||||
|
||||
static char func_microtask[] = "__kmp_invoke_microtask";
|
||||
static char func_fork[] = "__kmpc_fork_call";
|
||||
static char func_fork_teams[] = "__kmpc_fork_teams";
|
||||
|
||||
// Various info about runtime structures: addresses, field offsets, sizes, etc.
|
||||
kmp_omp_struct_info_t
|
||||
__kmp_omp_debug_struct_info = {
|
||||
kmp_omp_struct_info_t __kmp_omp_debug_struct_info = {
|
||||
|
||||
/* Change this only if you make a fundamental data structure change here */
|
||||
KMP_OMP_VERSION,
|
||||
@@ -67,166 +56,167 @@ __kmp_omp_debug_struct_info = {
|
||||
/* sanity check. Only should be checked if versions are identical
|
||||
* This is also used for backward compatibility to get the runtime
|
||||
* structure size if it the runtime is older than the interface */
|
||||
sizeof( kmp_omp_struct_info_t ),
|
||||
sizeof(kmp_omp_struct_info_t),
|
||||
|
||||
/* OpenMP RTL version info. */
|
||||
addr_and_size_of( __kmp_version_major ),
|
||||
addr_and_size_of( __kmp_version_minor ),
|
||||
addr_and_size_of( __kmp_version_build ),
|
||||
addr_and_size_of( __kmp_openmp_version ),
|
||||
{ (kmp_uint64)( __kmp_copyright ) + KMP_VERSION_MAGIC_LEN, 0 }, // Skip magic prefix.
|
||||
addr_and_size_of(__kmp_version_major),
|
||||
addr_and_size_of(__kmp_version_minor),
|
||||
addr_and_size_of(__kmp_version_build),
|
||||
addr_and_size_of(__kmp_openmp_version),
|
||||
{(kmp_uint64)(__kmp_copyright) + KMP_VERSION_MAGIC_LEN,
|
||||
0}, // Skip magic prefix.
|
||||
|
||||
/* Various globals. */
|
||||
addr_and_size_of( __kmp_threads ),
|
||||
addr_and_size_of( __kmp_root ),
|
||||
addr_and_size_of( __kmp_threads_capacity ),
|
||||
addr_and_size_of( __kmp_monitor ),
|
||||
#if ! KMP_USE_DYNAMIC_LOCK
|
||||
addr_and_size_of( __kmp_user_lock_table ),
|
||||
addr_and_size_of(__kmp_threads),
|
||||
addr_and_size_of(__kmp_root),
|
||||
addr_and_size_of(__kmp_threads_capacity),
|
||||
addr_and_size_of(__kmp_monitor),
|
||||
#if !KMP_USE_DYNAMIC_LOCK
|
||||
addr_and_size_of(__kmp_user_lock_table),
|
||||
#endif
|
||||
addr_and_size_of( func_microtask ),
|
||||
addr_and_size_of( func_fork ),
|
||||
addr_and_size_of( func_fork_teams ),
|
||||
addr_and_size_of( __kmp_team_counter ),
|
||||
addr_and_size_of( __kmp_task_counter ),
|
||||
addr_and_size_of( kmp_omp_nthr_info_buffer ),
|
||||
sizeof( void * ),
|
||||
addr_and_size_of(func_microtask),
|
||||
addr_and_size_of(func_fork),
|
||||
addr_and_size_of(func_fork_teams),
|
||||
addr_and_size_of(__kmp_team_counter),
|
||||
addr_and_size_of(__kmp_task_counter),
|
||||
addr_and_size_of(kmp_omp_nthr_info_buffer),
|
||||
sizeof(void *),
|
||||
OMP_LOCK_T_SIZE < sizeof(void *),
|
||||
bs_last_barrier,
|
||||
INITIAL_TASK_DEQUE_SIZE,
|
||||
|
||||
// thread structure information
|
||||
sizeof( kmp_base_info_t ),
|
||||
offset_and_size_of( kmp_base_info_t, th_info ),
|
||||
offset_and_size_of( kmp_base_info_t, th_team ),
|
||||
offset_and_size_of( kmp_base_info_t, th_root ),
|
||||
offset_and_size_of( kmp_base_info_t, th_serial_team ),
|
||||
offset_and_size_of( kmp_base_info_t, th_ident ),
|
||||
offset_and_size_of( kmp_base_info_t, th_spin_here ),
|
||||
offset_and_size_of( kmp_base_info_t, th_next_waiting ),
|
||||
offset_and_size_of( kmp_base_info_t, th_task_team ),
|
||||
offset_and_size_of( kmp_base_info_t, th_current_task ),
|
||||
offset_and_size_of( kmp_base_info_t, th_task_state ),
|
||||
offset_and_size_of( kmp_base_info_t, th_bar ),
|
||||
offset_and_size_of( kmp_bstate_t, b_worker_arrived ),
|
||||
sizeof(kmp_base_info_t),
|
||||
offset_and_size_of(kmp_base_info_t, th_info),
|
||||
offset_and_size_of(kmp_base_info_t, th_team),
|
||||
offset_and_size_of(kmp_base_info_t, th_root),
|
||||
offset_and_size_of(kmp_base_info_t, th_serial_team),
|
||||
offset_and_size_of(kmp_base_info_t, th_ident),
|
||||
offset_and_size_of(kmp_base_info_t, th_spin_here),
|
||||
offset_and_size_of(kmp_base_info_t, th_next_waiting),
|
||||
offset_and_size_of(kmp_base_info_t, th_task_team),
|
||||
offset_and_size_of(kmp_base_info_t, th_current_task),
|
||||
offset_and_size_of(kmp_base_info_t, th_task_state),
|
||||
offset_and_size_of(kmp_base_info_t, th_bar),
|
||||
offset_and_size_of(kmp_bstate_t, b_worker_arrived),
|
||||
|
||||
#if OMP_40_ENABLED
|
||||
// teams information
|
||||
offset_and_size_of( kmp_base_info_t, th_teams_microtask),
|
||||
offset_and_size_of( kmp_base_info_t, th_teams_level),
|
||||
offset_and_size_of( kmp_teams_size_t, nteams ),
|
||||
offset_and_size_of( kmp_teams_size_t, nth ),
|
||||
offset_and_size_of(kmp_base_info_t, th_teams_microtask),
|
||||
offset_and_size_of(kmp_base_info_t, th_teams_level),
|
||||
offset_and_size_of(kmp_teams_size_t, nteams),
|
||||
offset_and_size_of(kmp_teams_size_t, nth),
|
||||
#endif
|
||||
|
||||
// kmp_desc structure (for info field above)
|
||||
sizeof( kmp_desc_base_t ),
|
||||
offset_and_size_of( kmp_desc_base_t, ds_tid ),
|
||||
offset_and_size_of( kmp_desc_base_t, ds_gtid ),
|
||||
// On Windows* OS, ds_thread contains a thread /handle/, which is not usable, while thread /id/
|
||||
// is in ds_thread_id.
|
||||
#if KMP_OS_WINDOWS
|
||||
offset_and_size_of( kmp_desc_base_t, ds_thread_id),
|
||||
#else
|
||||
offset_and_size_of( kmp_desc_base_t, ds_thread),
|
||||
#endif
|
||||
sizeof(kmp_desc_base_t),
|
||||
offset_and_size_of(kmp_desc_base_t, ds_tid),
|
||||
offset_and_size_of(kmp_desc_base_t, ds_gtid),
|
||||
// On Windows* OS, ds_thread contains a thread /handle/, which is not usable,
|
||||
// while thread /id/ is in ds_thread_id.
|
||||
#if KMP_OS_WINDOWS
|
||||
offset_and_size_of(kmp_desc_base_t, ds_thread_id),
|
||||
#else
|
||||
offset_and_size_of(kmp_desc_base_t, ds_thread),
|
||||
#endif
|
||||
|
||||
// team structure information
|
||||
sizeof( kmp_base_team_t ),
|
||||
offset_and_size_of( kmp_base_team_t, t_master_tid ),
|
||||
offset_and_size_of( kmp_base_team_t, t_ident ),
|
||||
offset_and_size_of( kmp_base_team_t, t_parent ),
|
||||
offset_and_size_of( kmp_base_team_t, t_nproc ),
|
||||
offset_and_size_of( kmp_base_team_t, t_threads ),
|
||||
offset_and_size_of( kmp_base_team_t, t_serialized ),
|
||||
offset_and_size_of( kmp_base_team_t, t_id ),
|
||||
offset_and_size_of( kmp_base_team_t, t_pkfn ),
|
||||
offset_and_size_of( kmp_base_team_t, t_task_team ),
|
||||
offset_and_size_of( kmp_base_team_t, t_implicit_task_taskdata ),
|
||||
sizeof(kmp_base_team_t),
|
||||
offset_and_size_of(kmp_base_team_t, t_master_tid),
|
||||
offset_and_size_of(kmp_base_team_t, t_ident),
|
||||
offset_and_size_of(kmp_base_team_t, t_parent),
|
||||
offset_and_size_of(kmp_base_team_t, t_nproc),
|
||||
offset_and_size_of(kmp_base_team_t, t_threads),
|
||||
offset_and_size_of(kmp_base_team_t, t_serialized),
|
||||
offset_and_size_of(kmp_base_team_t, t_id),
|
||||
offset_and_size_of(kmp_base_team_t, t_pkfn),
|
||||
offset_and_size_of(kmp_base_team_t, t_task_team),
|
||||
offset_and_size_of(kmp_base_team_t, t_implicit_task_taskdata),
|
||||
#if OMP_40_ENABLED
|
||||
offset_and_size_of( kmp_base_team_t, t_cancel_request ),
|
||||
offset_and_size_of(kmp_base_team_t, t_cancel_request),
|
||||
#endif
|
||||
offset_and_size_of( kmp_base_team_t, t_bar ),
|
||||
offset_and_size_of( kmp_balign_team_t, b_master_arrived ),
|
||||
offset_and_size_of( kmp_balign_team_t, b_team_arrived ),
|
||||
offset_and_size_of(kmp_base_team_t, t_bar),
|
||||
offset_and_size_of(kmp_balign_team_t, b_master_arrived),
|
||||
offset_and_size_of(kmp_balign_team_t, b_team_arrived),
|
||||
|
||||
// root structure information
|
||||
sizeof( kmp_base_root_t ),
|
||||
offset_and_size_of( kmp_base_root_t, r_root_team ),
|
||||
offset_and_size_of( kmp_base_root_t, r_hot_team ),
|
||||
offset_and_size_of( kmp_base_root_t, r_uber_thread ),
|
||||
sizeof(kmp_base_root_t),
|
||||
offset_and_size_of(kmp_base_root_t, r_root_team),
|
||||
offset_and_size_of(kmp_base_root_t, r_hot_team),
|
||||
offset_and_size_of(kmp_base_root_t, r_uber_thread),
|
||||
offset_and_size_not_available,
|
||||
|
||||
// ident structure information
|
||||
sizeof( ident_t ),
|
||||
offset_and_size_of( ident_t, psource ),
|
||||
offset_and_size_of( ident_t, flags ),
|
||||
sizeof(ident_t),
|
||||
offset_and_size_of(ident_t, psource),
|
||||
offset_and_size_of(ident_t, flags),
|
||||
|
||||
// lock structure information
|
||||
sizeof( kmp_base_queuing_lock_t ),
|
||||
offset_and_size_of( kmp_base_queuing_lock_t, initialized ),
|
||||
offset_and_size_of( kmp_base_queuing_lock_t, location ),
|
||||
offset_and_size_of( kmp_base_queuing_lock_t, tail_id ),
|
||||
offset_and_size_of( kmp_base_queuing_lock_t, head_id ),
|
||||
offset_and_size_of( kmp_base_queuing_lock_t, next_ticket ),
|
||||
offset_and_size_of( kmp_base_queuing_lock_t, now_serving ),
|
||||
offset_and_size_of( kmp_base_queuing_lock_t, owner_id ),
|
||||
offset_and_size_of( kmp_base_queuing_lock_t, depth_locked ),
|
||||
offset_and_size_of( kmp_base_queuing_lock_t, flags ),
|
||||
sizeof(kmp_base_queuing_lock_t),
|
||||
offset_and_size_of(kmp_base_queuing_lock_t, initialized),
|
||||
offset_and_size_of(kmp_base_queuing_lock_t, location),
|
||||
offset_and_size_of(kmp_base_queuing_lock_t, tail_id),
|
||||
offset_and_size_of(kmp_base_queuing_lock_t, head_id),
|
||||
offset_and_size_of(kmp_base_queuing_lock_t, next_ticket),
|
||||
offset_and_size_of(kmp_base_queuing_lock_t, now_serving),
|
||||
offset_and_size_of(kmp_base_queuing_lock_t, owner_id),
|
||||
offset_and_size_of(kmp_base_queuing_lock_t, depth_locked),
|
||||
offset_and_size_of(kmp_base_queuing_lock_t, flags),
|
||||
|
||||
#if ! KMP_USE_DYNAMIC_LOCK
|
||||
#if !KMP_USE_DYNAMIC_LOCK
|
||||
/* Lock table. */
|
||||
sizeof( kmp_lock_table_t ),
|
||||
offset_and_size_of( kmp_lock_table_t, used ),
|
||||
offset_and_size_of( kmp_lock_table_t, allocated ),
|
||||
offset_and_size_of( kmp_lock_table_t, table ),
|
||||
sizeof(kmp_lock_table_t),
|
||||
offset_and_size_of(kmp_lock_table_t, used),
|
||||
offset_and_size_of(kmp_lock_table_t, allocated),
|
||||
offset_and_size_of(kmp_lock_table_t, table),
|
||||
#endif
|
||||
|
||||
// Task team structure information.
|
||||
sizeof( kmp_base_task_team_t ),
|
||||
offset_and_size_of( kmp_base_task_team_t, tt_threads_data ),
|
||||
offset_and_size_of( kmp_base_task_team_t, tt_found_tasks ),
|
||||
offset_and_size_of( kmp_base_task_team_t, tt_nproc ),
|
||||
offset_and_size_of( kmp_base_task_team_t, tt_unfinished_threads ),
|
||||
offset_and_size_of( kmp_base_task_team_t, tt_active ),
|
||||
sizeof(kmp_base_task_team_t),
|
||||
offset_and_size_of(kmp_base_task_team_t, tt_threads_data),
|
||||
offset_and_size_of(kmp_base_task_team_t, tt_found_tasks),
|
||||
offset_and_size_of(kmp_base_task_team_t, tt_nproc),
|
||||
offset_and_size_of(kmp_base_task_team_t, tt_unfinished_threads),
|
||||
offset_and_size_of(kmp_base_task_team_t, tt_active),
|
||||
|
||||
// task_data_t.
|
||||
sizeof( kmp_taskdata_t ),
|
||||
offset_and_size_of( kmp_taskdata_t, td_task_id ),
|
||||
offset_and_size_of( kmp_taskdata_t, td_flags ),
|
||||
offset_and_size_of( kmp_taskdata_t, td_team ),
|
||||
offset_and_size_of( kmp_taskdata_t, td_parent ),
|
||||
offset_and_size_of( kmp_taskdata_t, td_level ),
|
||||
offset_and_size_of( kmp_taskdata_t, td_ident ),
|
||||
offset_and_size_of( kmp_taskdata_t, td_allocated_child_tasks ),
|
||||
offset_and_size_of( kmp_taskdata_t, td_incomplete_child_tasks ),
|
||||
sizeof(kmp_taskdata_t),
|
||||
offset_and_size_of(kmp_taskdata_t, td_task_id),
|
||||
offset_and_size_of(kmp_taskdata_t, td_flags),
|
||||
offset_and_size_of(kmp_taskdata_t, td_team),
|
||||
offset_and_size_of(kmp_taskdata_t, td_parent),
|
||||
offset_and_size_of(kmp_taskdata_t, td_level),
|
||||
offset_and_size_of(kmp_taskdata_t, td_ident),
|
||||
offset_and_size_of(kmp_taskdata_t, td_allocated_child_tasks),
|
||||
offset_and_size_of(kmp_taskdata_t, td_incomplete_child_tasks),
|
||||
|
||||
offset_and_size_of( kmp_taskdata_t, td_taskwait_ident ),
|
||||
offset_and_size_of( kmp_taskdata_t, td_taskwait_counter ),
|
||||
offset_and_size_of( kmp_taskdata_t, td_taskwait_thread ),
|
||||
offset_and_size_of(kmp_taskdata_t, td_taskwait_ident),
|
||||
offset_and_size_of(kmp_taskdata_t, td_taskwait_counter),
|
||||
offset_and_size_of(kmp_taskdata_t, td_taskwait_thread),
|
||||
|
||||
#if OMP_40_ENABLED
|
||||
offset_and_size_of( kmp_taskdata_t, td_taskgroup ),
|
||||
offset_and_size_of( kmp_taskgroup_t, count ),
|
||||
offset_and_size_of( kmp_taskgroup_t, cancel_request ),
|
||||
offset_and_size_of(kmp_taskdata_t, td_taskgroup),
|
||||
offset_and_size_of(kmp_taskgroup_t, count),
|
||||
offset_and_size_of(kmp_taskgroup_t, cancel_request),
|
||||
|
||||
offset_and_size_of( kmp_taskdata_t, td_depnode ),
|
||||
offset_and_size_of( kmp_depnode_list_t, node ),
|
||||
offset_and_size_of( kmp_depnode_list_t, next ),
|
||||
offset_and_size_of( kmp_base_depnode_t, successors ),
|
||||
offset_and_size_of( kmp_base_depnode_t, task ),
|
||||
offset_and_size_of( kmp_base_depnode_t, npredecessors ),
|
||||
offset_and_size_of( kmp_base_depnode_t, nrefs ),
|
||||
offset_and_size_of(kmp_taskdata_t, td_depnode),
|
||||
offset_and_size_of(kmp_depnode_list_t, node),
|
||||
offset_and_size_of(kmp_depnode_list_t, next),
|
||||
offset_and_size_of(kmp_base_depnode_t, successors),
|
||||
offset_and_size_of(kmp_base_depnode_t, task),
|
||||
offset_and_size_of(kmp_base_depnode_t, npredecessors),
|
||||
offset_and_size_of(kmp_base_depnode_t, nrefs),
|
||||
#endif
|
||||
offset_and_size_of( kmp_task_t, routine ),
|
||||
offset_and_size_of(kmp_task_t, routine),
|
||||
|
||||
// thread_data_t.
|
||||
sizeof( kmp_thread_data_t ),
|
||||
offset_and_size_of( kmp_base_thread_data_t, td_deque ),
|
||||
offset_and_size_of( kmp_base_thread_data_t, td_deque_size ),
|
||||
offset_and_size_of( kmp_base_thread_data_t, td_deque_head ),
|
||||
offset_and_size_of( kmp_base_thread_data_t, td_deque_tail ),
|
||||
offset_and_size_of( kmp_base_thread_data_t, td_deque_ntasks ),
|
||||
offset_and_size_of( kmp_base_thread_data_t, td_deque_last_stolen ),
|
||||
sizeof(kmp_thread_data_t),
|
||||
offset_and_size_of(kmp_base_thread_data_t, td_deque),
|
||||
offset_and_size_of(kmp_base_thread_data_t, td_deque_size),
|
||||
offset_and_size_of(kmp_base_thread_data_t, td_deque_head),
|
||||
offset_and_size_of(kmp_base_thread_data_t, td_deque_tail),
|
||||
offset_and_size_of(kmp_base_thread_data_t, td_deque_ntasks),
|
||||
offset_and_size_of(kmp_base_thread_data_t, td_deque_last_stolen),
|
||||
|
||||
// The last field.
|
||||
KMP_OMP_VERSION,
|
||||
@@ -236,80 +226,66 @@ __kmp_omp_debug_struct_info = {
|
||||
#undef offset_and_size_of
|
||||
#undef addr_and_size_of
|
||||
|
||||
/*
|
||||
Intel compiler on IA-32 architecture issues a warning "conversion
|
||||
/* Intel compiler on IA-32 architecture issues a warning "conversion
|
||||
from "unsigned long long" to "char *" may lose significant bits"
|
||||
when 64-bit value is assigned to 32-bit pointer. Use this function
|
||||
to suppress the warning.
|
||||
*/
|
||||
static inline
|
||||
void *
|
||||
__kmp_convert_to_ptr(
|
||||
kmp_uint64 addr
|
||||
) {
|
||||
#if KMP_COMPILER_ICC
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable: 810 ) // conversion from "unsigned long long" to "char *" may lose significant bits
|
||||
#pragma warning( disable: 1195 ) // conversion from integer to smaller pointer
|
||||
#endif // KMP_COMPILER_ICC
|
||||
return (void *) addr;
|
||||
#if KMP_COMPILER_ICC
|
||||
#pragma warning( pop )
|
||||
#endif // KMP_COMPILER_ICC
|
||||
to suppress the warning. */
|
||||
static inline void *__kmp_convert_to_ptr(kmp_uint64 addr) {
|
||||
#if KMP_COMPILER_ICC
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 810) // conversion from "unsigned long long" to "char
|
||||
// *" may lose significant bits
|
||||
#pragma warning(disable : 1195) // conversion from integer to smaller pointer
|
||||
#endif // KMP_COMPILER_ICC
|
||||
return (void *)addr;
|
||||
#if KMP_COMPILER_ICC
|
||||
#pragma warning(pop)
|
||||
#endif // KMP_COMPILER_ICC
|
||||
} // __kmp_convert_to_ptr
|
||||
|
||||
static int kmp_location_match(kmp_str_loc_t *loc, kmp_omp_nthr_item_t *item) {
|
||||
|
||||
static int
|
||||
kmp_location_match(
|
||||
kmp_str_loc_t * loc,
|
||||
kmp_omp_nthr_item_t * item
|
||||
) {
|
||||
int file_match = 0;
|
||||
int func_match = 0;
|
||||
int line_match = 0;
|
||||
|
||||
int file_match = 0;
|
||||
int func_match = 0;
|
||||
int line_match = 0;
|
||||
char *file = (char *)__kmp_convert_to_ptr(item->file);
|
||||
char *func = (char *)__kmp_convert_to_ptr(item->func);
|
||||
file_match = __kmp_str_fname_match(&loc->fname, file);
|
||||
func_match =
|
||||
item->func == 0 // If item->func is NULL, it allows any func name.
|
||||
|| strcmp(func, "*") == 0 ||
|
||||
(loc->func != NULL && strcmp(loc->func, func) == 0);
|
||||
line_match =
|
||||
item->begin <= loc->line &&
|
||||
(item->end <= 0 ||
|
||||
loc->line <= item->end); // if item->end <= 0, it means "end of file".
|
||||
|
||||
char * file = (char *) __kmp_convert_to_ptr( item->file );
|
||||
char * func = (char *) __kmp_convert_to_ptr( item->func );
|
||||
file_match = __kmp_str_fname_match( & loc->fname, file );
|
||||
func_match =
|
||||
item->func == 0 // If item->func is NULL, it allows any func name.
|
||||
||
|
||||
strcmp( func, "*" ) == 0
|
||||
||
|
||||
( loc->func != NULL && strcmp( loc->func, func ) == 0 );
|
||||
line_match =
|
||||
item->begin <= loc->line
|
||||
&&
|
||||
( item->end <= 0 || loc->line <= item->end ); // if item->end <= 0, it means "end of file".
|
||||
|
||||
return ( file_match && func_match && line_match );
|
||||
return (file_match && func_match && line_match);
|
||||
|
||||
} // kmp_location_match
|
||||
|
||||
int __kmp_omp_num_threads(ident_t const *ident) {
|
||||
|
||||
int
|
||||
__kmp_omp_num_threads(
|
||||
ident_t const * ident
|
||||
) {
|
||||
int num_threads = 0;
|
||||
|
||||
int num_threads = 0;
|
||||
kmp_omp_nthr_info_t *info = (kmp_omp_nthr_info_t *)__kmp_convert_to_ptr(
|
||||
__kmp_omp_debug_struct_info.nthr_info.addr);
|
||||
if (info->num > 0 && info->array != 0) {
|
||||
kmp_omp_nthr_item_t *items =
|
||||
(kmp_omp_nthr_item_t *)__kmp_convert_to_ptr(info->array);
|
||||
kmp_str_loc_t loc = __kmp_str_loc_init(ident->psource, 1);
|
||||
int i;
|
||||
for (i = 0; i < info->num; ++i) {
|
||||
if (kmp_location_match(&loc, &items[i])) {
|
||||
num_threads = items[i].num_threads;
|
||||
}; // if
|
||||
}; // for
|
||||
__kmp_str_loc_free(&loc);
|
||||
}; // if
|
||||
|
||||
kmp_omp_nthr_info_t * info =
|
||||
(kmp_omp_nthr_info_t *) __kmp_convert_to_ptr( __kmp_omp_debug_struct_info.nthr_info.addr );
|
||||
if ( info->num > 0 && info->array != 0 ) {
|
||||
kmp_omp_nthr_item_t * items = (kmp_omp_nthr_item_t *) __kmp_convert_to_ptr( info->array );
|
||||
kmp_str_loc_t loc = __kmp_str_loc_init( ident->psource, 1 );
|
||||
int i;
|
||||
for ( i = 0; i < info->num; ++ i ) {
|
||||
if ( kmp_location_match( & loc, & items[ i ] ) ) {
|
||||
num_threads = items[ i ].num_threads;
|
||||
}; // if
|
||||
}; // for
|
||||
__kmp_str_loc_free( & loc );
|
||||
}; // if
|
||||
|
||||
return num_threads;;
|
||||
return num_threads;
|
||||
;
|
||||
|
||||
} // __kmp_omp_num_threads
|
||||
#endif /* USE_DEBUGGER */
|
||||
|
||||
+21
-21
@@ -18,34 +18,34 @@
|
||||
#define KMP_DEBUGGER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
/* * This external variable can be set by any debugger to flag to the runtime that we
|
||||
are currently executing inside a debugger. This will allow the debugger to override
|
||||
the number of threads spawned in a parallel region by using __kmp_omp_num_threads() (below).
|
||||
* When __kmp_debugging is TRUE, each team and each task gets a unique integer identifier
|
||||
that can be used by debugger to conveniently identify teams and tasks.
|
||||
* The debugger has access to __kmp_omp_debug_struct_info which contains information
|
||||
about the OpenMP library's important internal structures. This access will allow the debugger
|
||||
to read detailed information from the typical OpenMP constructs (teams, threads, tasking, etc. )
|
||||
during a debugging session and offer detailed and useful information which the user can probe
|
||||
about the OpenMP portion of their code.
|
||||
*/
|
||||
extern int __kmp_debugging; /* Boolean whether currently debugging OpenMP RTL */
|
||||
/* This external variable can be set by any debugger to flag to the runtime
|
||||
that we are currently executing inside a debugger. This will allow the
|
||||
debugger to override the number of threads spawned in a parallel region by
|
||||
using __kmp_omp_num_threads() (below).
|
||||
* When __kmp_debugging is TRUE, each team and each task gets a unique integer
|
||||
identifier that can be used by debugger to conveniently identify teams and
|
||||
tasks.
|
||||
* The debugger has access to __kmp_omp_debug_struct_info which contains
|
||||
information about the OpenMP library's important internal structures. This
|
||||
access will allow the debugger to read detailed information from the typical
|
||||
OpenMP constructs (teams, threads, tasking, etc. ) during a debugging
|
||||
session and offer detailed and useful information which the user can probe
|
||||
about the OpenMP portion of their code. */
|
||||
extern int __kmp_debugging; /* Boolean whether currently debugging OpenMP RTL */
|
||||
// Return number of threads specified by the debugger for given parallel region.
|
||||
/* The ident field, which represents a source file location, is used to check if the
|
||||
debugger has changed the number of threads for the parallel region at source file
|
||||
location ident. This way, specific parallel regions' number of threads can be changed
|
||||
at the debugger's request.
|
||||
*/
|
||||
int __kmp_omp_num_threads( ident_t const * ident );
|
||||
/* The ident field, which represents a source file location, is used to check if
|
||||
the debugger has changed the number of threads for the parallel region at
|
||||
source file location ident. This way, specific parallel regions' number of
|
||||
threads can be changed at the debugger's request. */
|
||||
int __kmp_omp_num_threads(ident_t const *ident);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
||||
|
||||
#endif // KMP_DEBUGGER_H
|
||||
|
||||
#endif // USE_DEBUGGER
|
||||
|
||||
+2464
-2414
File diff suppressed because it is too large
Load Diff
+381
-464
@@ -13,355 +13,297 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------------------------
|
||||
We use GetEnvironmentVariable for Windows* OS instead of getenv because the act of
|
||||
loading a DLL on Windows* OS makes any user-set environment variables (i.e. with putenv())
|
||||
unavailable. getenv() apparently gets a clean copy of the env variables as they existed
|
||||
at the start of the run.
|
||||
JH 12/23/2002
|
||||
------------------------------------------------------------------------------------------------
|
||||
On Windows* OS, there are two environments (at least, see below):
|
||||
/* We use GetEnvironmentVariable for Windows* OS instead of getenv because the
|
||||
act of loading a DLL on Windows* OS makes any user-set environment variables
|
||||
(i.e. with putenv()) unavailable. getenv() apparently gets a clean copy of
|
||||
the env variables as they existed at the start of the run. JH 12/23/2002
|
||||
|
||||
1. Environment maintained by Windows* OS on IA-32 architecture.
|
||||
Accessible through GetEnvironmentVariable(),
|
||||
SetEnvironmentVariable(), and GetEnvironmentStrings().
|
||||
On Windows* OS, there are two environments (at least, see below):
|
||||
|
||||
2. Environment maintained by C RTL. Accessible through getenv(), putenv().
|
||||
1. Environment maintained by Windows* OS on IA-32 architecture. Accessible
|
||||
through GetEnvironmentVariable(), SetEnvironmentVariable(), and
|
||||
GetEnvironmentStrings().
|
||||
|
||||
putenv() function updates both C and Windows* OS on IA-32 architecture. getenv() function
|
||||
search for variables in C RTL environment only. Windows* OS on IA-32 architecture functions work *only*
|
||||
with Windows* OS on IA-32 architecture.
|
||||
2. Environment maintained by C RTL. Accessible through getenv(), putenv().
|
||||
|
||||
Windows* OS on IA-32 architecture maintained by OS, so there is always only one Windows* OS on
|
||||
IA-32 architecture per process. Changes in Windows* OS on IA-32 architecture are process-visible.
|
||||
putenv() function updates both C and Windows* OS on IA-32 architecture.
|
||||
getenv() function search for variables in C RTL environment only.
|
||||
Windows* OS on IA-32 architecture functions work *only* with Windows* OS on
|
||||
IA-32 architecture.
|
||||
|
||||
C environment maintained by C RTL. Multiple copies of C RTL may be present in the process, and
|
||||
each C RTL maintains its own environment. :-(
|
||||
Windows* OS on IA-32 architecture maintained by OS, so there is always only
|
||||
one Windows* OS on IA-32 architecture per process. Changes in Windows* OS on
|
||||
IA-32 architecture are process-visible.
|
||||
|
||||
Thus, proper way to work with environment on Windows* OS is:
|
||||
C environment maintained by C RTL. Multiple copies of C RTL may be present
|
||||
in the process, and each C RTL maintains its own environment. :-(
|
||||
|
||||
1. Set variables with putenv() function -- both C and Windows* OS on
|
||||
IA-32 architecture are being updated. Windows* OS on
|
||||
IA-32 architecture may be considered as primary target,
|
||||
while updating C RTL environment is a free bonus.
|
||||
Thus, proper way to work with environment on Windows* OS is:
|
||||
|
||||
2. Get variables with GetEnvironmentVariable() -- getenv() does not
|
||||
search Windows* OS on IA-32 architecture, and can not see variables
|
||||
set with SetEnvironmentVariable().
|
||||
1. Set variables with putenv() function -- both C and Windows* OS on IA-32
|
||||
architecture are being updated. Windows* OS on IA-32 architecture may be
|
||||
considered primary target, while updating C RTL environment is free bonus.
|
||||
|
||||
2007-04-05 -- lev
|
||||
------------------------------------------------------------------------------------------------
|
||||
2. Get variables with GetEnvironmentVariable() -- getenv() does not
|
||||
search Windows* OS on IA-32 architecture, and can not see variables
|
||||
set with SetEnvironmentVariable().
|
||||
|
||||
2007-04-05 -- lev
|
||||
*/
|
||||
|
||||
#include "kmp_environment.h"
|
||||
|
||||
#include "kmp_os.h" // KMP_OS_*.
|
||||
#include "kmp.h" //
|
||||
#include "kmp_str.h" // __kmp_str_*().
|
||||
#include "kmp.h" //
|
||||
#include "kmp_i18n.h"
|
||||
#include "kmp_os.h" // KMP_OS_*.
|
||||
#include "kmp_str.h" // __kmp_str_*().
|
||||
|
||||
#if KMP_OS_UNIX
|
||||
#include <stdlib.h> // getenv, setenv, unsetenv.
|
||||
#include <string.h> // strlen, strcpy.
|
||||
#if KMP_OS_DARWIN
|
||||
#include <crt_externs.h>
|
||||
#define environ (*_NSGetEnviron())
|
||||
#else
|
||||
extern char * * environ;
|
||||
#endif
|
||||
#elif KMP_OS_WINDOWS
|
||||
#include <windows.h> // GetEnvironmentVariable, SetEnvironmentVariable, GetLastError.
|
||||
#include <stdlib.h> // getenv, setenv, unsetenv.
|
||||
#include <string.h> // strlen, strcpy.
|
||||
#if KMP_OS_DARWIN
|
||||
#include <crt_externs.h>
|
||||
#define environ (*_NSGetEnviron())
|
||||
#else
|
||||
#error Unknown or unsupported OS.
|
||||
extern char **environ;
|
||||
#endif
|
||||
#elif KMP_OS_WINDOWS
|
||||
#include <windows.h> // GetEnvironmentVariable, SetEnvironmentVariable,
|
||||
// GetLastError.
|
||||
#else
|
||||
#error Unknown or unsupported OS.
|
||||
#endif
|
||||
|
||||
|
||||
// TODO: Eliminate direct memory allocations, use string operations instead.
|
||||
|
||||
static inline
|
||||
void *
|
||||
allocate(
|
||||
size_t size
|
||||
) {
|
||||
void * ptr = KMP_INTERNAL_MALLOC( size );
|
||||
if ( ptr == NULL ) {
|
||||
KMP_FATAL( MemoryAllocFailed );
|
||||
}; // if
|
||||
return ptr;
|
||||
static inline void *allocate(size_t size) {
|
||||
void *ptr = KMP_INTERNAL_MALLOC(size);
|
||||
if (ptr == NULL) {
|
||||
KMP_FATAL(MemoryAllocFailed);
|
||||
}; // if
|
||||
return ptr;
|
||||
} // allocate
|
||||
|
||||
char *__kmp_env_get(char const *name) {
|
||||
|
||||
char *
|
||||
__kmp_env_get( char const * name ) {
|
||||
char *result = NULL;
|
||||
|
||||
char * result = NULL;
|
||||
#if KMP_OS_UNIX
|
||||
char const *value = getenv(name);
|
||||
if (value != NULL) {
|
||||
size_t len = KMP_STRLEN(value) + 1;
|
||||
result = (char *)KMP_INTERNAL_MALLOC(len);
|
||||
if (result == NULL) {
|
||||
KMP_FATAL(MemoryAllocFailed);
|
||||
}; // if
|
||||
KMP_STRNCPY_S(result, len, value, len);
|
||||
}; // if
|
||||
#elif KMP_OS_WINDOWS
|
||||
/* We use GetEnvironmentVariable for Windows* OS instead of getenv because the
|
||||
act of loading a DLL on Windows* OS makes any user-set environment
|
||||
variables (i.e. with putenv()) unavailable. getenv() apparently gets a
|
||||
clean copy of the env variables as they existed at the start of the run.
|
||||
JH 12/23/2002 */
|
||||
DWORD rc;
|
||||
rc = GetEnvironmentVariable(name, NULL, 0);
|
||||
if (!rc) {
|
||||
DWORD error = GetLastError();
|
||||
if (error != ERROR_ENVVAR_NOT_FOUND) {
|
||||
__kmp_msg(kmp_ms_fatal, KMP_MSG(CantGetEnvVar, name), KMP_ERR(error),
|
||||
__kmp_msg_null);
|
||||
}; // if
|
||||
// Variable is not found, it's ok, just continue.
|
||||
} else {
|
||||
DWORD len = rc;
|
||||
result = (char *)KMP_INTERNAL_MALLOC(len);
|
||||
if (result == NULL) {
|
||||
KMP_FATAL(MemoryAllocFailed);
|
||||
}; // if
|
||||
rc = GetEnvironmentVariable(name, result, len);
|
||||
if (!rc) {
|
||||
// GetEnvironmentVariable() may return 0 if variable is empty.
|
||||
// In such a case GetLastError() returns ERROR_SUCCESS.
|
||||
DWORD error = GetLastError();
|
||||
if (error != ERROR_SUCCESS) {
|
||||
// Unexpected error. The variable should be in the environment,
|
||||
// and buffer should be large enough.
|
||||
__kmp_msg(kmp_ms_fatal, KMP_MSG(CantGetEnvVar, name), KMP_ERR(error),
|
||||
__kmp_msg_null);
|
||||
KMP_INTERNAL_FREE((void *)result);
|
||||
result = NULL;
|
||||
}; // if
|
||||
}; // if
|
||||
}; // if
|
||||
#else
|
||||
#error Unknown or unsupported OS.
|
||||
#endif
|
||||
|
||||
#if KMP_OS_UNIX
|
||||
char const * value = getenv( name );
|
||||
if ( value != NULL ) {
|
||||
size_t len = KMP_STRLEN( value ) + 1;
|
||||
result = (char *) KMP_INTERNAL_MALLOC( len );
|
||||
if ( result == NULL ) {
|
||||
KMP_FATAL( MemoryAllocFailed );
|
||||
}; // if
|
||||
KMP_STRNCPY_S( result, len, value, len );
|
||||
}; // if
|
||||
#elif KMP_OS_WINDOWS
|
||||
/*
|
||||
We use GetEnvironmentVariable for Windows* OS instead of getenv because the act of
|
||||
loading a DLL on Windows* OS makes any user-set environment variables (i.e. with putenv())
|
||||
unavailable. getenv() apparently gets a clean copy of the env variables as they existed
|
||||
at the start of the run.
|
||||
JH 12/23/2002
|
||||
*/
|
||||
DWORD rc;
|
||||
rc = GetEnvironmentVariable( name, NULL, 0 );
|
||||
if ( ! rc ) {
|
||||
DWORD error = GetLastError();
|
||||
if ( error != ERROR_ENVVAR_NOT_FOUND ) {
|
||||
__kmp_msg(
|
||||
kmp_ms_fatal,
|
||||
KMP_MSG( CantGetEnvVar, name ),
|
||||
KMP_ERR( error ),
|
||||
__kmp_msg_null
|
||||
);
|
||||
}; // if
|
||||
// Variable is not found, it's ok, just continue.
|
||||
} else {
|
||||
DWORD len = rc;
|
||||
result = (char *) KMP_INTERNAL_MALLOC( len );
|
||||
if ( result == NULL ) {
|
||||
KMP_FATAL( MemoryAllocFailed );
|
||||
}; // if
|
||||
rc = GetEnvironmentVariable( name, result, len );
|
||||
if ( ! rc ) {
|
||||
// GetEnvironmentVariable() may return 0 if variable is empty.
|
||||
// In such a case GetLastError() returns ERROR_SUCCESS.
|
||||
DWORD error = GetLastError();
|
||||
if ( error != ERROR_SUCCESS ) {
|
||||
// Unexpected error. The variable should be in the environment,
|
||||
// and buffer should be large enough.
|
||||
__kmp_msg(
|
||||
kmp_ms_fatal,
|
||||
KMP_MSG( CantGetEnvVar, name ),
|
||||
KMP_ERR( error ),
|
||||
__kmp_msg_null
|
||||
);
|
||||
KMP_INTERNAL_FREE( (void *) result );
|
||||
result = NULL;
|
||||
}; // if
|
||||
}; // if
|
||||
}; // if
|
||||
#else
|
||||
#error Unknown or unsupported OS.
|
||||
#endif
|
||||
|
||||
return result;
|
||||
return result;
|
||||
|
||||
} // func __kmp_env_get
|
||||
|
||||
|
||||
// TODO: Find and replace all regular free() with __kmp_env_free().
|
||||
|
||||
void
|
||||
__kmp_env_free( char const * * value ) {
|
||||
void __kmp_env_free(char const **value) {
|
||||
|
||||
KMP_DEBUG_ASSERT( value != NULL );
|
||||
KMP_INTERNAL_FREE( (void *) * value );
|
||||
* value = NULL;
|
||||
KMP_DEBUG_ASSERT(value != NULL);
|
||||
KMP_INTERNAL_FREE(CCAST(char *, *value));
|
||||
*value = NULL;
|
||||
|
||||
} // func __kmp_env_free
|
||||
|
||||
int __kmp_env_exists(char const *name) {
|
||||
|
||||
|
||||
int
|
||||
__kmp_env_exists( char const * name ) {
|
||||
|
||||
#if KMP_OS_UNIX
|
||||
char const * value = getenv( name );
|
||||
return ( ( value == NULL ) ? ( 0 ) : ( 1 ) );
|
||||
#elif KMP_OS_WINDOWS
|
||||
DWORD rc;
|
||||
rc = GetEnvironmentVariable( name, NULL, 0 );
|
||||
if ( rc == 0 ) {
|
||||
DWORD error = GetLastError();
|
||||
if ( error != ERROR_ENVVAR_NOT_FOUND ) {
|
||||
__kmp_msg(
|
||||
kmp_ms_fatal,
|
||||
KMP_MSG( CantGetEnvVar, name ),
|
||||
KMP_ERR( error ),
|
||||
__kmp_msg_null
|
||||
);
|
||||
}; // if
|
||||
return 0;
|
||||
}; // if
|
||||
return 1;
|
||||
#else
|
||||
#error Unknown or unsupported OS.
|
||||
#endif
|
||||
#if KMP_OS_UNIX
|
||||
char const *value = getenv(name);
|
||||
return ((value == NULL) ? (0) : (1));
|
||||
#elif KMP_OS_WINDOWS
|
||||
DWORD rc;
|
||||
rc = GetEnvironmentVariable(name, NULL, 0);
|
||||
if (rc == 0) {
|
||||
DWORD error = GetLastError();
|
||||
if (error != ERROR_ENVVAR_NOT_FOUND) {
|
||||
__kmp_msg(kmp_ms_fatal, KMP_MSG(CantGetEnvVar, name), KMP_ERR(error),
|
||||
__kmp_msg_null);
|
||||
}; // if
|
||||
return 0;
|
||||
}; // if
|
||||
return 1;
|
||||
#else
|
||||
#error Unknown or unsupported OS.
|
||||
#endif
|
||||
|
||||
} // func __kmp_env_exists
|
||||
|
||||
void __kmp_env_set(char const *name, char const *value, int overwrite) {
|
||||
|
||||
|
||||
void
|
||||
__kmp_env_set( char const * name, char const * value, int overwrite ) {
|
||||
|
||||
#if KMP_OS_UNIX
|
||||
int rc = setenv( name, value, overwrite );
|
||||
if ( rc != 0 ) {
|
||||
// Dead code. I tried to put too many variables into Linux* OS
|
||||
// environment on IA-32 architecture. When application consumes
|
||||
// more than ~2.5 GB of memory, entire system feels bad. Sometimes
|
||||
// application is killed (by OS?), sometimes system stops
|
||||
// responding... But this error message never appears. --ln
|
||||
__kmp_msg(
|
||||
kmp_ms_fatal,
|
||||
KMP_MSG( CantSetEnvVar, name ),
|
||||
KMP_HNT( NotEnoughMemory ),
|
||||
__kmp_msg_null
|
||||
);
|
||||
}; // if
|
||||
#elif KMP_OS_WINDOWS
|
||||
BOOL rc;
|
||||
if ( ! overwrite ) {
|
||||
rc = GetEnvironmentVariable( name, NULL, 0 );
|
||||
if ( rc ) {
|
||||
// Variable exists, do not overwrite.
|
||||
return;
|
||||
}; // if
|
||||
DWORD error = GetLastError();
|
||||
if ( error != ERROR_ENVVAR_NOT_FOUND ) {
|
||||
__kmp_msg(
|
||||
kmp_ms_fatal,
|
||||
KMP_MSG( CantGetEnvVar, name ),
|
||||
KMP_ERR( error ),
|
||||
__kmp_msg_null
|
||||
);
|
||||
}; // if
|
||||
}; // if
|
||||
rc = SetEnvironmentVariable( name, value );
|
||||
if ( ! rc ) {
|
||||
DWORD error = GetLastError();
|
||||
__kmp_msg(
|
||||
kmp_ms_fatal,
|
||||
KMP_MSG( CantSetEnvVar, name ),
|
||||
KMP_ERR( error ),
|
||||
__kmp_msg_null
|
||||
);
|
||||
}; // if
|
||||
#else
|
||||
#error Unknown or unsupported OS.
|
||||
#endif
|
||||
#if KMP_OS_UNIX
|
||||
int rc = setenv(name, value, overwrite);
|
||||
if (rc != 0) {
|
||||
// Dead code. I tried to put too many variables into Linux* OS
|
||||
// environment on IA-32 architecture. When application consumes
|
||||
// more than ~2.5 GB of memory, entire system feels bad. Sometimes
|
||||
// application is killed (by OS?), sometimes system stops
|
||||
// responding... But this error message never appears. --ln
|
||||
__kmp_msg(kmp_ms_fatal, KMP_MSG(CantSetEnvVar, name),
|
||||
KMP_HNT(NotEnoughMemory), __kmp_msg_null);
|
||||
}; // if
|
||||
#elif KMP_OS_WINDOWS
|
||||
BOOL rc;
|
||||
if (!overwrite) {
|
||||
rc = GetEnvironmentVariable(name, NULL, 0);
|
||||
if (rc) {
|
||||
// Variable exists, do not overwrite.
|
||||
return;
|
||||
}; // if
|
||||
DWORD error = GetLastError();
|
||||
if (error != ERROR_ENVVAR_NOT_FOUND) {
|
||||
__kmp_msg(kmp_ms_fatal, KMP_MSG(CantGetEnvVar, name), KMP_ERR(error),
|
||||
__kmp_msg_null);
|
||||
}; // if
|
||||
}; // if
|
||||
rc = SetEnvironmentVariable(name, value);
|
||||
if (!rc) {
|
||||
DWORD error = GetLastError();
|
||||
__kmp_msg(kmp_ms_fatal, KMP_MSG(CantSetEnvVar, name), KMP_ERR(error),
|
||||
__kmp_msg_null);
|
||||
}; // if
|
||||
#else
|
||||
#error Unknown or unsupported OS.
|
||||
#endif
|
||||
|
||||
} // func __kmp_env_set
|
||||
|
||||
void __kmp_env_unset(char const *name) {
|
||||
|
||||
|
||||
void
|
||||
__kmp_env_unset( char const * name ) {
|
||||
|
||||
#if KMP_OS_UNIX
|
||||
unsetenv( name );
|
||||
#elif KMP_OS_WINDOWS
|
||||
BOOL rc = SetEnvironmentVariable( name, NULL );
|
||||
if ( ! rc ) {
|
||||
DWORD error = GetLastError();
|
||||
__kmp_msg(
|
||||
kmp_ms_fatal,
|
||||
KMP_MSG( CantSetEnvVar, name ),
|
||||
KMP_ERR( error ),
|
||||
__kmp_msg_null
|
||||
);
|
||||
}; // if
|
||||
#else
|
||||
#error Unknown or unsupported OS.
|
||||
#endif
|
||||
#if KMP_OS_UNIX
|
||||
unsetenv(name);
|
||||
#elif KMP_OS_WINDOWS
|
||||
BOOL rc = SetEnvironmentVariable(name, NULL);
|
||||
if (!rc) {
|
||||
DWORD error = GetLastError();
|
||||
__kmp_msg(kmp_ms_fatal, KMP_MSG(CantSetEnvVar, name), KMP_ERR(error),
|
||||
__kmp_msg_null);
|
||||
}; // if
|
||||
#else
|
||||
#error Unknown or unsupported OS.
|
||||
#endif
|
||||
|
||||
} // func __kmp_env_unset
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
Intel OpenMP RTL string representation of environment: just a string of characters, variables
|
||||
are separated with vertical bars, e. g.:
|
||||
/* Intel OpenMP RTL string representation of environment: just a string of
|
||||
characters, variables are separated with vertical bars, e. g.:
|
||||
|
||||
"KMP_WARNINGS=0|KMP_AFFINITY=compact|"
|
||||
|
||||
Empty variables are allowed and ignored:
|
||||
|
||||
"||KMP_WARNINGS=1||"
|
||||
|
||||
*/
|
||||
|
||||
static
|
||||
void
|
||||
___kmp_env_blk_parse_string(
|
||||
kmp_env_blk_t * block, // M: Env block to fill.
|
||||
char const * env // I: String to parse.
|
||||
) {
|
||||
static void
|
||||
___kmp_env_blk_parse_string(kmp_env_blk_t *block, // M: Env block to fill.
|
||||
char const *env // I: String to parse.
|
||||
) {
|
||||
|
||||
char const chr_delimiter = '|';
|
||||
char const str_delimiter[] = { chr_delimiter, 0 };
|
||||
char const chr_delimiter = '|';
|
||||
char const str_delimiter[] = {chr_delimiter, 0};
|
||||
|
||||
char * bulk = NULL;
|
||||
kmp_env_var_t * vars = NULL;
|
||||
int count = 0; // Number of used elements in vars array.
|
||||
int delimiters = 0; // Number of delimiters in input string.
|
||||
char *bulk = NULL;
|
||||
kmp_env_var_t *vars = NULL;
|
||||
int count = 0; // Number of used elements in vars array.
|
||||
int delimiters = 0; // Number of delimiters in input string.
|
||||
|
||||
// Copy original string, we will modify the copy.
|
||||
bulk = __kmp_str_format( "%s", env );
|
||||
// Copy original string, we will modify the copy.
|
||||
bulk = __kmp_str_format("%s", env);
|
||||
|
||||
// Loop thru all the vars in environment block. Count delimiters (maximum number of variables
|
||||
// is number of delimiters plus one).
|
||||
{
|
||||
char const * ptr = bulk;
|
||||
for ( ; ; ) {
|
||||
ptr = strchr( ptr, chr_delimiter );
|
||||
if ( ptr == NULL ) {
|
||||
break;
|
||||
}; // if
|
||||
++ delimiters;
|
||||
ptr += 1;
|
||||
}; // forever
|
||||
}
|
||||
// Loop thru all the vars in environment block. Count delimiters (maximum
|
||||
// number of variables is number of delimiters plus one).
|
||||
{
|
||||
char const *ptr = bulk;
|
||||
for (;;) {
|
||||
ptr = strchr(ptr, chr_delimiter);
|
||||
if (ptr == NULL) {
|
||||
break;
|
||||
}; // if
|
||||
++delimiters;
|
||||
ptr += 1;
|
||||
}; // forever
|
||||
}
|
||||
|
||||
// Allocate vars array.
|
||||
vars = (kmp_env_var_t *) allocate( ( delimiters + 1 ) * sizeof( kmp_env_var_t ) );
|
||||
// Allocate vars array.
|
||||
vars = (kmp_env_var_t *)allocate((delimiters + 1) * sizeof(kmp_env_var_t));
|
||||
|
||||
// Loop thru all the variables.
|
||||
{
|
||||
char * var; // Pointer to variable (both name and value).
|
||||
char * name; // Pointer to name of variable.
|
||||
char * value; // Pointer to value.
|
||||
char * buf; // Buffer for __kmp_str_token() function.
|
||||
var = __kmp_str_token( bulk, str_delimiter, & buf ); // Get the first var.
|
||||
while ( var != NULL ) {
|
||||
// Save found variable in vars array.
|
||||
__kmp_str_split( var, '=', & name, & value );
|
||||
KMP_DEBUG_ASSERT( count < delimiters + 1 );
|
||||
vars[ count ].name = name;
|
||||
vars[ count ].value = value;
|
||||
++ count;
|
||||
// Get the next var.
|
||||
var = __kmp_str_token( NULL, str_delimiter, & buf );
|
||||
}; // while
|
||||
}
|
||||
// Loop thru all the variables.
|
||||
{
|
||||
char *var; // Pointer to variable (both name and value).
|
||||
char *name; // Pointer to name of variable.
|
||||
char *value; // Pointer to value.
|
||||
char *buf; // Buffer for __kmp_str_token() function.
|
||||
var = __kmp_str_token(bulk, str_delimiter, &buf); // Get the first var.
|
||||
while (var != NULL) {
|
||||
// Save found variable in vars array.
|
||||
__kmp_str_split(var, '=', &name, &value);
|
||||
KMP_DEBUG_ASSERT(count < delimiters + 1);
|
||||
vars[count].name = name;
|
||||
vars[count].value = value;
|
||||
++count;
|
||||
// Get the next var.
|
||||
var = __kmp_str_token(NULL, str_delimiter, &buf);
|
||||
}; // while
|
||||
}
|
||||
|
||||
// Fill out result.
|
||||
block->bulk = bulk;
|
||||
block->vars = vars;
|
||||
block->count = count;
|
||||
// Fill out result.
|
||||
block->bulk = bulk;
|
||||
block->vars = vars;
|
||||
block->count = count;
|
||||
|
||||
}; // ___kmp_env_blk_parse_string
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Windows* OS (actually, DOS) environment block is a piece of memory with environment variables. Each
|
||||
variable is terminated with zero byte, entire block is terminated with one extra zero byte, so
|
||||
we have two zero bytes at the end of environment block, e. g.:
|
||||
/* Windows* OS (actually, DOS) environment block is a piece of memory with
|
||||
environment variables. Each variable is terminated with zero byte, entire
|
||||
block is terminated with one extra zero byte, so we have two zero bytes at
|
||||
the end of environment block, e. g.:
|
||||
|
||||
"HOME=C:\\users\\lev\x00OS=Windows_NT\x00\x00"
|
||||
|
||||
@@ -369,227 +311,202 @@ ___kmp_env_blk_parse_string(
|
||||
*/
|
||||
|
||||
#if KMP_OS_WINDOWS
|
||||
static
|
||||
void
|
||||
___kmp_env_blk_parse_windows(
|
||||
kmp_env_blk_t * block, // M: Env block to fill.
|
||||
char const * env // I: Pointer to Windows* OS (DOS) environment block.
|
||||
) {
|
||||
static void ___kmp_env_blk_parse_windows(
|
||||
kmp_env_blk_t *block, // M: Env block to fill.
|
||||
char const *env // I: Pointer to Windows* OS (DOS) environment block.
|
||||
) {
|
||||
|
||||
char * bulk = NULL;
|
||||
kmp_env_var_t * vars = NULL;
|
||||
int count = 0; // Number of used elements in vars array.
|
||||
int size = 0; // Size of bulk.
|
||||
char *bulk = NULL;
|
||||
kmp_env_var_t *vars = NULL;
|
||||
int count = 0; // Number of used elements in vars array.
|
||||
int size = 0; // Size of bulk.
|
||||
|
||||
char * name; // Pointer to name of variable.
|
||||
char * value; // Pointer to value.
|
||||
char *name; // Pointer to name of variable.
|
||||
char *value; // Pointer to value.
|
||||
|
||||
if ( env != NULL ) {
|
||||
if (env != NULL) {
|
||||
|
||||
// Loop thru all the vars in environment block. Count variables, find size of block.
|
||||
{
|
||||
char const * var; // Pointer to beginning of var.
|
||||
int len; // Length of variable.
|
||||
count = 0;
|
||||
var = env; // The first variable starts and beginning of environment block.
|
||||
len = KMP_STRLEN( var );
|
||||
while ( len != 0 ) {
|
||||
++ count;
|
||||
size = size + len + 1;
|
||||
var = var + len + 1; // Move pointer to the beginning of the next variable.
|
||||
len = KMP_STRLEN( var );
|
||||
}; // while
|
||||
size = size + 1; // Total size of env block, including terminating zero byte.
|
||||
}
|
||||
// Loop thru all the vars in environment block. Count variables, find size
|
||||
// of block.
|
||||
{
|
||||
char const *var; // Pointer to beginning of var.
|
||||
int len; // Length of variable.
|
||||
count = 0;
|
||||
var =
|
||||
env; // The first variable starts and beginning of environment block.
|
||||
len = KMP_STRLEN(var);
|
||||
while (len != 0) {
|
||||
++count;
|
||||
size = size + len + 1;
|
||||
var = var + len +
|
||||
1; // Move pointer to the beginning of the next variable.
|
||||
len = KMP_STRLEN(var);
|
||||
}; // while
|
||||
size =
|
||||
size + 1; // Total size of env block, including terminating zero byte.
|
||||
}
|
||||
|
||||
// Copy original block to bulk, we will modify bulk, not original block.
|
||||
bulk = (char *) allocate( size );
|
||||
KMP_MEMCPY_S( bulk, size, env, size );
|
||||
// Allocate vars array.
|
||||
vars = (kmp_env_var_t *) allocate( count * sizeof( kmp_env_var_t ) );
|
||||
// Copy original block to bulk, we will modify bulk, not original block.
|
||||
bulk = (char *)allocate(size);
|
||||
KMP_MEMCPY_S(bulk, size, env, size);
|
||||
// Allocate vars array.
|
||||
vars = (kmp_env_var_t *)allocate(count * sizeof(kmp_env_var_t));
|
||||
|
||||
// Loop thru all the vars, now in bulk.
|
||||
{
|
||||
char * var; // Pointer to beginning of var.
|
||||
int len; // Length of variable.
|
||||
count = 0;
|
||||
var = bulk;
|
||||
len = KMP_STRLEN( var );
|
||||
while ( len != 0 ) {
|
||||
// Save variable in vars array.
|
||||
__kmp_str_split( var, '=', & name, & value );
|
||||
vars[ count ].name = name;
|
||||
vars[ count ].value = value;
|
||||
++ count;
|
||||
// Get the next var.
|
||||
var = var + len + 1;
|
||||
len = KMP_STRLEN( var );
|
||||
}; // while
|
||||
}
|
||||
// Loop thru all the vars, now in bulk.
|
||||
{
|
||||
char *var; // Pointer to beginning of var.
|
||||
int len; // Length of variable.
|
||||
count = 0;
|
||||
var = bulk;
|
||||
len = KMP_STRLEN(var);
|
||||
while (len != 0) {
|
||||
// Save variable in vars array.
|
||||
__kmp_str_split(var, '=', &name, &value);
|
||||
vars[count].name = name;
|
||||
vars[count].value = value;
|
||||
++count;
|
||||
// Get the next var.
|
||||
var = var + len + 1;
|
||||
len = KMP_STRLEN(var);
|
||||
}; // while
|
||||
}
|
||||
|
||||
}; // if
|
||||
}; // if
|
||||
|
||||
// Fill out result.
|
||||
block->bulk = bulk;
|
||||
block->vars = vars;
|
||||
block->count = count;
|
||||
// Fill out result.
|
||||
block->bulk = bulk;
|
||||
block->vars = vars;
|
||||
block->count = count;
|
||||
|
||||
}; // ___kmp_env_blk_parse_windows
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
Unix environment block is a array of pointers to variables, last pointer in array is NULL:
|
||||
/* Unix environment block is a array of pointers to variables, last pointer in
|
||||
array is NULL:
|
||||
|
||||
{ "HOME=/home/lev", "TERM=xterm", NULL }
|
||||
*/
|
||||
|
||||
static
|
||||
void
|
||||
___kmp_env_blk_parse_unix(
|
||||
kmp_env_blk_t * block, // M: Env block to fill.
|
||||
char * * env // I: Unix environment to parse.
|
||||
) {
|
||||
static void
|
||||
___kmp_env_blk_parse_unix(kmp_env_blk_t *block, // M: Env block to fill.
|
||||
char **env // I: Unix environment to parse.
|
||||
) {
|
||||
|
||||
char * bulk = NULL;
|
||||
kmp_env_var_t * vars = NULL;
|
||||
int count = 0;
|
||||
int size = 0; // Size of bulk.
|
||||
char *bulk = NULL;
|
||||
kmp_env_var_t *vars = NULL;
|
||||
int count = 0;
|
||||
int size = 0; // Size of bulk.
|
||||
|
||||
// Count number of variables and length of required bulk.
|
||||
{
|
||||
count = 0;
|
||||
size = 0;
|
||||
while ( env[ count ] != NULL ) {
|
||||
size += KMP_STRLEN( env[ count ] ) + 1;
|
||||
++ count;
|
||||
}; // while
|
||||
}
|
||||
// Count number of variables and length of required bulk.
|
||||
{
|
||||
count = 0;
|
||||
size = 0;
|
||||
while (env[count] != NULL) {
|
||||
size += KMP_STRLEN(env[count]) + 1;
|
||||
++count;
|
||||
}; // while
|
||||
}
|
||||
|
||||
// Allocate memory.
|
||||
bulk = (char *) allocate( size );
|
||||
vars = (kmp_env_var_t *) allocate( count * sizeof( kmp_env_var_t ) );
|
||||
// Allocate memory.
|
||||
bulk = (char *)allocate(size);
|
||||
vars = (kmp_env_var_t *)allocate(count * sizeof(kmp_env_var_t));
|
||||
|
||||
// Loop thru all the vars.
|
||||
{
|
||||
char * var; // Pointer to beginning of var.
|
||||
char * name; // Pointer to name of variable.
|
||||
char * value; // Pointer to value.
|
||||
int len; // Length of variable.
|
||||
int i;
|
||||
var = bulk;
|
||||
for ( i = 0; i < count; ++ i ) {
|
||||
// Copy variable to bulk.
|
||||
len = KMP_STRLEN( env[ i ] );
|
||||
KMP_MEMCPY_S( var, size, env[ i ], len + 1 );
|
||||
// Save found variable in vars array.
|
||||
__kmp_str_split( var, '=', & name, & value );
|
||||
vars[ i ].name = name;
|
||||
vars[ i ].value = value;
|
||||
// Move pointer.
|
||||
var += len + 1;
|
||||
}; // for
|
||||
}
|
||||
// Loop thru all the vars.
|
||||
{
|
||||
char *var; // Pointer to beginning of var.
|
||||
char *name; // Pointer to name of variable.
|
||||
char *value; // Pointer to value.
|
||||
int len; // Length of variable.
|
||||
int i;
|
||||
var = bulk;
|
||||
for (i = 0; i < count; ++i) {
|
||||
// Copy variable to bulk.
|
||||
len = KMP_STRLEN(env[i]);
|
||||
KMP_MEMCPY_S(var, size, env[i], len + 1);
|
||||
// Save found variable in vars array.
|
||||
__kmp_str_split(var, '=', &name, &value);
|
||||
vars[i].name = name;
|
||||
vars[i].value = value;
|
||||
// Move pointer.
|
||||
var += len + 1;
|
||||
}; // for
|
||||
}
|
||||
|
||||
// Fill out result.
|
||||
block->bulk = bulk;
|
||||
block->vars = vars;
|
||||
block->count = count;
|
||||
// Fill out result.
|
||||
block->bulk = bulk;
|
||||
block->vars = vars;
|
||||
block->count = count;
|
||||
|
||||
}; // ___kmp_env_blk_parse_unix
|
||||
|
||||
void __kmp_env_blk_init(kmp_env_blk_t *block, // M: Block to initialize.
|
||||
char const *bulk // I: Initialization string, or NULL.
|
||||
) {
|
||||
|
||||
|
||||
void
|
||||
__kmp_env_blk_init(
|
||||
kmp_env_blk_t * block, // M: Block to initialize.
|
||||
char const * bulk // I: Initialization string, or NULL.
|
||||
) {
|
||||
|
||||
if ( bulk != NULL ) {
|
||||
___kmp_env_blk_parse_string( block, bulk );
|
||||
} else {
|
||||
#if KMP_OS_UNIX
|
||||
___kmp_env_blk_parse_unix( block, environ );
|
||||
#elif KMP_OS_WINDOWS
|
||||
{
|
||||
char * mem = GetEnvironmentStrings();
|
||||
if ( mem == NULL ) {
|
||||
DWORD error = GetLastError();
|
||||
__kmp_msg(
|
||||
kmp_ms_fatal,
|
||||
KMP_MSG( CantGetEnvironment ),
|
||||
KMP_ERR( error ),
|
||||
__kmp_msg_null
|
||||
);
|
||||
}; // if
|
||||
___kmp_env_blk_parse_windows( block, mem );
|
||||
FreeEnvironmentStrings( mem );
|
||||
}
|
||||
#else
|
||||
#error Unknown or unsupported OS.
|
||||
#endif
|
||||
}; // if
|
||||
if (bulk != NULL) {
|
||||
___kmp_env_blk_parse_string(block, bulk);
|
||||
} else {
|
||||
#if KMP_OS_UNIX
|
||||
___kmp_env_blk_parse_unix(block, environ);
|
||||
#elif KMP_OS_WINDOWS
|
||||
{
|
||||
char *mem = GetEnvironmentStrings();
|
||||
if (mem == NULL) {
|
||||
DWORD error = GetLastError();
|
||||
__kmp_msg(kmp_ms_fatal, KMP_MSG(CantGetEnvironment), KMP_ERR(error),
|
||||
__kmp_msg_null);
|
||||
}; // if
|
||||
___kmp_env_blk_parse_windows(block, mem);
|
||||
FreeEnvironmentStrings(mem);
|
||||
}
|
||||
#else
|
||||
#error Unknown or unsupported OS.
|
||||
#endif
|
||||
}; // if
|
||||
|
||||
} // __kmp_env_blk_init
|
||||
|
||||
|
||||
|
||||
static
|
||||
int
|
||||
___kmp_env_var_cmp( // Comparison function for qsort().
|
||||
kmp_env_var_t const * lhs,
|
||||
kmp_env_var_t const * rhs
|
||||
) {
|
||||
return strcmp( lhs->name, rhs->name );
|
||||
static int ___kmp_env_var_cmp( // Comparison function for qsort().
|
||||
kmp_env_var_t const *lhs, kmp_env_var_t const *rhs) {
|
||||
return strcmp(lhs->name, rhs->name);
|
||||
}
|
||||
|
||||
void
|
||||
__kmp_env_blk_sort(
|
||||
kmp_env_blk_t * block // M: Block of environment variables to sort.
|
||||
) {
|
||||
void __kmp_env_blk_sort(
|
||||
kmp_env_blk_t *block // M: Block of environment variables to sort.
|
||||
) {
|
||||
|
||||
qsort(
|
||||
(void *) block->vars,
|
||||
block->count,
|
||||
sizeof( kmp_env_var_t ),
|
||||
( int ( * )( void const *, void const * ) ) & ___kmp_env_var_cmp
|
||||
);
|
||||
qsort(CCAST(kmp_env_var_t *, block->vars), block->count,
|
||||
sizeof(kmp_env_var_t),
|
||||
(int (*)(void const *, void const *)) & ___kmp_env_var_cmp);
|
||||
|
||||
} // __kmp_env_block_sort
|
||||
|
||||
void __kmp_env_blk_free(
|
||||
kmp_env_blk_t *block // M: Block of environment variables to free.
|
||||
) {
|
||||
|
||||
KMP_INTERNAL_FREE(CCAST(kmp_env_var_t *, block->vars));
|
||||
__kmp_str_free(&(block->bulk));
|
||||
|
||||
void
|
||||
__kmp_env_blk_free(
|
||||
kmp_env_blk_t * block // M: Block of environment variables to free.
|
||||
) {
|
||||
|
||||
KMP_INTERNAL_FREE( (void *) block->vars );
|
||||
__kmp_str_free(&(block->bulk));
|
||||
|
||||
block->count = 0;
|
||||
block->vars = NULL;
|
||||
block->count = 0;
|
||||
block->vars = NULL;
|
||||
|
||||
} // __kmp_env_blk_free
|
||||
|
||||
char const * // R: Value of variable or NULL if variable does not exist.
|
||||
__kmp_env_blk_var(
|
||||
kmp_env_blk_t *block, // I: Block of environment variables.
|
||||
char const *name // I: Name of variable to find.
|
||||
) {
|
||||
|
||||
|
||||
char const * // R: Value of variable or NULL if variable does not exist.
|
||||
__kmp_env_blk_var(
|
||||
kmp_env_blk_t * block, // I: Block of environment variables.
|
||||
char const * name // I: Name of variable to find.
|
||||
) {
|
||||
|
||||
int i;
|
||||
for ( i = 0; i < block->count; ++ i ) {
|
||||
if ( strcmp( block->vars[ i ].name, name ) == 0 ) {
|
||||
return block->vars[ i ].value;
|
||||
}; // if
|
||||
}; // for
|
||||
return NULL;
|
||||
int i;
|
||||
for (i = 0; i < block->count; ++i) {
|
||||
if (strcmp(block->vars[i].name, name) == 0) {
|
||||
return block->vars[i].value;
|
||||
}; // if
|
||||
}; // for
|
||||
return NULL;
|
||||
|
||||
} // __kmp_env_block_var
|
||||
|
||||
|
||||
// end of file //
|
||||
|
||||
@@ -20,56 +20,56 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Return a copy of the value of environment variable or NULL if the variable does not exist.
|
||||
// Return a copy of the value of environment variable or NULL if the variable
|
||||
// does not exist.
|
||||
// *Note*: Returned pointed *must* be freed after use with __kmp_env_free().
|
||||
char * __kmp_env_get( char const * name );
|
||||
void __kmp_env_free( char const * * value );
|
||||
char *__kmp_env_get(char const *name);
|
||||
void __kmp_env_free(char const **value);
|
||||
|
||||
// Return 1 if the environment variable exists or 0 if does not exist.
|
||||
int __kmp_env_exists( char const * name );
|
||||
int __kmp_env_exists(char const *name);
|
||||
|
||||
// Set the environment variable.
|
||||
void __kmp_env_set( char const * name, char const * value, int overwrite );
|
||||
void __kmp_env_set(char const *name, char const *value, int overwrite);
|
||||
|
||||
// Unset (remove) environment variable.
|
||||
void __kmp_env_unset( char const * name );
|
||||
void __kmp_env_unset(char const *name);
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------------
|
||||
// Working with environment blocks.
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
kmp_env_blk_t is read-only collection of environment variables (or environment-like). Usage:
|
||||
/* kmp_env_blk_t is read-only collection of environment variables (or
|
||||
environment-like). Usage:
|
||||
|
||||
kmp_env_blk_t block;
|
||||
__kmp_env_blk_init( & block, NULL ); // Initialize block from process environment.
|
||||
// or
|
||||
__kmp_env_blk_init( & block, "KMP_WARNING=1|KMP_AFFINITY=none" ); // from string.
|
||||
__kmp_env_blk_sort( & block ); // Optionally, sort list.
|
||||
for ( i = 0; i < block.count; ++ i ) {
|
||||
// Process block.vars[ i ].name and block.vars[ i ].value...
|
||||
}; // for i
|
||||
__kmp_env_block_free( & block );
|
||||
kmp_env_blk_t block;
|
||||
__kmp_env_blk_init( & block, NULL ); // Initialize block from process
|
||||
// environment.
|
||||
// or
|
||||
__kmp_env_blk_init( & block, "KMP_WARNING=1|KMP_AFFINITY=none" ); // from string
|
||||
__kmp_env_blk_sort( & block ); // Optionally, sort list.
|
||||
for ( i = 0; i < block.count; ++ i ) {
|
||||
// Process block.vars[ i ].name and block.vars[ i ].value...
|
||||
}; // for i
|
||||
__kmp_env_block_free( & block );
|
||||
*/
|
||||
|
||||
struct __kmp_env_var {
|
||||
char const * name;
|
||||
char const * value;
|
||||
char const *name;
|
||||
char const *value;
|
||||
};
|
||||
typedef struct __kmp_env_var kmp_env_var_t;
|
||||
|
||||
struct __kmp_env_blk {
|
||||
char const * bulk;
|
||||
kmp_env_var_t const * vars;
|
||||
int count;
|
||||
char const *bulk;
|
||||
kmp_env_var_t const *vars;
|
||||
int count;
|
||||
};
|
||||
typedef struct __kmp_env_blk kmp_env_blk_t;
|
||||
|
||||
void __kmp_env_blk_init( kmp_env_blk_t * block, char const * bulk );
|
||||
void __kmp_env_blk_free( kmp_env_blk_t * block );
|
||||
void __kmp_env_blk_sort( kmp_env_blk_t * block );
|
||||
char const * __kmp_env_blk_var( kmp_env_blk_t * block, char const * name );
|
||||
void __kmp_env_blk_init(kmp_env_blk_t *block, char const *bulk);
|
||||
void __kmp_env_blk_free(kmp_env_blk_t *block);
|
||||
void __kmp_env_blk_sort(kmp_env_blk_t *block);
|
||||
char const *__kmp_env_blk_var(kmp_env_blk_t *block, char const *name);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
@@ -78,4 +78,3 @@ char const * __kmp_env_blk_var( kmp_env_blk_t * block, char const * name );
|
||||
#endif // KMP_ENVIRONMENT_H
|
||||
|
||||
// end of file //
|
||||
|
||||
|
||||
+357
-415
@@ -14,259 +14,237 @@
|
||||
|
||||
|
||||
#include "kmp.h"
|
||||
#include "kmp_error.h"
|
||||
#include "kmp_i18n.h"
|
||||
#include "kmp_str.h"
|
||||
#include "kmp_error.h"
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
#define MIN_STACK 100
|
||||
#define MIN_STACK 100
|
||||
|
||||
|
||||
static char const * cons_text_c[] = {
|
||||
"(none)",
|
||||
"\"parallel\"",
|
||||
"work-sharing", /* this is not called "for" because of lowering of "sections" pragmas */
|
||||
"\"ordered\" work-sharing", /* this is not called "for ordered" because of lowering of "sections" pragmas */
|
||||
static char const *cons_text_c[] = {
|
||||
"(none)", "\"parallel\"", "work-sharing", /* this is not called "for"
|
||||
because of lowering of
|
||||
"sections" pragmas */
|
||||
"\"ordered\" work-sharing", /* this is not called "for ordered" because of
|
||||
lowering of "sections" pragmas */
|
||||
"\"sections\"",
|
||||
"work-sharing", /* this is not called "single" because of lowering of "sections" pragmas */
|
||||
"\"taskq\"",
|
||||
"\"taskq\"",
|
||||
"\"taskq ordered\"",
|
||||
"\"critical\"",
|
||||
"\"ordered\"", /* in PARALLEL */
|
||||
"\"ordered\"", /* in PDO */
|
||||
"\"ordered\"", /* in TASKQ */
|
||||
"\"master\"",
|
||||
"\"reduce\"",
|
||||
"\"barrier\""
|
||||
};
|
||||
"work-sharing", /* this is not called "single" because of lowering of
|
||||
"sections" pragmas */
|
||||
"\"taskq\"", "\"taskq\"", "\"taskq ordered\"", "\"critical\"",
|
||||
"\"ordered\"", /* in PARALLEL */
|
||||
"\"ordered\"", /* in PDO */
|
||||
"\"ordered\"", /* in TASKQ */
|
||||
"\"master\"", "\"reduce\"", "\"barrier\""};
|
||||
|
||||
#define get_src( ident ) ( (ident) == NULL ? NULL : (ident)->psource )
|
||||
#define get_src(ident) ((ident) == NULL ? NULL : (ident)->psource)
|
||||
|
||||
#define PUSH_MSG( ct, ident ) \
|
||||
"\tpushing on stack: %s (%s)\n", cons_text_c[ (ct) ], get_src( (ident) )
|
||||
#define POP_MSG( p ) \
|
||||
"\tpopping off stack: %s (%s)\n", \
|
||||
cons_text_c[ (p)->stack_data[ tos ].type ], \
|
||||
get_src( (p)->stack_data[ tos ].ident )
|
||||
#define PUSH_MSG(ct, ident) \
|
||||
"\tpushing on stack: %s (%s)\n", cons_text_c[(ct)], get_src((ident))
|
||||
#define POP_MSG(p) \
|
||||
"\tpopping off stack: %s (%s)\n", cons_text_c[(p)->stack_data[tos].type], \
|
||||
get_src((p)->stack_data[tos].ident)
|
||||
|
||||
static int const cons_text_c_num = sizeof( cons_text_c ) / sizeof( char const * );
|
||||
static int const cons_text_c_num = sizeof(cons_text_c) / sizeof(char const *);
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* --------------- START OF STATIC LOCAL ROUTINES ------------------------- */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
static void
|
||||
__kmp_check_null_func( void )
|
||||
{
|
||||
/* nothing to do */
|
||||
static void __kmp_check_null_func(void) { /* nothing to do */
|
||||
}
|
||||
|
||||
static void
|
||||
__kmp_expand_cons_stack( int gtid, struct cons_header *p )
|
||||
{
|
||||
int i;
|
||||
struct cons_data *d;
|
||||
static void __kmp_expand_cons_stack(int gtid, struct cons_header *p) {
|
||||
int i;
|
||||
struct cons_data *d;
|
||||
|
||||
/* TODO for monitor perhaps? */
|
||||
if (gtid < 0)
|
||||
__kmp_check_null_func();
|
||||
/* TODO for monitor perhaps? */
|
||||
if (gtid < 0)
|
||||
__kmp_check_null_func();
|
||||
|
||||
KE_TRACE( 10, ("expand cons_stack (%d %d)\n", gtid, __kmp_get_gtid() ) );
|
||||
KE_TRACE(10, ("expand cons_stack (%d %d)\n", gtid, __kmp_get_gtid()));
|
||||
|
||||
d = p->stack_data;
|
||||
d = p->stack_data;
|
||||
|
||||
p->stack_size = (p->stack_size * 2) + 100;
|
||||
p->stack_size = (p->stack_size * 2) + 100;
|
||||
|
||||
/* TODO free the old data */
|
||||
p->stack_data = (struct cons_data *) __kmp_allocate( sizeof( struct cons_data ) * (p->stack_size+1) );
|
||||
/* TODO free the old data */
|
||||
p->stack_data = (struct cons_data *)__kmp_allocate(sizeof(struct cons_data) *
|
||||
(p->stack_size + 1));
|
||||
|
||||
for (i = p->stack_top; i >= 0; --i)
|
||||
p->stack_data[i] = d[i];
|
||||
for (i = p->stack_top; i >= 0; --i)
|
||||
p->stack_data[i] = d[i];
|
||||
|
||||
/* NOTE: we do not free the old stack_data */
|
||||
/* NOTE: we do not free the old stack_data */
|
||||
}
|
||||
|
||||
// NOTE: Function returns allocated memory, caller must free it!
|
||||
static char const *
|
||||
__kmp_pragma(
|
||||
int ct,
|
||||
ident_t const * ident
|
||||
) {
|
||||
char const * cons = NULL; // Construct name.
|
||||
char * file = NULL; // File name.
|
||||
char * func = NULL; // Function (routine) name.
|
||||
char * line = NULL; // Line number.
|
||||
kmp_str_buf_t buffer;
|
||||
kmp_msg_t prgm;
|
||||
__kmp_str_buf_init( & buffer );
|
||||
if ( 0 < ct && ct < cons_text_c_num ) {
|
||||
cons = cons_text_c[ ct ];
|
||||
} else {
|
||||
KMP_DEBUG_ASSERT( 0 );
|
||||
};
|
||||
if ( ident != NULL && ident->psource != NULL ) {
|
||||
char * tail = NULL;
|
||||
__kmp_str_buf_print( & buffer, "%s", ident->psource ); // Copy source to buffer.
|
||||
// Split string in buffer to file, func, and line.
|
||||
tail = buffer.str;
|
||||
__kmp_str_split( tail, ';', NULL, & tail );
|
||||
__kmp_str_split( tail, ';', & file, & tail );
|
||||
__kmp_str_split( tail, ';', & func, & tail );
|
||||
__kmp_str_split( tail, ';', & line, & tail );
|
||||
}; // if
|
||||
prgm = __kmp_msg_format( kmp_i18n_fmt_Pragma, cons, file, func, line );
|
||||
__kmp_str_buf_free( & buffer );
|
||||
return prgm.str;
|
||||
static char const *__kmp_pragma(int ct, ident_t const *ident) {
|
||||
char const *cons = NULL; // Construct name.
|
||||
char *file = NULL; // File name.
|
||||
char *func = NULL; // Function (routine) name.
|
||||
char *line = NULL; // Line number.
|
||||
kmp_str_buf_t buffer;
|
||||
kmp_msg_t prgm;
|
||||
__kmp_str_buf_init(&buffer);
|
||||
if (0 < ct && ct < cons_text_c_num) {
|
||||
cons = cons_text_c[ct];
|
||||
} else {
|
||||
KMP_DEBUG_ASSERT(0);
|
||||
};
|
||||
if (ident != NULL && ident->psource != NULL) {
|
||||
char *tail = NULL;
|
||||
__kmp_str_buf_print(&buffer, "%s",
|
||||
ident->psource); // Copy source to buffer.
|
||||
// Split string in buffer to file, func, and line.
|
||||
tail = buffer.str;
|
||||
__kmp_str_split(tail, ';', NULL, &tail);
|
||||
__kmp_str_split(tail, ';', &file, &tail);
|
||||
__kmp_str_split(tail, ';', &func, &tail);
|
||||
__kmp_str_split(tail, ';', &line, &tail);
|
||||
}; // if
|
||||
prgm = __kmp_msg_format(kmp_i18n_fmt_Pragma, cons, file, func, line);
|
||||
__kmp_str_buf_free(&buffer);
|
||||
return prgm.str;
|
||||
} // __kmp_pragma
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ----------------- END OF STATIC LOCAL ROUTINES ------------------------- */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
|
||||
void
|
||||
__kmp_error_construct(
|
||||
kmp_i18n_id_t id, // Message identifier.
|
||||
enum cons_type ct, // Construct type.
|
||||
ident_t const * ident // Construct ident.
|
||||
) {
|
||||
char const * construct = __kmp_pragma( ct, ident );
|
||||
__kmp_msg( kmp_ms_fatal, __kmp_msg_format( id, construct ), __kmp_msg_null );
|
||||
KMP_INTERNAL_FREE( (void *) construct );
|
||||
void __kmp_error_construct(kmp_i18n_id_t id, // Message identifier.
|
||||
enum cons_type ct, // Construct type.
|
||||
ident_t const *ident // Construct ident.
|
||||
) {
|
||||
char const *construct = __kmp_pragma(ct, ident);
|
||||
__kmp_msg(kmp_ms_fatal, __kmp_msg_format(id, construct), __kmp_msg_null);
|
||||
KMP_INTERNAL_FREE(CCAST(char *, construct));
|
||||
}
|
||||
|
||||
void
|
||||
__kmp_error_construct2(
|
||||
kmp_i18n_id_t id, // Message identifier.
|
||||
enum cons_type ct, // First construct type.
|
||||
ident_t const * ident, // First construct ident.
|
||||
struct cons_data const * cons // Second construct.
|
||||
) {
|
||||
char const * construct1 = __kmp_pragma( ct, ident );
|
||||
char const * construct2 = __kmp_pragma( cons->type, cons->ident );
|
||||
__kmp_msg( kmp_ms_fatal, __kmp_msg_format( id, construct1, construct2 ), __kmp_msg_null );
|
||||
KMP_INTERNAL_FREE( (void *) construct1 );
|
||||
KMP_INTERNAL_FREE( (void *) construct2 );
|
||||
void __kmp_error_construct2(kmp_i18n_id_t id, // Message identifier.
|
||||
enum cons_type ct, // First construct type.
|
||||
ident_t const *ident, // First construct ident.
|
||||
struct cons_data const *cons // Second construct.
|
||||
) {
|
||||
char const *construct1 = __kmp_pragma(ct, ident);
|
||||
char const *construct2 = __kmp_pragma(cons->type, cons->ident);
|
||||
__kmp_msg(kmp_ms_fatal, __kmp_msg_format(id, construct1, construct2),
|
||||
__kmp_msg_null);
|
||||
KMP_INTERNAL_FREE(CCAST(char *, construct1));
|
||||
KMP_INTERNAL_FREE(CCAST(char *, construct2));
|
||||
}
|
||||
|
||||
struct cons_header *__kmp_allocate_cons_stack(int gtid) {
|
||||
struct cons_header *p;
|
||||
|
||||
struct cons_header *
|
||||
__kmp_allocate_cons_stack( int gtid )
|
||||
{
|
||||
struct cons_header *p;
|
||||
/* TODO for monitor perhaps? */
|
||||
if (gtid < 0) {
|
||||
__kmp_check_null_func();
|
||||
}; // if
|
||||
KE_TRACE(10, ("allocate cons_stack (%d)\n", gtid));
|
||||
p = (struct cons_header *)__kmp_allocate(sizeof(struct cons_header));
|
||||
p->p_top = p->w_top = p->s_top = 0;
|
||||
p->stack_data = (struct cons_data *)__kmp_allocate(sizeof(struct cons_data) *
|
||||
(MIN_STACK + 1));
|
||||
p->stack_size = MIN_STACK;
|
||||
p->stack_top = 0;
|
||||
p->stack_data[0].type = ct_none;
|
||||
p->stack_data[0].prev = 0;
|
||||
p->stack_data[0].ident = NULL;
|
||||
return p;
|
||||
}
|
||||
|
||||
/* TODO for monitor perhaps? */
|
||||
if ( gtid < 0 ) {
|
||||
__kmp_check_null_func();
|
||||
void __kmp_free_cons_stack(void *ptr) {
|
||||
struct cons_header *p = (struct cons_header *)ptr;
|
||||
if (p != NULL) {
|
||||
if (p->stack_data != NULL) {
|
||||
__kmp_free(p->stack_data);
|
||||
p->stack_data = NULL;
|
||||
}; // if
|
||||
KE_TRACE( 10, ("allocate cons_stack (%d)\n", gtid ) );
|
||||
p = (struct cons_header *) __kmp_allocate( sizeof( struct cons_header ) );
|
||||
p->p_top = p->w_top = p->s_top = 0;
|
||||
p->stack_data = (struct cons_data *) __kmp_allocate( sizeof( struct cons_data ) * (MIN_STACK+1) );
|
||||
p->stack_size = MIN_STACK;
|
||||
p->stack_top = 0;
|
||||
p->stack_data[ 0 ].type = ct_none;
|
||||
p->stack_data[ 0 ].prev = 0;
|
||||
p->stack_data[ 0 ].ident = NULL;
|
||||
return p;
|
||||
__kmp_free(p);
|
||||
}; // if
|
||||
}
|
||||
|
||||
void
|
||||
__kmp_free_cons_stack( void * ptr ) {
|
||||
struct cons_header * p = (struct cons_header *) ptr;
|
||||
if ( p != NULL ) {
|
||||
if ( p->stack_data != NULL ) {
|
||||
__kmp_free( p->stack_data );
|
||||
p->stack_data = NULL;
|
||||
}; // if
|
||||
__kmp_free( p );
|
||||
}; // if
|
||||
}
|
||||
|
||||
|
||||
#if KMP_DEBUG
|
||||
static void
|
||||
dump_cons_stack( int gtid, struct cons_header * p ) {
|
||||
int i;
|
||||
int tos = p->stack_top;
|
||||
kmp_str_buf_t buffer;
|
||||
__kmp_str_buf_init( & buffer );
|
||||
__kmp_str_buf_print( & buffer, "+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-\n" );
|
||||
__kmp_str_buf_print( & buffer, "Begin construct stack with %d items for thread %d\n", tos, gtid );
|
||||
__kmp_str_buf_print( & buffer, " stack_top=%d { P=%d, W=%d, S=%d }\n", tos, p->p_top, p->w_top, p->s_top );
|
||||
for ( i = tos; i > 0; i-- ) {
|
||||
struct cons_data * c = & ( p->stack_data[ i ] );
|
||||
__kmp_str_buf_print( & buffer, " stack_data[%2d] = { %s (%s) %d %p }\n", i, cons_text_c[ c->type ], get_src( c->ident ), c->prev, c->name );
|
||||
}; // for i
|
||||
__kmp_str_buf_print( & buffer, "End construct stack for thread %d\n", gtid );
|
||||
__kmp_str_buf_print( & buffer, "+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-\n" );
|
||||
__kmp_debug_printf( "%s", buffer.str );
|
||||
__kmp_str_buf_free( & buffer );
|
||||
static void dump_cons_stack(int gtid, struct cons_header *p) {
|
||||
int i;
|
||||
int tos = p->stack_top;
|
||||
kmp_str_buf_t buffer;
|
||||
__kmp_str_buf_init(&buffer);
|
||||
__kmp_str_buf_print(
|
||||
&buffer,
|
||||
"+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-\n");
|
||||
__kmp_str_buf_print(&buffer,
|
||||
"Begin construct stack with %d items for thread %d\n",
|
||||
tos, gtid);
|
||||
__kmp_str_buf_print(&buffer, " stack_top=%d { P=%d, W=%d, S=%d }\n", tos,
|
||||
p->p_top, p->w_top, p->s_top);
|
||||
for (i = tos; i > 0; i--) {
|
||||
struct cons_data *c = &(p->stack_data[i]);
|
||||
__kmp_str_buf_print(
|
||||
&buffer, " stack_data[%2d] = { %s (%s) %d %p }\n", i,
|
||||
cons_text_c[c->type], get_src(c->ident), c->prev, c->name);
|
||||
}; // for i
|
||||
__kmp_str_buf_print(&buffer, "End construct stack for thread %d\n", gtid);
|
||||
__kmp_str_buf_print(
|
||||
&buffer,
|
||||
"+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-\n");
|
||||
__kmp_debug_printf("%s", buffer.str);
|
||||
__kmp_str_buf_free(&buffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
__kmp_push_parallel( int gtid, ident_t const * ident )
|
||||
{
|
||||
int tos;
|
||||
struct cons_header *p = __kmp_threads[ gtid ]->th.th_cons;
|
||||
void __kmp_push_parallel(int gtid, ident_t const *ident) {
|
||||
int tos;
|
||||
struct cons_header *p = __kmp_threads[gtid]->th.th_cons;
|
||||
|
||||
KMP_DEBUG_ASSERT( __kmp_threads[ gtid ]-> th.th_cons );
|
||||
KE_TRACE( 10, ("__kmp_push_parallel (%d %d)\n", gtid, __kmp_get_gtid() ) );
|
||||
KE_TRACE( 100, ( PUSH_MSG( ct_parallel, ident ) ) );
|
||||
if ( p->stack_top >= p->stack_size ) {
|
||||
__kmp_expand_cons_stack( gtid, p );
|
||||
}; // if
|
||||
tos = ++p->stack_top;
|
||||
p->stack_data[ tos ].type = ct_parallel;
|
||||
p->stack_data[ tos ].prev = p->p_top;
|
||||
p->stack_data[ tos ].ident = ident;
|
||||
p->stack_data[ tos ].name = NULL;
|
||||
p->p_top = tos;
|
||||
KE_DUMP( 1000, dump_cons_stack( gtid, p ) );
|
||||
KMP_DEBUG_ASSERT(__kmp_threads[gtid]->th.th_cons);
|
||||
KE_TRACE(10, ("__kmp_push_parallel (%d %d)\n", gtid, __kmp_get_gtid()));
|
||||
KE_TRACE(100, (PUSH_MSG(ct_parallel, ident)));
|
||||
if (p->stack_top >= p->stack_size) {
|
||||
__kmp_expand_cons_stack(gtid, p);
|
||||
}; // if
|
||||
tos = ++p->stack_top;
|
||||
p->stack_data[tos].type = ct_parallel;
|
||||
p->stack_data[tos].prev = p->p_top;
|
||||
p->stack_data[tos].ident = ident;
|
||||
p->stack_data[tos].name = NULL;
|
||||
p->p_top = tos;
|
||||
KE_DUMP(1000, dump_cons_stack(gtid, p));
|
||||
}
|
||||
|
||||
void
|
||||
__kmp_check_workshare( int gtid, enum cons_type ct, ident_t const * ident )
|
||||
{
|
||||
struct cons_header *p = __kmp_threads[ gtid ]->th.th_cons;
|
||||
void __kmp_check_workshare(int gtid, enum cons_type ct, ident_t const *ident) {
|
||||
struct cons_header *p = __kmp_threads[gtid]->th.th_cons;
|
||||
|
||||
KMP_DEBUG_ASSERT( __kmp_threads[ gtid ]-> th.th_cons );
|
||||
KE_TRACE( 10, ("__kmp_check_workshare (%d %d)\n", gtid, __kmp_get_gtid() ) );
|
||||
KMP_DEBUG_ASSERT(__kmp_threads[gtid]->th.th_cons);
|
||||
KE_TRACE(10, ("__kmp_check_workshare (%d %d)\n", gtid, __kmp_get_gtid()));
|
||||
|
||||
|
||||
if ( p->stack_top >= p->stack_size ) {
|
||||
__kmp_expand_cons_stack( gtid, p );
|
||||
}; // if
|
||||
if ( p->w_top > p->p_top &&
|
||||
!(IS_CONS_TYPE_TASKQ(p->stack_data[ p->w_top ].type) && IS_CONS_TYPE_TASKQ(ct))) {
|
||||
// We are already in a WORKSHARE construct for this PARALLEL region.
|
||||
__kmp_error_construct2( kmp_i18n_msg_CnsInvalidNesting, ct, ident, & p->stack_data[ p->w_top ] );
|
||||
}; // if
|
||||
if ( p->s_top > p->p_top ) {
|
||||
// We are already in a SYNC construct for this PARALLEL region.
|
||||
__kmp_error_construct2( kmp_i18n_msg_CnsInvalidNesting, ct, ident, & p->stack_data[ p->s_top ] );
|
||||
}; // if
|
||||
if (p->stack_top >= p->stack_size) {
|
||||
__kmp_expand_cons_stack(gtid, p);
|
||||
}; // if
|
||||
if (p->w_top > p->p_top &&
|
||||
!(IS_CONS_TYPE_TASKQ(p->stack_data[p->w_top].type) &&
|
||||
IS_CONS_TYPE_TASKQ(ct))) {
|
||||
// We are already in a WORKSHARE construct for this PARALLEL region.
|
||||
__kmp_error_construct2(kmp_i18n_msg_CnsInvalidNesting, ct, ident,
|
||||
&p->stack_data[p->w_top]);
|
||||
}; // if
|
||||
if (p->s_top > p->p_top) {
|
||||
// We are already in a SYNC construct for this PARALLEL region.
|
||||
__kmp_error_construct2(kmp_i18n_msg_CnsInvalidNesting, ct, ident,
|
||||
&p->stack_data[p->s_top]);
|
||||
}; // if
|
||||
}
|
||||
|
||||
void
|
||||
__kmp_push_workshare( int gtid, enum cons_type ct, ident_t const * ident )
|
||||
{
|
||||
int tos;
|
||||
struct cons_header *p = __kmp_threads[ gtid ]->th.th_cons;
|
||||
KE_TRACE( 10, ("__kmp_push_workshare (%d %d)\n", gtid, __kmp_get_gtid() ) );
|
||||
__kmp_check_workshare( gtid, ct, ident );
|
||||
KE_TRACE( 100, ( PUSH_MSG( ct, ident ) ) );
|
||||
tos = ++p->stack_top;
|
||||
p->stack_data[ tos ].type = ct;
|
||||
p->stack_data[ tos ].prev = p->w_top;
|
||||
p->stack_data[ tos ].ident = ident;
|
||||
p->stack_data[ tos ].name = NULL;
|
||||
p->w_top = tos;
|
||||
KE_DUMP( 1000, dump_cons_stack( gtid, p ) );
|
||||
void __kmp_push_workshare(int gtid, enum cons_type ct, ident_t const *ident) {
|
||||
int tos;
|
||||
struct cons_header *p = __kmp_threads[gtid]->th.th_cons;
|
||||
KE_TRACE(10, ("__kmp_push_workshare (%d %d)\n", gtid, __kmp_get_gtid()));
|
||||
__kmp_check_workshare(gtid, ct, ident);
|
||||
KE_TRACE(100, (PUSH_MSG(ct, ident)));
|
||||
tos = ++p->stack_top;
|
||||
p->stack_data[tos].type = ct;
|
||||
p->stack_data[tos].prev = p->w_top;
|
||||
p->stack_data[tos].ident = ident;
|
||||
p->stack_data[tos].name = NULL;
|
||||
p->w_top = tos;
|
||||
KE_DUMP(1000, dump_cons_stack(gtid, p));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -276,98 +254,91 @@ __kmp_check_sync( int gtid, enum cons_type ct, ident_t const * ident, kmp_user_l
|
||||
__kmp_check_sync( int gtid, enum cons_type ct, ident_t const * ident, kmp_user_lock_p lck )
|
||||
#endif
|
||||
{
|
||||
struct cons_header *p = __kmp_threads[ gtid ]->th.th_cons;
|
||||
struct cons_header *p = __kmp_threads[gtid]->th.th_cons;
|
||||
|
||||
KE_TRACE( 10, ("__kmp_check_sync (gtid=%d)\n", __kmp_get_gtid() ) );
|
||||
KE_TRACE(10, ("__kmp_check_sync (gtid=%d)\n", __kmp_get_gtid()));
|
||||
|
||||
if (p->stack_top >= p->stack_size)
|
||||
__kmp_expand_cons_stack( gtid, p );
|
||||
if (p->stack_top >= p->stack_size)
|
||||
__kmp_expand_cons_stack(gtid, p);
|
||||
|
||||
if (ct == ct_ordered_in_parallel || ct == ct_ordered_in_pdo || ct == ct_ordered_in_taskq ) {
|
||||
if (p->w_top <= p->p_top) {
|
||||
/* we are not in a worksharing construct */
|
||||
#ifdef BUILD_PARALLEL_ORDERED
|
||||
/* do not report error messages for PARALLEL ORDERED */
|
||||
KMP_ASSERT( ct == ct_ordered_in_parallel );
|
||||
#else
|
||||
__kmp_error_construct( kmp_i18n_msg_CnsBoundToWorksharing, ct, ident );
|
||||
#endif /* BUILD_PARALLEL_ORDERED */
|
||||
} else {
|
||||
/* inside a WORKSHARING construct for this PARALLEL region */
|
||||
if (!IS_CONS_TYPE_ORDERED(p->stack_data[ p->w_top ].type)) {
|
||||
if (p->stack_data[ p->w_top ].type == ct_taskq) {
|
||||
__kmp_error_construct2(
|
||||
kmp_i18n_msg_CnsNotInTaskConstruct,
|
||||
ct, ident,
|
||||
& p->stack_data[ p->w_top ]
|
||||
);
|
||||
} else {
|
||||
__kmp_error_construct2(
|
||||
kmp_i18n_msg_CnsNoOrderedClause,
|
||||
ct, ident,
|
||||
& p->stack_data[ p->w_top ]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (p->s_top > p->p_top && p->s_top > p->w_top) {
|
||||
/* inside a sync construct which is inside a worksharing construct */
|
||||
int index = p->s_top;
|
||||
enum cons_type stack_type;
|
||||
|
||||
stack_type = p->stack_data[ index ].type;
|
||||
|
||||
if (stack_type == ct_critical ||
|
||||
( ( stack_type == ct_ordered_in_parallel ||
|
||||
stack_type == ct_ordered_in_pdo ||
|
||||
stack_type == ct_ordered_in_taskq ) && /* C doesn't allow named ordered; ordered in ordered gets error */
|
||||
p->stack_data[ index ].ident != NULL &&
|
||||
(p->stack_data[ index ].ident->flags & KMP_IDENT_KMPC ))) {
|
||||
/* we are in ORDERED which is inside an ORDERED or CRITICAL construct */
|
||||
__kmp_error_construct2(
|
||||
kmp_i18n_msg_CnsInvalidNesting,
|
||||
ct, ident,
|
||||
& p->stack_data[ index ]
|
||||
);
|
||||
}
|
||||
}
|
||||
} else if ( ct == ct_critical ) {
|
||||
#if KMP_USE_DYNAMIC_LOCK
|
||||
if ( lck != NULL && __kmp_get_user_lock_owner( lck, seq ) == gtid ) { /* this same thread already has lock for this critical section */
|
||||
if (ct == ct_ordered_in_parallel || ct == ct_ordered_in_pdo ||
|
||||
ct == ct_ordered_in_taskq) {
|
||||
if (p->w_top <= p->p_top) {
|
||||
/* we are not in a worksharing construct */
|
||||
#ifdef BUILD_PARALLEL_ORDERED
|
||||
/* do not report error messages for PARALLEL ORDERED */
|
||||
KMP_ASSERT(ct == ct_ordered_in_parallel);
|
||||
#else
|
||||
if ( lck != NULL && __kmp_get_user_lock_owner( lck ) == gtid ) { /* this same thread already has lock for this critical section */
|
||||
__kmp_error_construct(kmp_i18n_msg_CnsBoundToWorksharing, ct, ident);
|
||||
#endif /* BUILD_PARALLEL_ORDERED */
|
||||
} else {
|
||||
/* inside a WORKSHARING construct for this PARALLEL region */
|
||||
if (!IS_CONS_TYPE_ORDERED(p->stack_data[p->w_top].type)) {
|
||||
if (p->stack_data[p->w_top].type == ct_taskq) {
|
||||
__kmp_error_construct2(kmp_i18n_msg_CnsNotInTaskConstruct, ct, ident,
|
||||
&p->stack_data[p->w_top]);
|
||||
} else {
|
||||
__kmp_error_construct2(kmp_i18n_msg_CnsNoOrderedClause, ct, ident,
|
||||
&p->stack_data[p->w_top]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (p->s_top > p->p_top && p->s_top > p->w_top) {
|
||||
/* inside a sync construct which is inside a worksharing construct */
|
||||
int index = p->s_top;
|
||||
enum cons_type stack_type;
|
||||
|
||||
stack_type = p->stack_data[index].type;
|
||||
|
||||
if (stack_type == ct_critical ||
|
||||
((stack_type == ct_ordered_in_parallel ||
|
||||
stack_type == ct_ordered_in_pdo ||
|
||||
stack_type ==
|
||||
ct_ordered_in_taskq) && /* C doesn't allow named ordered;
|
||||
ordered in ordered gets error */
|
||||
p->stack_data[index].ident != NULL &&
|
||||
(p->stack_data[index].ident->flags & KMP_IDENT_KMPC))) {
|
||||
/* we are in ORDERED which is inside an ORDERED or CRITICAL construct */
|
||||
__kmp_error_construct2(kmp_i18n_msg_CnsInvalidNesting, ct, ident,
|
||||
&p->stack_data[index]);
|
||||
}
|
||||
}
|
||||
} else if (ct == ct_critical) {
|
||||
#if KMP_USE_DYNAMIC_LOCK
|
||||
if (lck != NULL &&
|
||||
__kmp_get_user_lock_owner(lck, seq) ==
|
||||
gtid) { /* this thread already has lock for this critical section */
|
||||
#else
|
||||
if (lck != NULL &&
|
||||
__kmp_get_user_lock_owner(lck) ==
|
||||
gtid) { /* this thread already has lock for this critical section */
|
||||
#endif
|
||||
int index = p->s_top;
|
||||
struct cons_data cons = { NULL, ct_critical, 0, NULL };
|
||||
/* walk up construct stack and try to find critical with matching name */
|
||||
while ( index != 0 && p->stack_data[ index ].name != lck ) {
|
||||
index = p->stack_data[ index ].prev;
|
||||
}
|
||||
if ( index != 0 ) {
|
||||
/* found match on the stack (may not always because of interleaved critical for Fortran) */
|
||||
cons = p->stack_data[ index ];
|
||||
}
|
||||
/* we are in CRITICAL which is inside a CRITICAL construct of the same name */
|
||||
__kmp_error_construct2( kmp_i18n_msg_CnsNestingSameName, ct, ident, & cons );
|
||||
}
|
||||
} else if ( ct == ct_master || ct == ct_reduce ) {
|
||||
if (p->w_top > p->p_top) {
|
||||
/* inside a WORKSHARING construct for this PARALLEL region */
|
||||
__kmp_error_construct2(
|
||||
kmp_i18n_msg_CnsInvalidNesting,
|
||||
ct, ident,
|
||||
& p->stack_data[ p->w_top ]
|
||||
);
|
||||
}
|
||||
if (ct == ct_reduce && p->s_top > p->p_top) {
|
||||
/* inside a another SYNC construct for this PARALLEL region */
|
||||
__kmp_error_construct2(
|
||||
kmp_i18n_msg_CnsInvalidNesting,
|
||||
ct, ident,
|
||||
& p->stack_data[ p->s_top ]
|
||||
);
|
||||
}; // if
|
||||
int index = p->s_top;
|
||||
struct cons_data cons = {NULL, ct_critical, 0, NULL};
|
||||
/* walk up construct stack and try to find critical with matching name */
|
||||
while (index != 0 && p->stack_data[index].name != lck) {
|
||||
index = p->stack_data[index].prev;
|
||||
}
|
||||
if (index != 0) {
|
||||
/* found match on the stack (may not always because of interleaved
|
||||
* critical for Fortran) */
|
||||
cons = p->stack_data[index];
|
||||
}
|
||||
/* we are in CRITICAL which is inside a CRITICAL construct of same name */
|
||||
__kmp_error_construct2(kmp_i18n_msg_CnsNestingSameName, ct, ident, &cons);
|
||||
}
|
||||
} else if (ct == ct_master || ct == ct_reduce) {
|
||||
if (p->w_top > p->p_top) {
|
||||
/* inside a WORKSHARING construct for this PARALLEL region */
|
||||
__kmp_error_construct2(kmp_i18n_msg_CnsInvalidNesting, ct, ident,
|
||||
&p->stack_data[p->w_top]);
|
||||
}
|
||||
if (ct == ct_reduce && p->s_top > p->p_top) {
|
||||
/* inside a another SYNC construct for this PARALLEL region */
|
||||
__kmp_error_construct2(kmp_i18n_msg_CnsInvalidNesting, ct, ident,
|
||||
&p->stack_data[p->s_top]);
|
||||
}; // if
|
||||
}; // if
|
||||
}
|
||||
|
||||
void
|
||||
@@ -377,147 +348,118 @@ __kmp_push_sync( int gtid, enum cons_type ct, ident_t const * ident, kmp_user_lo
|
||||
__kmp_push_sync( int gtid, enum cons_type ct, ident_t const * ident, kmp_user_lock_p lck )
|
||||
#endif
|
||||
{
|
||||
int tos;
|
||||
struct cons_header *p = __kmp_threads[ gtid ]->th.th_cons;
|
||||
int tos;
|
||||
struct cons_header *p = __kmp_threads[gtid]->th.th_cons;
|
||||
|
||||
KMP_ASSERT( gtid == __kmp_get_gtid() );
|
||||
KE_TRACE( 10, ("__kmp_push_sync (gtid=%d)\n", gtid ) );
|
||||
KMP_ASSERT(gtid == __kmp_get_gtid());
|
||||
KE_TRACE(10, ("__kmp_push_sync (gtid=%d)\n", gtid));
|
||||
#if KMP_USE_DYNAMIC_LOCK
|
||||
__kmp_check_sync( gtid, ct, ident, lck, seq );
|
||||
__kmp_check_sync(gtid, ct, ident, lck, seq);
|
||||
#else
|
||||
__kmp_check_sync( gtid, ct, ident, lck );
|
||||
__kmp_check_sync(gtid, ct, ident, lck);
|
||||
#endif
|
||||
KE_TRACE( 100, ( PUSH_MSG( ct, ident ) ) );
|
||||
tos = ++ p->stack_top;
|
||||
p->stack_data[ tos ].type = ct;
|
||||
p->stack_data[ tos ].prev = p->s_top;
|
||||
p->stack_data[ tos ].ident = ident;
|
||||
p->stack_data[ tos ].name = lck;
|
||||
p->s_top = tos;
|
||||
KE_DUMP( 1000, dump_cons_stack( gtid, p ) );
|
||||
KE_TRACE(100, (PUSH_MSG(ct, ident)));
|
||||
tos = ++p->stack_top;
|
||||
p->stack_data[tos].type = ct;
|
||||
p->stack_data[tos].prev = p->s_top;
|
||||
p->stack_data[tos].ident = ident;
|
||||
p->stack_data[tos].name = lck;
|
||||
p->s_top = tos;
|
||||
KE_DUMP(1000, dump_cons_stack(gtid, p));
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
void
|
||||
__kmp_pop_parallel( int gtid, ident_t const * ident )
|
||||
{
|
||||
int tos;
|
||||
struct cons_header *p = __kmp_threads[ gtid ]->th.th_cons;
|
||||
tos = p->stack_top;
|
||||
KE_TRACE( 10, ("__kmp_pop_parallel (%d %d)\n", gtid, __kmp_get_gtid() ) );
|
||||
if ( tos == 0 || p->p_top == 0 ) {
|
||||
__kmp_error_construct( kmp_i18n_msg_CnsDetectedEnd, ct_parallel, ident );
|
||||
}
|
||||
if ( tos != p->p_top || p->stack_data[ tos ].type != ct_parallel ) {
|
||||
__kmp_error_construct2(
|
||||
kmp_i18n_msg_CnsExpectedEnd,
|
||||
ct_parallel, ident,
|
||||
& p->stack_data[ tos ]
|
||||
);
|
||||
}
|
||||
KE_TRACE( 100, ( POP_MSG( p ) ) );
|
||||
p->p_top = p->stack_data[ tos ].prev;
|
||||
p->stack_data[ tos ].type = ct_none;
|
||||
p->stack_data[ tos ].ident = NULL;
|
||||
p->stack_top = tos - 1;
|
||||
KE_DUMP( 1000, dump_cons_stack( gtid, p ) );
|
||||
void __kmp_pop_parallel(int gtid, ident_t const *ident) {
|
||||
int tos;
|
||||
struct cons_header *p = __kmp_threads[gtid]->th.th_cons;
|
||||
tos = p->stack_top;
|
||||
KE_TRACE(10, ("__kmp_pop_parallel (%d %d)\n", gtid, __kmp_get_gtid()));
|
||||
if (tos == 0 || p->p_top == 0) {
|
||||
__kmp_error_construct(kmp_i18n_msg_CnsDetectedEnd, ct_parallel, ident);
|
||||
}
|
||||
if (tos != p->p_top || p->stack_data[tos].type != ct_parallel) {
|
||||
__kmp_error_construct2(kmp_i18n_msg_CnsExpectedEnd, ct_parallel, ident,
|
||||
&p->stack_data[tos]);
|
||||
}
|
||||
KE_TRACE(100, (POP_MSG(p)));
|
||||
p->p_top = p->stack_data[tos].prev;
|
||||
p->stack_data[tos].type = ct_none;
|
||||
p->stack_data[tos].ident = NULL;
|
||||
p->stack_top = tos - 1;
|
||||
KE_DUMP(1000, dump_cons_stack(gtid, p));
|
||||
}
|
||||
|
||||
enum cons_type
|
||||
__kmp_pop_workshare( int gtid, enum cons_type ct, ident_t const * ident )
|
||||
{
|
||||
int tos;
|
||||
struct cons_header *p = __kmp_threads[ gtid ]->th.th_cons;
|
||||
enum cons_type __kmp_pop_workshare(int gtid, enum cons_type ct,
|
||||
ident_t const *ident) {
|
||||
int tos;
|
||||
struct cons_header *p = __kmp_threads[gtid]->th.th_cons;
|
||||
|
||||
tos = p->stack_top;
|
||||
KE_TRACE( 10, ("__kmp_pop_workshare (%d %d)\n", gtid, __kmp_get_gtid() ) );
|
||||
if ( tos == 0 || p->w_top == 0 ) {
|
||||
__kmp_error_construct( kmp_i18n_msg_CnsDetectedEnd, ct, ident );
|
||||
}
|
||||
tos = p->stack_top;
|
||||
KE_TRACE(10, ("__kmp_pop_workshare (%d %d)\n", gtid, __kmp_get_gtid()));
|
||||
if (tos == 0 || p->w_top == 0) {
|
||||
__kmp_error_construct(kmp_i18n_msg_CnsDetectedEnd, ct, ident);
|
||||
}
|
||||
|
||||
if ( tos != p->w_top ||
|
||||
( p->stack_data[ tos ].type != ct &&
|
||||
/* below are two exceptions to the rule that construct types must match */
|
||||
! ( p->stack_data[ tos ].type == ct_pdo_ordered && ct == ct_pdo ) &&
|
||||
! ( p->stack_data[ tos ].type == ct_task_ordered && ct == ct_task )
|
||||
)
|
||||
) {
|
||||
__kmp_check_null_func();
|
||||
__kmp_error_construct2(
|
||||
kmp_i18n_msg_CnsExpectedEnd,
|
||||
ct, ident,
|
||||
& p->stack_data[ tos ]
|
||||
);
|
||||
}
|
||||
KE_TRACE( 100, ( POP_MSG( p ) ) );
|
||||
p->w_top = p->stack_data[ tos ].prev;
|
||||
p->stack_data[ tos ].type = ct_none;
|
||||
p->stack_data[ tos ].ident = NULL;
|
||||
p->stack_top = tos - 1;
|
||||
KE_DUMP( 1000, dump_cons_stack( gtid, p ) );
|
||||
return p->stack_data[ p->w_top ].type;
|
||||
if (tos != p->w_top ||
|
||||
(p->stack_data[tos].type != ct &&
|
||||
// below are two exceptions to the rule that construct types must match
|
||||
!(p->stack_data[tos].type == ct_pdo_ordered && ct == ct_pdo) &&
|
||||
!(p->stack_data[tos].type == ct_task_ordered && ct == ct_task))) {
|
||||
__kmp_check_null_func();
|
||||
__kmp_error_construct2(kmp_i18n_msg_CnsExpectedEnd, ct, ident,
|
||||
&p->stack_data[tos]);
|
||||
}
|
||||
KE_TRACE(100, (POP_MSG(p)));
|
||||
p->w_top = p->stack_data[tos].prev;
|
||||
p->stack_data[tos].type = ct_none;
|
||||
p->stack_data[tos].ident = NULL;
|
||||
p->stack_top = tos - 1;
|
||||
KE_DUMP(1000, dump_cons_stack(gtid, p));
|
||||
return p->stack_data[p->w_top].type;
|
||||
}
|
||||
|
||||
void
|
||||
__kmp_pop_sync( int gtid, enum cons_type ct, ident_t const * ident )
|
||||
{
|
||||
int tos;
|
||||
struct cons_header *p = __kmp_threads[ gtid ]->th.th_cons;
|
||||
tos = p->stack_top;
|
||||
KE_TRACE( 10, ("__kmp_pop_sync (%d %d)\n", gtid, __kmp_get_gtid() ) );
|
||||
if ( tos == 0 || p->s_top == 0 ) {
|
||||
__kmp_error_construct( kmp_i18n_msg_CnsDetectedEnd, ct, ident );
|
||||
};
|
||||
if ( tos != p->s_top || p->stack_data[ tos ].type != ct ) {
|
||||
__kmp_check_null_func();
|
||||
__kmp_error_construct2(
|
||||
kmp_i18n_msg_CnsExpectedEnd,
|
||||
ct, ident,
|
||||
& p->stack_data[ tos ]
|
||||
);
|
||||
};
|
||||
if ( gtid < 0 ) {
|
||||
__kmp_check_null_func();
|
||||
};
|
||||
KE_TRACE( 100, ( POP_MSG( p ) ) );
|
||||
p->s_top = p->stack_data[ tos ].prev;
|
||||
p->stack_data[ tos ].type = ct_none;
|
||||
p->stack_data[ tos ].ident = NULL;
|
||||
p->stack_top = tos - 1;
|
||||
KE_DUMP( 1000, dump_cons_stack( gtid, p ) );
|
||||
void __kmp_pop_sync(int gtid, enum cons_type ct, ident_t const *ident) {
|
||||
int tos;
|
||||
struct cons_header *p = __kmp_threads[gtid]->th.th_cons;
|
||||
tos = p->stack_top;
|
||||
KE_TRACE(10, ("__kmp_pop_sync (%d %d)\n", gtid, __kmp_get_gtid()));
|
||||
if (tos == 0 || p->s_top == 0) {
|
||||
__kmp_error_construct(kmp_i18n_msg_CnsDetectedEnd, ct, ident);
|
||||
};
|
||||
if (tos != p->s_top || p->stack_data[tos].type != ct) {
|
||||
__kmp_check_null_func();
|
||||
__kmp_error_construct2(kmp_i18n_msg_CnsExpectedEnd, ct, ident,
|
||||
&p->stack_data[tos]);
|
||||
};
|
||||
if (gtid < 0) {
|
||||
__kmp_check_null_func();
|
||||
};
|
||||
KE_TRACE(100, (POP_MSG(p)));
|
||||
p->s_top = p->stack_data[tos].prev;
|
||||
p->stack_data[tos].type = ct_none;
|
||||
p->stack_data[tos].ident = NULL;
|
||||
p->stack_top = tos - 1;
|
||||
KE_DUMP(1000, dump_cons_stack(gtid, p));
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
void
|
||||
__kmp_check_barrier( int gtid, enum cons_type ct, ident_t const * ident )
|
||||
{
|
||||
struct cons_header *p = __kmp_threads[ gtid ]->th.th_cons;
|
||||
KE_TRACE( 10, ("__kmp_check_barrier (loc: %p, gtid: %d %d)\n", ident, gtid, __kmp_get_gtid() ) );
|
||||
if ( ident != 0 ) {
|
||||
__kmp_check_null_func();
|
||||
}
|
||||
if ( p->w_top > p->p_top ) {
|
||||
/* we are already in a WORKSHARING construct for this PARALLEL region */
|
||||
__kmp_error_construct2(
|
||||
kmp_i18n_msg_CnsInvalidNesting,
|
||||
ct, ident,
|
||||
& p->stack_data[ p->w_top ]
|
||||
);
|
||||
}
|
||||
if (p->s_top > p->p_top) {
|
||||
/* we are already in a SYNC construct for this PARALLEL region */
|
||||
__kmp_error_construct2(
|
||||
kmp_i18n_msg_CnsInvalidNesting,
|
||||
ct, ident,
|
||||
& p->stack_data[ p->s_top ]
|
||||
);
|
||||
}
|
||||
void __kmp_check_barrier(int gtid, enum cons_type ct, ident_t const *ident) {
|
||||
struct cons_header *p = __kmp_threads[gtid]->th.th_cons;
|
||||
KE_TRACE(10, ("__kmp_check_barrier (loc: %p, gtid: %d %d)\n", ident, gtid,
|
||||
__kmp_get_gtid()));
|
||||
if (ident != 0) {
|
||||
__kmp_check_null_func();
|
||||
}
|
||||
if (p->w_top > p->p_top) {
|
||||
/* we are already in a WORKSHARING construct for this PARALLEL region */
|
||||
__kmp_error_construct2(kmp_i18n_msg_CnsInvalidNesting, ct, ident,
|
||||
&p->stack_data[p->w_top]);
|
||||
}
|
||||
if (p->s_top > p->p_top) {
|
||||
/* we are already in a SYNC construct for this PARALLEL region */
|
||||
__kmp_error_construct2(kmp_i18n_msg_CnsInvalidNesting, ct, ident,
|
||||
&p->stack_data[p->s_top]);
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
+24
-18
@@ -20,38 +20,44 @@
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void __kmp_error_construct( kmp_i18n_id_t id, enum cons_type ct, ident_t const * ident );
|
||||
void __kmp_error_construct2( kmp_i18n_id_t id, enum cons_type ct, ident_t const * ident, struct cons_data const * cons );
|
||||
void __kmp_error_construct(kmp_i18n_id_t id, enum cons_type ct,
|
||||
ident_t const *ident);
|
||||
void __kmp_error_construct2(kmp_i18n_id_t id, enum cons_type ct,
|
||||
ident_t const *ident, struct cons_data const *cons);
|
||||
|
||||
struct cons_header * __kmp_allocate_cons_stack( int gtid );
|
||||
void __kmp_free_cons_stack( void * ptr );
|
||||
struct cons_header *__kmp_allocate_cons_stack(int gtid);
|
||||
void __kmp_free_cons_stack(void *ptr);
|
||||
|
||||
void __kmp_push_parallel( int gtid, ident_t const * ident );
|
||||
void __kmp_push_workshare( int gtid, enum cons_type ct, ident_t const * ident );
|
||||
void __kmp_push_parallel(int gtid, ident_t const *ident);
|
||||
void __kmp_push_workshare(int gtid, enum cons_type ct, ident_t const *ident);
|
||||
#if KMP_USE_DYNAMIC_LOCK
|
||||
void __kmp_push_sync( int gtid, enum cons_type ct, ident_t const * ident, kmp_user_lock_p name, kmp_uint32 );
|
||||
void __kmp_push_sync(int gtid, enum cons_type ct, ident_t const *ident,
|
||||
kmp_user_lock_p name, kmp_uint32);
|
||||
#else
|
||||
void __kmp_push_sync( int gtid, enum cons_type ct, ident_t const * ident, kmp_user_lock_p name );
|
||||
void __kmp_push_sync(int gtid, enum cons_type ct, ident_t const *ident,
|
||||
kmp_user_lock_p name);
|
||||
#endif
|
||||
|
||||
void __kmp_check_workshare( int gtid, enum cons_type ct, ident_t const * ident );
|
||||
void __kmp_check_workshare(int gtid, enum cons_type ct, ident_t const *ident);
|
||||
#if KMP_USE_DYNAMIC_LOCK
|
||||
void __kmp_check_sync( int gtid, enum cons_type ct, ident_t const * ident, kmp_user_lock_p name, kmp_uint32 );
|
||||
void __kmp_check_sync(int gtid, enum cons_type ct, ident_t const *ident,
|
||||
kmp_user_lock_p name, kmp_uint32);
|
||||
#else
|
||||
void __kmp_check_sync( int gtid, enum cons_type ct, ident_t const * ident, kmp_user_lock_p name );
|
||||
void __kmp_check_sync(int gtid, enum cons_type ct, ident_t const *ident,
|
||||
kmp_user_lock_p name);
|
||||
#endif
|
||||
|
||||
void __kmp_pop_parallel( int gtid, ident_t const * ident );
|
||||
enum cons_type __kmp_pop_workshare( int gtid, enum cons_type ct, ident_t const * ident );
|
||||
void __kmp_pop_sync( int gtid, enum cons_type ct, ident_t const * ident );
|
||||
void __kmp_check_barrier( int gtid, enum cons_type ct, ident_t const * ident );
|
||||
void __kmp_pop_parallel(int gtid, ident_t const *ident);
|
||||
enum cons_type __kmp_pop_workshare(int gtid, enum cons_type ct,
|
||||
ident_t const *ident);
|
||||
void __kmp_pop_sync(int gtid, enum cons_type ct, ident_t const *ident);
|
||||
void __kmp_check_barrier(int gtid, enum cons_type ct, ident_t const *ident);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // KMP_ERROR_H
|
||||
|
||||
|
||||
@@ -17,20 +17,21 @@
|
||||
#include "kmp_affinity.h"
|
||||
|
||||
#if KMP_OS_WINDOWS
|
||||
# if defined KMP_WIN_CDECL || !defined KMP_DYNAMIC_LIB
|
||||
# define KMP_FTN_ENTRIES KMP_FTN_UPPER
|
||||
# endif
|
||||
#if defined KMP_WIN_CDECL || !defined KMP_DYNAMIC_LIB
|
||||
#define KMP_FTN_ENTRIES KMP_FTN_UPPER
|
||||
#endif
|
||||
#elif KMP_OS_UNIX
|
||||
# define KMP_FTN_ENTRIES KMP_FTN_PLAIN
|
||||
#define KMP_FTN_ENTRIES KMP_FTN_PLAIN
|
||||
#endif
|
||||
|
||||
// Note: This string is not printed when KMP_VERSION=1.
|
||||
char const __kmp_version_ftncdecl[] = KMP_VERSION_PREFIX "Fortran __cdecl OMP support: "
|
||||
char const __kmp_version_ftncdecl[] =
|
||||
KMP_VERSION_PREFIX "Fortran __cdecl OMP support: "
|
||||
#ifdef KMP_FTN_ENTRIES
|
||||
"yes";
|
||||
# define FTN_STDCALL /* no stdcall */
|
||||
# include "kmp_ftn_os.h"
|
||||
# include "kmp_ftn_entry.h"
|
||||
"yes";
|
||||
#define FTN_STDCALL /* no stdcall */
|
||||
#include "kmp_ftn_os.h"
|
||||
#include "kmp_ftn_entry.h"
|
||||
#else
|
||||
"no";
|
||||
"no";
|
||||
#endif /* KMP_FTN_ENTRIES */
|
||||
|
||||
+952
-1144
File diff suppressed because it is too large
Load Diff
@@ -17,18 +17,19 @@
|
||||
#include "kmp_affinity.h"
|
||||
|
||||
#if KMP_OS_WINDOWS
|
||||
# define KMP_FTN_ENTRIES KMP_FTN_PLAIN
|
||||
#define KMP_FTN_ENTRIES KMP_FTN_PLAIN
|
||||
#elif KMP_OS_UNIX
|
||||
# define KMP_FTN_ENTRIES KMP_FTN_APPEND
|
||||
#define KMP_FTN_ENTRIES KMP_FTN_APPEND
|
||||
#endif
|
||||
|
||||
// Note: This string is not printed when KMP_VERSION=1.
|
||||
char const __kmp_version_ftnextra[] = KMP_VERSION_PREFIX "Fortran \"extra\" OMP support: "
|
||||
char const __kmp_version_ftnextra[] =
|
||||
KMP_VERSION_PREFIX "Fortran \"extra\" OMP support: "
|
||||
#ifdef KMP_FTN_ENTRIES
|
||||
"yes";
|
||||
# define FTN_STDCALL /* nothing to do */
|
||||
# include "kmp_ftn_os.h"
|
||||
# include "kmp_ftn_entry.h"
|
||||
"yes";
|
||||
#define FTN_STDCALL /* nothing to do */
|
||||
#include "kmp_ftn_os.h"
|
||||
#include "kmp_ftn_entry.h"
|
||||
#else
|
||||
"no";
|
||||
"no";
|
||||
#endif /* KMP_FTN_ENTRIES */
|
||||
|
||||
+483
-459
File diff suppressed because it is too large
Load Diff
@@ -16,20 +16,20 @@
|
||||
#include "kmp.h"
|
||||
|
||||
// Note: This string is not printed when KMP_VERSION=1.
|
||||
char const __kmp_version_ftnstdcall[] = KMP_VERSION_PREFIX "Fortran __stdcall OMP support: "
|
||||
char const __kmp_version_ftnstdcall[] =
|
||||
KMP_VERSION_PREFIX "Fortran __stdcall OMP support: "
|
||||
#ifdef USE_FTN_STDCALL
|
||||
"yes";
|
||||
"yes";
|
||||
#else
|
||||
"no";
|
||||
"no";
|
||||
#endif
|
||||
|
||||
#ifdef USE_FTN_STDCALL
|
||||
|
||||
#define FTN_STDCALL KMP_STDCALL
|
||||
#define KMP_FTN_ENTRIES USE_FTN_STDCALL
|
||||
#define FTN_STDCALL KMP_STDCALL
|
||||
#define KMP_FTN_ENTRIES USE_FTN_STDCALL
|
||||
|
||||
#include "kmp_ftn_os.h"
|
||||
#include "kmp_ftn_entry.h"
|
||||
#include "kmp_ftn_os.h"
|
||||
|
||||
#endif /* USE_FTN_STDCALL */
|
||||
|
||||
|
||||
+286
-252
@@ -19,7 +19,7 @@
|
||||
kmp_key_t __kmp_gtid_threadprivate_key;
|
||||
|
||||
#if KMP_ARCH_X86 || KMP_ARCH_X86_64
|
||||
kmp_cpuinfo_t __kmp_cpuinfo = { 0 }; // Not initialized
|
||||
kmp_cpuinfo_t __kmp_cpuinfo = {0}; // Not initialized
|
||||
#endif
|
||||
|
||||
#if KMP_STATS_ENABLED
|
||||
@@ -27,11 +27,12 @@ kmp_cpuinfo_t __kmp_cpuinfo = { 0 }; // Not initialized
|
||||
// lock for modifying the global __kmp_stats_list
|
||||
kmp_tas_lock_t __kmp_stats_lock;
|
||||
|
||||
// global list of per thread stats, the head is a sentinel node which accumulates all stats produced before __kmp_create_worker is called.
|
||||
kmp_stats_list* __kmp_stats_list;
|
||||
// global list of per thread stats, the head is a sentinel node which
|
||||
// accumulates all stats produced before __kmp_create_worker is called.
|
||||
kmp_stats_list *__kmp_stats_list;
|
||||
|
||||
// thread local pointer to stats node within list
|
||||
__thread kmp_stats_list* __kmp_stats_thread_ptr = NULL;
|
||||
__thread kmp_stats_list *__kmp_stats_thread_ptr = NULL;
|
||||
|
||||
// gives reference tick for all events (considered the 0 tick)
|
||||
tsc_tick_count __kmp_stats_start_time;
|
||||
@@ -40,176 +41,196 @@ tsc_tick_count __kmp_stats_start_time;
|
||||
/* ----------------------------------------------------- */
|
||||
/* INITIALIZATION VARIABLES */
|
||||
/* they are syncronized to write during init, but read anytime */
|
||||
volatile int __kmp_init_serial = FALSE;
|
||||
volatile int __kmp_init_gtid = FALSE;
|
||||
volatile int __kmp_init_common = FALSE;
|
||||
volatile int __kmp_init_middle = FALSE;
|
||||
volatile int __kmp_init_parallel = FALSE;
|
||||
volatile int __kmp_init_serial = FALSE;
|
||||
volatile int __kmp_init_gtid = FALSE;
|
||||
volatile int __kmp_init_common = FALSE;
|
||||
volatile int __kmp_init_middle = FALSE;
|
||||
volatile int __kmp_init_parallel = FALSE;
|
||||
#if KMP_USE_MONITOR
|
||||
volatile int __kmp_init_monitor = 0; /* 1 - launched, 2 - actually started (Windows* OS only) */
|
||||
volatile int __kmp_init_monitor =
|
||||
0; /* 1 - launched, 2 - actually started (Windows* OS only) */
|
||||
#endif
|
||||
volatile int __kmp_init_user_locks = FALSE;
|
||||
volatile int __kmp_init_user_locks = FALSE;
|
||||
|
||||
/* list of address of allocated caches for commons */
|
||||
kmp_cached_addr_t *__kmp_threadpriv_cache_list = NULL;
|
||||
kmp_cached_addr_t *__kmp_threadpriv_cache_list = NULL;
|
||||
|
||||
int __kmp_init_counter = 0;
|
||||
int __kmp_root_counter = 0;
|
||||
int __kmp_version = 0;
|
||||
int __kmp_init_counter = 0;
|
||||
int __kmp_root_counter = 0;
|
||||
int __kmp_version = 0;
|
||||
|
||||
volatile kmp_uint32 __kmp_team_counter = 0;
|
||||
volatile kmp_uint32 __kmp_task_counter = 0;
|
||||
volatile kmp_uint32 __kmp_team_counter = 0;
|
||||
volatile kmp_uint32 __kmp_task_counter = 0;
|
||||
|
||||
unsigned int __kmp_init_wait = KMP_DEFAULT_INIT_WAIT; /* initial number of spin-tests */
|
||||
unsigned int __kmp_next_wait = KMP_DEFAULT_NEXT_WAIT; /* susequent number of spin-tests */
|
||||
unsigned int __kmp_init_wait =
|
||||
KMP_DEFAULT_INIT_WAIT; /* initial number of spin-tests */
|
||||
unsigned int __kmp_next_wait =
|
||||
KMP_DEFAULT_NEXT_WAIT; /* susequent number of spin-tests */
|
||||
|
||||
size_t __kmp_stksize = KMP_DEFAULT_STKSIZE;
|
||||
size_t __kmp_stksize = KMP_DEFAULT_STKSIZE;
|
||||
#if KMP_USE_MONITOR
|
||||
size_t __kmp_monitor_stksize = 0; // auto adjust
|
||||
size_t __kmp_monitor_stksize = 0; // auto adjust
|
||||
#endif
|
||||
size_t __kmp_stkoffset = KMP_DEFAULT_STKOFFSET;
|
||||
int __kmp_stkpadding = KMP_MIN_STKPADDING;
|
||||
size_t __kmp_stkoffset = KMP_DEFAULT_STKOFFSET;
|
||||
int __kmp_stkpadding = KMP_MIN_STKPADDING;
|
||||
|
||||
size_t __kmp_malloc_pool_incr = KMP_DEFAULT_MALLOC_POOL_INCR;
|
||||
size_t __kmp_malloc_pool_incr = KMP_DEFAULT_MALLOC_POOL_INCR;
|
||||
|
||||
/* Barrier method defaults, settings, and strings */
|
||||
/* branch factor = 2^branch_bits (only relevant for tree and hyper barrier types) */
|
||||
// Barrier method defaults, settings, and strings.
|
||||
// branch factor = 2^branch_bits (only relevant for tree & hyper barrier types)
|
||||
#if KMP_ARCH_X86_64
|
||||
kmp_uint32 __kmp_barrier_gather_bb_dflt = 2; /* branch_factor = 4 */ /* hyper2: C78980 */
|
||||
kmp_uint32 __kmp_barrier_release_bb_dflt = 2; /* branch_factor = 4 */ /* hyper2: C78980 */
|
||||
kmp_uint32 __kmp_barrier_gather_bb_dflt = 2;
|
||||
/* branch_factor = 4 */ /* hyper2: C78980 */
|
||||
kmp_uint32 __kmp_barrier_release_bb_dflt = 2;
|
||||
/* branch_factor = 4 */ /* hyper2: C78980 */
|
||||
#else
|
||||
kmp_uint32 __kmp_barrier_gather_bb_dflt = 2; /* branch_factor = 4 */ /* communication in core for MIC */
|
||||
kmp_uint32 __kmp_barrier_release_bb_dflt = 2; /* branch_factor = 4 */ /* communication in core for MIC */
|
||||
kmp_uint32 __kmp_barrier_gather_bb_dflt = 2;
|
||||
/* branch_factor = 4 */ /* communication in core for MIC */
|
||||
kmp_uint32 __kmp_barrier_release_bb_dflt = 2;
|
||||
/* branch_factor = 4 */ /* communication in core for MIC */
|
||||
#endif // KMP_ARCH_X86_64
|
||||
#if KMP_ARCH_X86_64
|
||||
kmp_bar_pat_e __kmp_barrier_gather_pat_dflt = bp_hyper_bar; /* hyper2: C78980 */
|
||||
kmp_bar_pat_e __kmp_barrier_release_pat_dflt = bp_hyper_bar; /* hyper2: C78980 */
|
||||
kmp_bar_pat_e __kmp_barrier_gather_pat_dflt = bp_hyper_bar; /* hyper2: C78980 */
|
||||
kmp_bar_pat_e __kmp_barrier_release_pat_dflt =
|
||||
bp_hyper_bar; /* hyper2: C78980 */
|
||||
#else
|
||||
kmp_bar_pat_e __kmp_barrier_gather_pat_dflt = bp_linear_bar;
|
||||
kmp_bar_pat_e __kmp_barrier_gather_pat_dflt = bp_linear_bar;
|
||||
kmp_bar_pat_e __kmp_barrier_release_pat_dflt = bp_linear_bar;
|
||||
#endif
|
||||
kmp_uint32 __kmp_barrier_gather_branch_bits [ bs_last_barrier ] = { 0 };
|
||||
kmp_uint32 __kmp_barrier_release_branch_bits [ bs_last_barrier ] = { 0 };
|
||||
kmp_bar_pat_e __kmp_barrier_gather_pattern [ bs_last_barrier ] = { bp_linear_bar };
|
||||
kmp_bar_pat_e __kmp_barrier_release_pattern [ bs_last_barrier ] = { bp_linear_bar };
|
||||
char const *__kmp_barrier_branch_bit_env_name [ bs_last_barrier ] =
|
||||
{ "KMP_PLAIN_BARRIER", "KMP_FORKJOIN_BARRIER"
|
||||
#if KMP_FAST_REDUCTION_BARRIER
|
||||
, "KMP_REDUCTION_BARRIER"
|
||||
#endif // KMP_FAST_REDUCTION_BARRIER
|
||||
};
|
||||
char const *__kmp_barrier_pattern_env_name [ bs_last_barrier ] =
|
||||
{ "KMP_PLAIN_BARRIER_PATTERN", "KMP_FORKJOIN_BARRIER_PATTERN"
|
||||
#if KMP_FAST_REDUCTION_BARRIER
|
||||
, "KMP_REDUCTION_BARRIER_PATTERN"
|
||||
#endif // KMP_FAST_REDUCTION_BARRIER
|
||||
};
|
||||
char const *__kmp_barrier_type_name [ bs_last_barrier ] =
|
||||
{ "plain", "forkjoin"
|
||||
#if KMP_FAST_REDUCTION_BARRIER
|
||||
, "reduction"
|
||||
#endif // KMP_FAST_REDUCTION_BARRIER
|
||||
};
|
||||
char const *__kmp_barrier_pattern_name[bp_last_bar] = {"linear","tree","hyper","hierarchical"};
|
||||
kmp_uint32 __kmp_barrier_gather_branch_bits[bs_last_barrier] = {0};
|
||||
kmp_uint32 __kmp_barrier_release_branch_bits[bs_last_barrier] = {0};
|
||||
kmp_bar_pat_e __kmp_barrier_gather_pattern[bs_last_barrier] = {bp_linear_bar};
|
||||
kmp_bar_pat_e __kmp_barrier_release_pattern[bs_last_barrier] = {bp_linear_bar};
|
||||
char const *__kmp_barrier_branch_bit_env_name[bs_last_barrier] = {
|
||||
"KMP_PLAIN_BARRIER", "KMP_FORKJOIN_BARRIER"
|
||||
#if KMP_FAST_REDUCTION_BARRIER
|
||||
,
|
||||
"KMP_REDUCTION_BARRIER"
|
||||
#endif // KMP_FAST_REDUCTION_BARRIER
|
||||
};
|
||||
char const *__kmp_barrier_pattern_env_name[bs_last_barrier] = {
|
||||
"KMP_PLAIN_BARRIER_PATTERN", "KMP_FORKJOIN_BARRIER_PATTERN"
|
||||
#if KMP_FAST_REDUCTION_BARRIER
|
||||
,
|
||||
"KMP_REDUCTION_BARRIER_PATTERN"
|
||||
#endif // KMP_FAST_REDUCTION_BARRIER
|
||||
};
|
||||
char const *__kmp_barrier_type_name[bs_last_barrier] = {"plain", "forkjoin"
|
||||
#if KMP_FAST_REDUCTION_BARRIER
|
||||
,
|
||||
"reduction"
|
||||
#endif // KMP_FAST_REDUCTION_BARRIER
|
||||
};
|
||||
char const *__kmp_barrier_pattern_name[bp_last_bar] = {"linear", "tree",
|
||||
"hyper", "hierarchical"};
|
||||
|
||||
int __kmp_allThreadsSpecified = 0;
|
||||
size_t __kmp_align_alloc = CACHE_LINE;
|
||||
int __kmp_allThreadsSpecified = 0;
|
||||
size_t __kmp_align_alloc = CACHE_LINE;
|
||||
|
||||
|
||||
int __kmp_generate_warnings = kmp_warnings_low;
|
||||
int __kmp_reserve_warn = 0;
|
||||
int __kmp_xproc = 0;
|
||||
int __kmp_avail_proc = 0;
|
||||
size_t __kmp_sys_min_stksize = KMP_MIN_STKSIZE;
|
||||
int __kmp_sys_max_nth = KMP_MAX_NTH;
|
||||
int __kmp_max_nth = 0;
|
||||
int __kmp_threads_capacity = 0;
|
||||
int __kmp_dflt_team_nth = 0;
|
||||
int __kmp_dflt_team_nth_ub = 0;
|
||||
int __kmp_tp_capacity = 0;
|
||||
int __kmp_tp_cached = 0;
|
||||
int __kmp_dflt_nested = FALSE;
|
||||
int __kmp_dispatch_num_buffers = KMP_DFLT_DISP_NUM_BUFF;
|
||||
int __kmp_dflt_max_active_levels = KMP_MAX_ACTIVE_LEVELS_LIMIT; /* max_active_levels limit */
|
||||
int __kmp_generate_warnings = kmp_warnings_low;
|
||||
int __kmp_reserve_warn = 0;
|
||||
int __kmp_xproc = 0;
|
||||
int __kmp_avail_proc = 0;
|
||||
size_t __kmp_sys_min_stksize = KMP_MIN_STKSIZE;
|
||||
int __kmp_sys_max_nth = KMP_MAX_NTH;
|
||||
int __kmp_max_nth = 0;
|
||||
int __kmp_threads_capacity = 0;
|
||||
int __kmp_dflt_team_nth = 0;
|
||||
int __kmp_dflt_team_nth_ub = 0;
|
||||
int __kmp_tp_capacity = 0;
|
||||
int __kmp_tp_cached = 0;
|
||||
int __kmp_dflt_nested = FALSE;
|
||||
int __kmp_dispatch_num_buffers = KMP_DFLT_DISP_NUM_BUFF;
|
||||
int __kmp_dflt_max_active_levels =
|
||||
KMP_MAX_ACTIVE_LEVELS_LIMIT; /* max_active_levels limit */
|
||||
#if KMP_NESTED_HOT_TEAMS
|
||||
int __kmp_hot_teams_mode = 0; /* 0 - free extra threads when reduced */
|
||||
/* 1 - keep extra threads when reduced */
|
||||
int __kmp_hot_teams_max_level = 1; /* nesting level of hot teams */
|
||||
int __kmp_hot_teams_mode = 0; /* 0 - free extra threads when reduced */
|
||||
/* 1 - keep extra threads when reduced */
|
||||
int __kmp_hot_teams_max_level = 1; /* nesting level of hot teams */
|
||||
#endif
|
||||
enum library_type __kmp_library = library_none;
|
||||
enum sched_type __kmp_sched = kmp_sch_default; /* scheduling method for runtime scheduling */
|
||||
enum sched_type __kmp_static = kmp_sch_static_greedy; /* default static scheduling method */
|
||||
enum sched_type __kmp_guided = kmp_sch_guided_iterative_chunked; /* default guided scheduling method */
|
||||
enum sched_type __kmp_auto = kmp_sch_guided_analytical_chunked; /* default auto scheduling method */
|
||||
int __kmp_dflt_blocktime = KMP_DEFAULT_BLOCKTIME;
|
||||
enum sched_type __kmp_sched =
|
||||
kmp_sch_default; /* scheduling method for runtime scheduling */
|
||||
enum sched_type __kmp_static =
|
||||
kmp_sch_static_greedy; /* default static scheduling method */
|
||||
enum sched_type __kmp_guided =
|
||||
kmp_sch_guided_iterative_chunked; /* default guided scheduling method */
|
||||
enum sched_type __kmp_auto =
|
||||
kmp_sch_guided_analytical_chunked; /* default auto scheduling method */
|
||||
int __kmp_dflt_blocktime = KMP_DEFAULT_BLOCKTIME;
|
||||
#if KMP_USE_MONITOR
|
||||
int __kmp_monitor_wakeups = KMP_MIN_MONITOR_WAKEUPS;
|
||||
int __kmp_bt_intervals = KMP_INTERVALS_FROM_BLOCKTIME( KMP_DEFAULT_BLOCKTIME, KMP_MIN_MONITOR_WAKEUPS );
|
||||
int __kmp_monitor_wakeups = KMP_MIN_MONITOR_WAKEUPS;
|
||||
int __kmp_bt_intervals = KMP_INTERVALS_FROM_BLOCKTIME(KMP_DEFAULT_BLOCKTIME,
|
||||
KMP_MIN_MONITOR_WAKEUPS);
|
||||
#endif
|
||||
#ifdef KMP_ADJUST_BLOCKTIME
|
||||
int __kmp_zero_bt = FALSE;
|
||||
int __kmp_zero_bt = FALSE;
|
||||
#endif /* KMP_ADJUST_BLOCKTIME */
|
||||
#ifdef KMP_DFLT_NTH_CORES
|
||||
int __kmp_ncores = 0;
|
||||
int __kmp_ncores = 0;
|
||||
#endif
|
||||
int __kmp_chunk = 0;
|
||||
int __kmp_abort_delay = 0;
|
||||
int __kmp_chunk = 0;
|
||||
int __kmp_abort_delay = 0;
|
||||
#if KMP_OS_LINUX && defined(KMP_TDATA_GTID)
|
||||
int __kmp_gtid_mode = 3; /* use __declspec(thread) TLS to store gtid */
|
||||
int __kmp_adjust_gtid_mode = FALSE;
|
||||
int __kmp_gtid_mode = 3; /* use __declspec(thread) TLS to store gtid */
|
||||
int __kmp_adjust_gtid_mode = FALSE;
|
||||
#elif KMP_OS_WINDOWS
|
||||
int __kmp_gtid_mode = 2; /* use TLS functions to store gtid */
|
||||
int __kmp_adjust_gtid_mode = FALSE;
|
||||
int __kmp_gtid_mode = 2; /* use TLS functions to store gtid */
|
||||
int __kmp_adjust_gtid_mode = FALSE;
|
||||
#else
|
||||
int __kmp_gtid_mode = 0; /* select method to get gtid based on #threads */
|
||||
int __kmp_adjust_gtid_mode = TRUE;
|
||||
int __kmp_gtid_mode = 0; /* select method to get gtid based on #threads */
|
||||
int __kmp_adjust_gtid_mode = TRUE;
|
||||
#endif /* KMP_OS_LINUX && defined(KMP_TDATA_GTID) */
|
||||
#ifdef KMP_TDATA_GTID
|
||||
#if KMP_OS_WINDOWS
|
||||
__declspec(thread) int __kmp_gtid = KMP_GTID_DNE;
|
||||
#else
|
||||
__thread int __kmp_gtid = KMP_GTID_DNE;
|
||||
#endif /* KMP_OS_WINDOWS - workaround because Intel(R) Many Integrated Core compiler 20110316 doesn't accept __declspec */
|
||||
#endif /* KMP_OS_WINDOWS - workaround because Intel(R) Many Integrated Core \
|
||||
compiler 20110316 doesn't accept __declspec */
|
||||
#endif /* KMP_TDATA_GTID */
|
||||
int __kmp_tls_gtid_min = INT_MAX;
|
||||
int __kmp_foreign_tp = TRUE;
|
||||
int __kmp_tls_gtid_min = INT_MAX;
|
||||
int __kmp_foreign_tp = TRUE;
|
||||
#if KMP_ARCH_X86 || KMP_ARCH_X86_64
|
||||
int __kmp_inherit_fp_control = TRUE;
|
||||
kmp_int16 __kmp_init_x87_fpu_control_word = 0;
|
||||
kmp_uint32 __kmp_init_mxcsr = 0;
|
||||
int __kmp_inherit_fp_control = TRUE;
|
||||
kmp_int16 __kmp_init_x87_fpu_control_word = 0;
|
||||
kmp_uint32 __kmp_init_mxcsr = 0;
|
||||
#endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
|
||||
|
||||
#ifdef USE_LOAD_BALANCE
|
||||
double __kmp_load_balance_interval = 1.0;
|
||||
double __kmp_load_balance_interval = 1.0;
|
||||
#endif /* USE_LOAD_BALANCE */
|
||||
|
||||
kmp_nested_nthreads_t __kmp_nested_nth = { NULL, 0, 0 };
|
||||
kmp_nested_nthreads_t __kmp_nested_nth = {NULL, 0, 0};
|
||||
|
||||
#if KMP_USE_ADAPTIVE_LOCKS
|
||||
|
||||
kmp_adaptive_backoff_params_t __kmp_adaptive_backoff_params = { 1, 1024 }; // TODO: tune it!
|
||||
kmp_adaptive_backoff_params_t __kmp_adaptive_backoff_params = {
|
||||
1, 1024}; // TODO: tune it!
|
||||
|
||||
#if KMP_DEBUG_ADAPTIVE_LOCKS
|
||||
char * __kmp_speculative_statsfile = "-";
|
||||
char *__kmp_speculative_statsfile = "-";
|
||||
#endif
|
||||
|
||||
#endif // KMP_USE_ADAPTIVE_LOCKS
|
||||
|
||||
#if OMP_40_ENABLED
|
||||
int __kmp_display_env = FALSE;
|
||||
int __kmp_display_env_verbose = FALSE;
|
||||
int __kmp_omp_cancellation = FALSE;
|
||||
int __kmp_display_env = FALSE;
|
||||
int __kmp_display_env_verbose = FALSE;
|
||||
int __kmp_omp_cancellation = FALSE;
|
||||
#endif
|
||||
|
||||
/* map OMP 3.0 schedule types with our internal schedule types */
|
||||
enum sched_type __kmp_sch_map[ kmp_sched_upper - kmp_sched_lower_ext + kmp_sched_upper_std - kmp_sched_lower - 2 ] = {
|
||||
kmp_sch_static_chunked, // ==> kmp_sched_static = 1
|
||||
kmp_sch_dynamic_chunked, // ==> kmp_sched_dynamic = 2
|
||||
kmp_sch_guided_chunked, // ==> kmp_sched_guided = 3
|
||||
kmp_sch_auto, // ==> kmp_sched_auto = 4
|
||||
kmp_sch_trapezoidal // ==> kmp_sched_trapezoidal = 101
|
||||
// will likely not used, introduced here just to debug the code
|
||||
// of public intel extension schedules
|
||||
enum sched_type __kmp_sch_map[kmp_sched_upper - kmp_sched_lower_ext +
|
||||
kmp_sched_upper_std - kmp_sched_lower - 2] = {
|
||||
kmp_sch_static_chunked, // ==> kmp_sched_static = 1
|
||||
kmp_sch_dynamic_chunked, // ==> kmp_sched_dynamic = 2
|
||||
kmp_sch_guided_chunked, // ==> kmp_sched_guided = 3
|
||||
kmp_sch_auto, // ==> kmp_sched_auto = 4
|
||||
kmp_sch_trapezoidal // ==> kmp_sched_trapezoidal = 101
|
||||
// will likely not be used, introduced here just to debug the code
|
||||
// of public intel extension schedules
|
||||
};
|
||||
|
||||
#if KMP_OS_LINUX
|
||||
@@ -217,58 +238,61 @@ enum clock_function_type __kmp_clock_function;
|
||||
int __kmp_clock_function_param;
|
||||
#endif /* KMP_OS_LINUX */
|
||||
|
||||
#if KMP_ARCH_X86_64 && (KMP_OS_LINUX || KMP_OS_WINDOWS)
|
||||
#if KMP_MIC_SUPPORTED
|
||||
enum mic_type __kmp_mic_type = non_mic;
|
||||
#endif
|
||||
|
||||
#if KMP_AFFINITY_SUPPORTED
|
||||
|
||||
KMPAffinity* __kmp_affinity_dispatch = NULL;
|
||||
KMPAffinity *__kmp_affinity_dispatch = NULL;
|
||||
|
||||
# if KMP_USE_HWLOC
|
||||
#if KMP_USE_HWLOC
|
||||
int __kmp_hwloc_error = FALSE;
|
||||
hwloc_topology_t __kmp_hwloc_topology = NULL;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
# if KMP_OS_WINDOWS
|
||||
# if KMP_GROUP_AFFINITY
|
||||
#if KMP_OS_WINDOWS
|
||||
#if KMP_GROUP_AFFINITY
|
||||
int __kmp_num_proc_groups = 1;
|
||||
# endif /* KMP_GROUP_AFFINITY */
|
||||
#endif /* KMP_GROUP_AFFINITY */
|
||||
kmp_GetActiveProcessorCount_t __kmp_GetActiveProcessorCount = NULL;
|
||||
kmp_GetActiveProcessorGroupCount_t __kmp_GetActiveProcessorGroupCount = NULL;
|
||||
kmp_GetThreadGroupAffinity_t __kmp_GetThreadGroupAffinity = NULL;
|
||||
kmp_SetThreadGroupAffinity_t __kmp_SetThreadGroupAffinity = NULL;
|
||||
# endif /* KMP_OS_WINDOWS */
|
||||
#endif /* KMP_OS_WINDOWS */
|
||||
|
||||
size_t __kmp_affin_mask_size = 0;
|
||||
size_t __kmp_affin_mask_size = 0;
|
||||
enum affinity_type __kmp_affinity_type = affinity_default;
|
||||
enum affinity_gran __kmp_affinity_gran = affinity_gran_default;
|
||||
int __kmp_affinity_gran_levels = -1;
|
||||
int __kmp_affinity_gran_levels = -1;
|
||||
int __kmp_affinity_dups = TRUE;
|
||||
enum affinity_top_method __kmp_affinity_top_method = affinity_top_method_default;
|
||||
int __kmp_affinity_compact = 0;
|
||||
int __kmp_affinity_offset = 0;
|
||||
int __kmp_affinity_verbose = FALSE;
|
||||
int __kmp_affinity_warnings = TRUE;
|
||||
int __kmp_affinity_respect_mask = affinity_respect_mask_default;
|
||||
char * __kmp_affinity_proclist = NULL;
|
||||
enum affinity_top_method __kmp_affinity_top_method =
|
||||
affinity_top_method_default;
|
||||
int __kmp_affinity_compact = 0;
|
||||
int __kmp_affinity_offset = 0;
|
||||
int __kmp_affinity_verbose = FALSE;
|
||||
int __kmp_affinity_warnings = TRUE;
|
||||
int __kmp_affinity_respect_mask = affinity_respect_mask_default;
|
||||
char *__kmp_affinity_proclist = NULL;
|
||||
kmp_affin_mask_t *__kmp_affinity_masks = NULL;
|
||||
unsigned __kmp_affinity_num_masks = 0;
|
||||
unsigned __kmp_affinity_num_masks = 0;
|
||||
|
||||
char const * __kmp_cpuinfo_file = NULL;
|
||||
char const *__kmp_cpuinfo_file = NULL;
|
||||
|
||||
#endif /* KMP_AFFINITY_SUPPORTED */
|
||||
|
||||
#if OMP_40_ENABLED
|
||||
kmp_nested_proc_bind_t __kmp_nested_proc_bind = { NULL, 0, 0 };
|
||||
kmp_nested_proc_bind_t __kmp_nested_proc_bind = {NULL, 0, 0};
|
||||
int __kmp_affinity_num_places = 0;
|
||||
#endif
|
||||
|
||||
int __kmp_place_num_sockets = 0;
|
||||
int __kmp_place_socket_offset = 0;
|
||||
int __kmp_place_num_cores = 0;
|
||||
int __kmp_place_core_offset = 0;
|
||||
int __kmp_place_num_threads_per_core = 0;
|
||||
kmp_hws_item_t __kmp_hws_socket = {0, 0};
|
||||
kmp_hws_item_t __kmp_hws_node = {0, 0};
|
||||
kmp_hws_item_t __kmp_hws_tile = {0, 0};
|
||||
kmp_hws_item_t __kmp_hws_core = {0, 0};
|
||||
kmp_hws_item_t __kmp_hws_proc = {0, 0};
|
||||
int __kmp_hws_requested = 0;
|
||||
int __kmp_hws_abs_flag = 0; // absolute or per-item number requested
|
||||
|
||||
#if OMP_40_ENABLED
|
||||
kmp_int32 __kmp_default_device = 0;
|
||||
@@ -277,123 +301,132 @@ kmp_int32 __kmp_default_device = 0;
|
||||
kmp_tasking_mode_t __kmp_tasking_mode = tskm_task_teams;
|
||||
#if OMP_45_ENABLED
|
||||
kmp_int32 __kmp_max_task_priority = 0;
|
||||
kmp_uint64 __kmp_taskloop_min_tasks = 0;
|
||||
#endif
|
||||
|
||||
/* This check ensures that the compiler is passing the correct data type
|
||||
* for the flags formal parameter of the function kmpc_omp_task_alloc().
|
||||
* If the type is not a 4-byte type, then give an error message about
|
||||
* a non-positive length array pointing here. If that happens, the
|
||||
* kmp_tasking_flags_t structure must be redefined to have exactly 32 bits.
|
||||
*/
|
||||
KMP_BUILD_ASSERT( sizeof(kmp_tasking_flags_t) == 4 );
|
||||
/* This check ensures that the compiler is passing the correct data type for the
|
||||
flags formal parameter of the function kmpc_omp_task_alloc(). If the type is
|
||||
not a 4-byte type, then give an error message about a non-positive length
|
||||
array pointing here. If that happens, the kmp_tasking_flags_t structure must
|
||||
be redefined to have exactly 32 bits. */
|
||||
KMP_BUILD_ASSERT(sizeof(kmp_tasking_flags_t) == 4);
|
||||
|
||||
kmp_int32 __kmp_task_stealing_constraint = 1; /* Constrain task stealing by default */
|
||||
kmp_int32 __kmp_task_stealing_constraint =
|
||||
1; /* Constrain task stealing by default */
|
||||
|
||||
#ifdef DEBUG_SUSPEND
|
||||
int __kmp_suspend_count = 0;
|
||||
int __kmp_suspend_count = 0;
|
||||
#endif
|
||||
|
||||
int __kmp_settings = FALSE;
|
||||
int __kmp_duplicate_library_ok = 0;
|
||||
int __kmp_settings = FALSE;
|
||||
int __kmp_duplicate_library_ok = 0;
|
||||
#if USE_ITT_BUILD
|
||||
int __kmp_forkjoin_frames = 1;
|
||||
int __kmp_forkjoin_frames_mode = 3;
|
||||
int __kmp_forkjoin_frames = 1;
|
||||
int __kmp_forkjoin_frames_mode = 3;
|
||||
#endif
|
||||
PACKED_REDUCTION_METHOD_T __kmp_force_reduction_method = reduction_method_not_defined;
|
||||
int __kmp_determ_red = FALSE;
|
||||
PACKED_REDUCTION_METHOD_T __kmp_force_reduction_method =
|
||||
reduction_method_not_defined;
|
||||
int __kmp_determ_red = FALSE;
|
||||
|
||||
#ifdef KMP_DEBUG
|
||||
int kmp_a_debug = 0;
|
||||
int kmp_b_debug = 0;
|
||||
int kmp_c_debug = 0;
|
||||
int kmp_d_debug = 0;
|
||||
int kmp_e_debug = 0;
|
||||
int kmp_f_debug = 0;
|
||||
int kmp_diag = 0;
|
||||
int kmp_a_debug = 0;
|
||||
int kmp_b_debug = 0;
|
||||
int kmp_c_debug = 0;
|
||||
int kmp_d_debug = 0;
|
||||
int kmp_e_debug = 0;
|
||||
int kmp_f_debug = 0;
|
||||
int kmp_diag = 0;
|
||||
#endif
|
||||
|
||||
/* For debug information logging using rotating buffer */
|
||||
int __kmp_debug_buf = FALSE; /* TRUE means use buffer, FALSE means print to stderr */
|
||||
int __kmp_debug_buf_lines = KMP_DEBUG_BUF_LINES_INIT; /* Lines of debug stored in buffer */
|
||||
int __kmp_debug_buf_chars = KMP_DEBUG_BUF_CHARS_INIT; /* Characters allowed per line in buffer */
|
||||
int __kmp_debug_buf_atomic = FALSE; /* TRUE means use atomic update of buffer entry pointer */
|
||||
int __kmp_debug_buf =
|
||||
FALSE; /* TRUE means use buffer, FALSE means print to stderr */
|
||||
int __kmp_debug_buf_lines =
|
||||
KMP_DEBUG_BUF_LINES_INIT; /* Lines of debug stored in buffer */
|
||||
int __kmp_debug_buf_chars =
|
||||
KMP_DEBUG_BUF_CHARS_INIT; /* Characters allowed per line in buffer */
|
||||
int __kmp_debug_buf_atomic =
|
||||
FALSE; /* TRUE means use atomic update of buffer entry pointer */
|
||||
|
||||
char *__kmp_debug_buffer = NULL; /* Debug buffer itself */
|
||||
int __kmp_debug_count = 0; /* Counter for number of lines printed in buffer so far */
|
||||
int __kmp_debug_buf_warn_chars = 0; /* Keep track of char increase recommended in warnings */
|
||||
char *__kmp_debug_buffer = NULL; /* Debug buffer itself */
|
||||
int __kmp_debug_count =
|
||||
0; /* Counter for number of lines printed in buffer so far */
|
||||
int __kmp_debug_buf_warn_chars =
|
||||
0; /* Keep track of char increase recommended in warnings */
|
||||
/* end rotating debug buffer */
|
||||
|
||||
#ifdef KMP_DEBUG
|
||||
int __kmp_par_range; /* +1 => only go par for constructs in range */
|
||||
/* -1 => only go par for constructs outside range */
|
||||
char __kmp_par_range_routine[KMP_PAR_RANGE_ROUTINE_LEN] = { '\0' };
|
||||
char __kmp_par_range_filename[KMP_PAR_RANGE_FILENAME_LEN] = { '\0' };
|
||||
int __kmp_par_range_lb = 0;
|
||||
int __kmp_par_range_ub = INT_MAX;
|
||||
int __kmp_par_range; /* +1 => only go par for constructs in range */
|
||||
/* -1 => only go par for constructs outside range */
|
||||
char __kmp_par_range_routine[KMP_PAR_RANGE_ROUTINE_LEN] = {'\0'};
|
||||
char __kmp_par_range_filename[KMP_PAR_RANGE_FILENAME_LEN] = {'\0'};
|
||||
int __kmp_par_range_lb = 0;
|
||||
int __kmp_par_range_ub = INT_MAX;
|
||||
#endif /* KMP_DEBUG */
|
||||
|
||||
/* For printing out dynamic storage map for threads and teams */
|
||||
int __kmp_storage_map = FALSE; /* True means print storage map for threads and teams */
|
||||
int __kmp_storage_map_verbose = FALSE; /* True means storage map includes placement info */
|
||||
int __kmp_storage_map_verbose_specified = FALSE;
|
||||
/* Initialize the library data structures when we fork a child process, defaults to TRUE */
|
||||
int __kmp_need_register_atfork = TRUE; /* At initialization, call pthread_atfork to install fork handler */
|
||||
int __kmp_need_register_atfork_specified = TRUE;
|
||||
int __kmp_storage_map =
|
||||
FALSE; /* True means print storage map for threads and teams */
|
||||
int __kmp_storage_map_verbose =
|
||||
FALSE; /* True means storage map includes placement info */
|
||||
int __kmp_storage_map_verbose_specified = FALSE;
|
||||
/* Initialize the library data structures when we fork a child process, defaults
|
||||
* to TRUE */
|
||||
int __kmp_need_register_atfork =
|
||||
TRUE; /* At initialization, call pthread_atfork to install fork handler */
|
||||
int __kmp_need_register_atfork_specified = TRUE;
|
||||
|
||||
int __kmp_env_chunk = FALSE; /* KMP_CHUNK specified? */
|
||||
int __kmp_env_stksize = FALSE; /* KMP_STACKSIZE specified? */
|
||||
int __kmp_env_omp_stksize = FALSE; /* OMP_STACKSIZE specified? */
|
||||
int __kmp_env_all_threads = FALSE;/* KMP_ALL_THREADS or KMP_MAX_THREADS specified? */
|
||||
int __kmp_env_omp_all_threads = FALSE;/* OMP_THREAD_LIMIT specified? */
|
||||
int __kmp_env_blocktime = FALSE; /* KMP_BLOCKTIME specified? */
|
||||
int __kmp_env_checks = FALSE; /* KMP_CHECKS specified? */
|
||||
int __kmp_env_consistency_check = FALSE; /* KMP_CONSISTENCY_CHECK specified? */
|
||||
int __kmp_env_chunk = FALSE; /* KMP_CHUNK specified? */
|
||||
int __kmp_env_stksize = FALSE; /* KMP_STACKSIZE specified? */
|
||||
int __kmp_env_omp_stksize = FALSE; /* OMP_STACKSIZE specified? */
|
||||
int __kmp_env_all_threads =
|
||||
FALSE; /* KMP_ALL_THREADS or KMP_MAX_THREADS specified? */
|
||||
int __kmp_env_omp_all_threads = FALSE; /* OMP_THREAD_LIMIT specified? */
|
||||
int __kmp_env_blocktime = FALSE; /* KMP_BLOCKTIME specified? */
|
||||
int __kmp_env_checks = FALSE; /* KMP_CHECKS specified? */
|
||||
int __kmp_env_consistency_check = FALSE; /* KMP_CONSISTENCY_CHECK specified? */
|
||||
|
||||
kmp_uint32 __kmp_yield_init = KMP_INIT_WAIT;
|
||||
kmp_uint32 __kmp_yield_next = KMP_NEXT_WAIT;
|
||||
|
||||
#if KMP_USE_MONITOR
|
||||
kmp_uint32 __kmp_yielding_on = 1;
|
||||
#endif
|
||||
#if KMP_OS_CNK
|
||||
kmp_uint32 __kmp_yield_cycle = 0;
|
||||
#else
|
||||
kmp_uint32 __kmp_yield_cycle = 1; /* Yield-cycle is on by default */
|
||||
kmp_uint32 __kmp_yield_cycle = 1; /* Yield-cycle is on by default */
|
||||
#endif
|
||||
kmp_int32 __kmp_yield_on_count = 10; /* By default, yielding is on for 10 monitor periods. */
|
||||
kmp_int32 __kmp_yield_off_count = 1; /* By default, yielding is off for 1 monitor periods. */
|
||||
#endif
|
||||
/* ----------------------------------------------------- */
|
||||
|
||||
kmp_int32 __kmp_yield_on_count =
|
||||
10; /* By default, yielding is on for 10 monitor periods. */
|
||||
kmp_int32 __kmp_yield_off_count =
|
||||
1; /* By default, yielding is off for 1 monitor periods. */
|
||||
|
||||
/* ------------------------------------------------------ */
|
||||
/* STATE mostly syncronized with global lock */
|
||||
/* data written to rarely by masters, read often by workers */
|
||||
/*
|
||||
* SHALL WE EDIT THE COMMENT BELOW IN SOME WAY?
|
||||
* TODO: None of this global padding stuff works consistently because
|
||||
* the order of declaration is not necessarily correlated to storage order.
|
||||
* To fix this, all the important globals must be put in a big structure
|
||||
* instead.
|
||||
*/
|
||||
/* TODO: None of this global padding stuff works consistently because the order
|
||||
of declaration is not necessarily correlated to storage order. To fix this,
|
||||
all the important globals must be put in a big structure instead. */
|
||||
KMP_ALIGN_CACHE
|
||||
kmp_info_t **__kmp_threads = NULL;
|
||||
kmp_root_t **__kmp_root = NULL;
|
||||
kmp_info_t **__kmp_threads = NULL;
|
||||
kmp_root_t **__kmp_root = NULL;
|
||||
|
||||
/* data read/written to often by masters */
|
||||
KMP_ALIGN_CACHE
|
||||
volatile int __kmp_nth = 0;
|
||||
volatile int __kmp_all_nth = 0;
|
||||
int __kmp_thread_pool_nth = 0;
|
||||
volatile kmp_info_t *__kmp_thread_pool = NULL;
|
||||
volatile kmp_team_t *__kmp_team_pool = NULL;
|
||||
volatile int __kmp_nth = 0;
|
||||
volatile int __kmp_all_nth = 0;
|
||||
int __kmp_thread_pool_nth = 0;
|
||||
volatile kmp_info_t *__kmp_thread_pool = NULL;
|
||||
volatile kmp_team_t *__kmp_team_pool = NULL;
|
||||
|
||||
KMP_ALIGN_CACHE
|
||||
volatile int __kmp_thread_pool_active_nth = 0;
|
||||
volatile int __kmp_thread_pool_active_nth = 0;
|
||||
|
||||
/* -------------------------------------------------
|
||||
* GLOBAL/ROOT STATE */
|
||||
KMP_ALIGN_CACHE
|
||||
kmp_global_t __kmp_global = {{ 0 }};
|
||||
kmp_global_t __kmp_global = {{0}};
|
||||
|
||||
/* ----------------------------------------------- */
|
||||
/* GLOBAL SYNCHRONIZATION LOCKS */
|
||||
@@ -404,66 +437,72 @@ kmp_global_t __kmp_global = {{ 0 }};
|
||||
* false sharing if the alignment is not large enough for these locks */
|
||||
KMP_ALIGN_CACHE_INTERNODE
|
||||
|
||||
kmp_bootstrap_lock_t __kmp_initz_lock = KMP_BOOTSTRAP_LOCK_INITIALIZER( __kmp_initz_lock ); /* Control initializations */
|
||||
kmp_bootstrap_lock_t __kmp_initz_lock = KMP_BOOTSTRAP_LOCK_INITIALIZER(
|
||||
__kmp_initz_lock); /* Control initializations */
|
||||
KMP_ALIGN_CACHE_INTERNODE
|
||||
kmp_bootstrap_lock_t __kmp_forkjoin_lock; /* control fork/join access */
|
||||
KMP_ALIGN_CACHE_INTERNODE
|
||||
kmp_bootstrap_lock_t __kmp_exit_lock; /* exit() is not always thread-safe */
|
||||
kmp_bootstrap_lock_t __kmp_exit_lock; /* exit() is not always thread-safe */
|
||||
#if KMP_USE_MONITOR
|
||||
KMP_ALIGN_CACHE_INTERNODE
|
||||
kmp_bootstrap_lock_t __kmp_monitor_lock; /* control monitor thread creation */
|
||||
#endif
|
||||
/* used for the hack to allow threadprivate cache and __kmp_threads expansion
|
||||
to co-exist */
|
||||
KMP_ALIGN_CACHE_INTERNODE
|
||||
kmp_bootstrap_lock_t __kmp_tp_cached_lock; /* used for the hack to allow threadprivate cache and __kmp_threads expansion to co-exist */
|
||||
kmp_bootstrap_lock_t __kmp_tp_cached_lock;
|
||||
|
||||
KMP_ALIGN_CACHE_INTERNODE
|
||||
kmp_lock_t __kmp_global_lock; /* Control OS/global access */
|
||||
kmp_lock_t __kmp_global_lock; /* Control OS/global access */
|
||||
KMP_ALIGN_CACHE_INTERNODE
|
||||
kmp_queuing_lock_t __kmp_dispatch_lock; /* Control dispatch access */
|
||||
kmp_queuing_lock_t __kmp_dispatch_lock; /* Control dispatch access */
|
||||
KMP_ALIGN_CACHE_INTERNODE
|
||||
kmp_lock_t __kmp_debug_lock; /* Control I/O access for KMP_DEBUG */
|
||||
kmp_lock_t __kmp_debug_lock; /* Control I/O access for KMP_DEBUG */
|
||||
#else
|
||||
KMP_ALIGN_CACHE
|
||||
|
||||
kmp_bootstrap_lock_t __kmp_initz_lock = KMP_BOOTSTRAP_LOCK_INITIALIZER( __kmp_initz_lock ); /* Control initializations */
|
||||
kmp_bootstrap_lock_t __kmp_initz_lock = KMP_BOOTSTRAP_LOCK_INITIALIZER(
|
||||
__kmp_initz_lock); /* Control initializations */
|
||||
kmp_bootstrap_lock_t __kmp_forkjoin_lock; /* control fork/join access */
|
||||
kmp_bootstrap_lock_t __kmp_exit_lock; /* exit() is not always thread-safe */
|
||||
kmp_bootstrap_lock_t __kmp_exit_lock; /* exit() is not always thread-safe */
|
||||
#if KMP_USE_MONITOR
|
||||
kmp_bootstrap_lock_t __kmp_monitor_lock; /* control monitor thread creation */
|
||||
#endif
|
||||
kmp_bootstrap_lock_t __kmp_tp_cached_lock; /* used for the hack to allow threadprivate cache and __kmp_threads expansion to co-exist */
|
||||
/* used for the hack to allow threadprivate cache and __kmp_threads expansion
|
||||
to co-exist */
|
||||
kmp_bootstrap_lock_t __kmp_tp_cached_lock;
|
||||
|
||||
KMP_ALIGN(128)
|
||||
kmp_lock_t __kmp_global_lock; /* Control OS/global access */
|
||||
kmp_lock_t __kmp_global_lock; /* Control OS/global access */
|
||||
KMP_ALIGN(128)
|
||||
kmp_queuing_lock_t __kmp_dispatch_lock; /* Control dispatch access */
|
||||
kmp_queuing_lock_t __kmp_dispatch_lock; /* Control dispatch access */
|
||||
KMP_ALIGN(128)
|
||||
kmp_lock_t __kmp_debug_lock; /* Control I/O access for KMP_DEBUG */
|
||||
kmp_lock_t __kmp_debug_lock; /* Control I/O access for KMP_DEBUG */
|
||||
#endif
|
||||
|
||||
/* ----------------------------------------------- */
|
||||
|
||||
#if KMP_HANDLE_SIGNALS
|
||||
/*
|
||||
Signal handling is disabled by default, because it confuses users: In case of sigsegv
|
||||
(or other trouble) in user code signal handler catches the signal, which then "appears" in
|
||||
the monitor thread (when the monitor executes raise() function). Users see signal in the
|
||||
monitor thread and blame OpenMP RTL.
|
||||
/* Signal handling is disabled by default, because it confuses users: In case of
|
||||
sigsegv (or other trouble) in user code signal handler catches the signal,
|
||||
which then "appears" in the monitor thread (when the monitor executes raise()
|
||||
function). Users see signal in the monitor thread and blame OpenMP RTL.
|
||||
|
||||
Grant said signal handling required on some older OSes (Irix?) supported by KAI, because
|
||||
bad applications hung but not aborted. Currently it is not a problem for Linux* OS, OS X* and
|
||||
Windows* OS.
|
||||
Grant said signal handling required on some older OSes (Irix?) supported by
|
||||
KAI, because bad applications hung but not aborted. Currently it is not a
|
||||
problem for Linux* OS, OS X* and Windows* OS.
|
||||
|
||||
Grant: Found new hangs for EL4, EL5, and a Fedora Core machine. So I'm putting
|
||||
the default back for now to see if that fixes hangs on those machines.
|
||||
Grant: Found new hangs for EL4, EL5, and a Fedora Core machine. So I'm
|
||||
putting the default back for now to see if that fixes hangs on those
|
||||
machines.
|
||||
|
||||
2010-04013 Lev: It was a bug in Fortran RTL. Fortran RTL prints a kind of stack backtrace
|
||||
when program is aborting, but the code is not signal-safe. When multiple signals raised at
|
||||
the same time (which occurs in dynamic negative tests because all the worker threads detects
|
||||
the same error), Fortran RTL may hang. The bug finally fixed in Fortran RTL library provided
|
||||
by Steve R., and will be available soon.
|
||||
*/
|
||||
int __kmp_handle_signals = FALSE;
|
||||
2010-04013 Lev: It was a bug in Fortran RTL. Fortran RTL prints a kind of
|
||||
stack backtrace when program is aborting, but the code is not signal-safe.
|
||||
When multiple signals raised at the same time (which occurs in dynamic
|
||||
negative tests because all the worker threads detects the same error),
|
||||
Fortran RTL may hang. The bug finally fixed in Fortran RTL library provided
|
||||
by Steve R., and will be available soon. */
|
||||
int __kmp_handle_signals = FALSE;
|
||||
#endif
|
||||
|
||||
/* ----------------------------------------------- */
|
||||
@@ -471,27 +510,22 @@ kmp_lock_t __kmp_debug_lock; /* Control I/O access for KMP_DEBUG */
|
||||
kmp_key_t __kmp_tv_key = 0;
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
#ifdef DEBUG_SUSPEND
|
||||
int
|
||||
get_suspend_count_( void ) {
|
||||
int count = __kmp_suspend_count;
|
||||
__kmp_suspend_count = 0;
|
||||
return count;
|
||||
}
|
||||
void
|
||||
set_suspend_count_( int * value ) {
|
||||
__kmp_suspend_count = *value;
|
||||
int get_suspend_count_(void) {
|
||||
int count = __kmp_suspend_count;
|
||||
__kmp_suspend_count = 0;
|
||||
return count;
|
||||
}
|
||||
void set_suspend_count_(int *value) { __kmp_suspend_count = *value; }
|
||||
#endif
|
||||
|
||||
// Symbols for MS mutual detection.
|
||||
int _You_must_link_with_exactly_one_OpenMP_library = 1;
|
||||
int _You_must_link_with_Intel_OpenMP_library = 1;
|
||||
#if KMP_OS_WINDOWS && ( KMP_VERSION_MAJOR > 4 )
|
||||
int _You_must_link_with_Microsoft_OpenMP_library = 1;
|
||||
int _You_must_link_with_Intel_OpenMP_library = 1;
|
||||
#if KMP_OS_WINDOWS && (KMP_VERSION_MAJOR > 4)
|
||||
int _You_must_link_with_Microsoft_OpenMP_library = 1;
|
||||
#endif
|
||||
|
||||
// end of file //
|
||||
|
||||
+932
-1046
File diff suppressed because it is too large
Load Diff
+674
-803
File diff suppressed because it is too large
Load Diff
+110
-119
@@ -19,173 +19,164 @@
|
||||
#include "kmp_str.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
/*
|
||||
kmp_i18n_id.inc defines kmp_i18n_id_t type. It is an enumeration with identifiers of all the
|
||||
messages in the catalog. There is one special identifier: kmp_i18n_null, which denotes absence
|
||||
of message.
|
||||
*/
|
||||
/* kmp_i18n_id.inc defines kmp_i18n_id_t type. It is an enumeration with
|
||||
identifiers of all the messages in the catalog. There is one special
|
||||
identifier: kmp_i18n_null, which denotes absence of message. */
|
||||
#include "kmp_i18n_id.inc" // Generated file. Do not edit it manually.
|
||||
|
||||
/*
|
||||
Low-level functions handling message catalog. __kmp_i18n_open() opens message catalog,
|
||||
__kmp_i18n_closes() it. Explicit opening is not required: if message catalog is not yet open,
|
||||
__kmp_i18n_catgets() will open it implicitly. However, catalog should be explicitly closed,
|
||||
otherwise resources (mamory, handles) may leak.
|
||||
/* Low-level functions handling message catalog. __kmp_i18n_open() opens message
|
||||
catalog, __kmp_i18n_closes() it. Explicit opening is not required: if message
|
||||
catalog is not yet open, __kmp_i18n_catgets() will open it implicitly.
|
||||
However, catalog should be explicitly closed, otherwise resources (mamory,
|
||||
handles) may leak.
|
||||
|
||||
__kmp_i18n_catgets() returns read-only string. It should not be freed.
|
||||
__kmp_i18n_catgets() returns read-only string. It should not be freed.
|
||||
|
||||
KMP_I18N_STR macro simplifies acces to strings in message catalog a bit. Following two lines are
|
||||
equivalent:
|
||||
KMP_I18N_STR macro simplifies acces to strings in message catalog a bit.
|
||||
Following two lines are equivalent:
|
||||
|
||||
__kmp_i18n_catgets( kmp_i18n_str_Warning )
|
||||
KMP_I18N_STR( Warning )
|
||||
__kmp_i18n_catgets( kmp_i18n_str_Warning )
|
||||
KMP_I18N_STR( Warning )
|
||||
*/
|
||||
|
||||
void __kmp_i18n_catopen();
|
||||
void __kmp_i18n_catclose();
|
||||
char const * __kmp_i18n_catgets( kmp_i18n_id_t id );
|
||||
void __kmp_i18n_catopen();
|
||||
void __kmp_i18n_catclose();
|
||||
char const *__kmp_i18n_catgets(kmp_i18n_id_t id);
|
||||
|
||||
#define KMP_I18N_STR( id ) __kmp_i18n_catgets( kmp_i18n_str_ ## id )
|
||||
#define KMP_I18N_STR(id) __kmp_i18n_catgets(kmp_i18n_str_##id)
|
||||
|
||||
/* High-level interface for printing strings targeted to the user.
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------------------------
|
||||
All the strings are divided into 3 types:
|
||||
* messages,
|
||||
* hints,
|
||||
* system errors.
|
||||
|
||||
High-level interface for printing strings targeted to the user.
|
||||
There are 3 kind of message severities:
|
||||
* informational messages,
|
||||
* warnings (non-fatal errors),
|
||||
* fatal errors.
|
||||
|
||||
All the strings are divided into 3 types:
|
||||
For example:
|
||||
OMP: Warning #2: Cannot open message catalog "libguide.cat": (1)
|
||||
OMP: System error #2: No such file or directory (2)
|
||||
OMP: Hint: Please check NLSPATH environment variable. (3)
|
||||
OMP: Info #3: Default messages will be used. (4)
|
||||
|
||||
* messages,
|
||||
* hints,
|
||||
* system errors.
|
||||
|
||||
There are 3 kind of message severities:
|
||||
|
||||
* informational messages,
|
||||
* warnings (non-fatal errors),
|
||||
* fatal errors.
|
||||
|
||||
For example:
|
||||
|
||||
OMP: Warning #2: Cannot open message catalog "libguide.cat": (1)
|
||||
OMP: System error #2: No such file or directory (2)
|
||||
OMP: Hint: Please check NLSPATH environment variable. (3)
|
||||
OMP: Info #3: Default messages will be used. (4)
|
||||
|
||||
where
|
||||
|
||||
(1) is a message of warning severity,
|
||||
(2) is a system error caused the previous warning,
|
||||
(3) is a hint for the user how to fix the problem,
|
||||
(4) is a message of informational severity.
|
||||
where
|
||||
(1) is a message of warning severity,
|
||||
(2) is a system error caused the previous warning,
|
||||
(3) is a hint for the user how to fix the problem,
|
||||
(4) is a message of informational severity.
|
||||
|
||||
Usage in complex cases (message is accompanied with hints and system errors):
|
||||
|
||||
int error = errno; // We need save errno immediately, because it may be changed.
|
||||
__kmp_msg(
|
||||
kmp_ms_warning, // Severity
|
||||
KMP_MSG( CantOpenMessageCatalog, name ), // Primary message
|
||||
KMP_ERR( error ), // System error
|
||||
KMP_HNT( CheckNLSPATH ), // Hint
|
||||
__kmp_msg_null // Variadic argument list finisher
|
||||
);
|
||||
int error = errno; // We need save errno immediately, because it may
|
||||
// be changed.
|
||||
__kmp_msg(
|
||||
kmp_ms_warning, // Severity
|
||||
KMP_MSG( CantOpenMessageCatalog, name ), // Primary message
|
||||
KMP_ERR( error ), // System error
|
||||
KMP_HNT( CheckNLSPATH ), // Hint
|
||||
__kmp_msg_null // Variadic argument list finisher
|
||||
);
|
||||
|
||||
Usage in simple cases (just a message, no system errors or hints):
|
||||
|
||||
KMP_INFORM( WillUseDefaultMessages );
|
||||
KMP_WARNING( CantOpenMessageCatalog, name );
|
||||
KMP_FATAL( StackOverlap );
|
||||
KMP_SYSFAIL( "pthread_create", status );
|
||||
KMP_CHECK_SYSFAIL( "pthread_create", status );
|
||||
KMP_CHECK_SYSFAIL_ERRNO( "gettimeofday", status );
|
||||
|
||||
------------------------------------------------------------------------------------------------
|
||||
Usage in simple cases (just a message, no system errors or hints):
|
||||
KMP_INFORM( WillUseDefaultMessages );
|
||||
KMP_WARNING( CantOpenMessageCatalog, name );
|
||||
KMP_FATAL( StackOverlap );
|
||||
KMP_SYSFAIL( "pthread_create", status );
|
||||
KMP_CHECK_SYSFAIL( "pthread_create", status );
|
||||
KMP_CHECK_SYSFAIL_ERRNO( "gettimeofday", status );
|
||||
*/
|
||||
|
||||
enum kmp_msg_type {
|
||||
kmp_mt_dummy = 0, // Special type for internal purposes.
|
||||
kmp_mt_mesg = 4, // Primary OpenMP message, could be information, warning, or fatal.
|
||||
kmp_mt_hint = 5, // Hint to the user.
|
||||
kmp_mt_syserr = -1 // System error message.
|
||||
kmp_mt_dummy = 0, // Special type for internal purposes.
|
||||
kmp_mt_mesg =
|
||||
4, // Primary OpenMP message, could be information, warning, or fatal.
|
||||
kmp_mt_hint = 5, // Hint to the user.
|
||||
kmp_mt_syserr = -1 // System error message.
|
||||
}; // enum kmp_msg_type
|
||||
typedef enum kmp_msg_type kmp_msg_type_t;
|
||||
typedef enum kmp_msg_type kmp_msg_type_t;
|
||||
|
||||
struct kmp_msg {
|
||||
kmp_msg_type_t type;
|
||||
int num;
|
||||
char const * str;
|
||||
int len;
|
||||
kmp_msg_type_t type;
|
||||
int num;
|
||||
char const *str;
|
||||
int len;
|
||||
}; // struct kmp_message
|
||||
typedef struct kmp_msg kmp_msg_t;
|
||||
typedef struct kmp_msg kmp_msg_t;
|
||||
|
||||
// Two special messages.
|
||||
extern kmp_msg_t __kmp_msg_empty; // Can be used in place where message is required syntactically.
|
||||
extern kmp_msg_t __kmp_msg_null; // Denotes the end of variadic list of arguments.
|
||||
extern kmp_msg_t __kmp_msg_empty; // Can be used in place where message is
|
||||
// required syntactically.
|
||||
extern kmp_msg_t
|
||||
__kmp_msg_null; // Denotes the end of variadic list of arguments.
|
||||
|
||||
// Helper functions. Creates messages either from message catalog or from system. Note: these
|
||||
// functions allocate memory. You should pass created messages to __kmp_msg() function, it will
|
||||
// print messages and destroy them.
|
||||
kmp_msg_t __kmp_msg_format( unsigned id_arg, ... );
|
||||
kmp_msg_t __kmp_msg_error_code( int code );
|
||||
kmp_msg_t __kmp_msg_error_mesg( char const * mesg );
|
||||
// Helper functions. Creates messages either from message catalog or from
|
||||
// system. Note: these functions allocate memory. You should pass created
|
||||
// messages to __kmp_msg() function, it will print messages and destroy them.
|
||||
kmp_msg_t __kmp_msg_format(unsigned id_arg, ...);
|
||||
kmp_msg_t __kmp_msg_error_code(int code);
|
||||
kmp_msg_t __kmp_msg_error_mesg(char const *mesg);
|
||||
|
||||
// Helper macros to make calls shorter.
|
||||
#define KMP_MSG( ... ) __kmp_msg_format( kmp_i18n_msg_ ## __VA_ARGS__ )
|
||||
#define KMP_HNT( ... ) __kmp_msg_format( kmp_i18n_hnt_ ## __VA_ARGS__ )
|
||||
#define KMP_SYSERRCODE( code ) __kmp_msg_error_code( code )
|
||||
#define KMP_SYSERRMESG( mesg ) __kmp_msg_error_mesg( mesg )
|
||||
#define KMP_MSG(...) __kmp_msg_format(kmp_i18n_msg_##__VA_ARGS__)
|
||||
#define KMP_HNT(...) __kmp_msg_format(kmp_i18n_hnt_##__VA_ARGS__)
|
||||
#define KMP_SYSERRCODE(code) __kmp_msg_error_code(code)
|
||||
#define KMP_SYSERRMESG(mesg) __kmp_msg_error_mesg(mesg)
|
||||
#define KMP_ERR KMP_SYSERRCODE
|
||||
|
||||
// Message severity.
|
||||
enum kmp_msg_severity {
|
||||
kmp_ms_inform, // Just information for the user.
|
||||
kmp_ms_warning, // Non-fatal error, execution continues.
|
||||
kmp_ms_fatal // Fatal error, program aborts.
|
||||
kmp_ms_inform, // Just information for the user.
|
||||
kmp_ms_warning, // Non-fatal error, execution continues.
|
||||
kmp_ms_fatal // Fatal error, program aborts.
|
||||
}; // enum kmp_msg_severity
|
||||
typedef enum kmp_msg_severity kmp_msg_severity_t;
|
||||
typedef enum kmp_msg_severity kmp_msg_severity_t;
|
||||
|
||||
// Primary function for printing messages for the user. The first message is mandatory. Any number
|
||||
// of system errors and hints may be specified. Argument list must be finished with __kmp_msg_null.
|
||||
void __kmp_msg( kmp_msg_severity_t severity, kmp_msg_t message, ... );
|
||||
// Primary function for printing messages for the user. The first message is
|
||||
// mandatory. Any number of system errors and hints may be specified. Argument
|
||||
// list must be finished with __kmp_msg_null.
|
||||
void __kmp_msg(kmp_msg_severity_t severity, kmp_msg_t message, ...);
|
||||
|
||||
// Helper macros to make calls shorter in simple cases.
|
||||
#define KMP_INFORM( ... ) __kmp_msg( kmp_ms_inform, KMP_MSG( __VA_ARGS__ ), __kmp_msg_null )
|
||||
#define KMP_WARNING( ... ) __kmp_msg( kmp_ms_warning, KMP_MSG( __VA_ARGS__ ), __kmp_msg_null )
|
||||
#define KMP_FATAL( ... ) __kmp_msg( kmp_ms_fatal, KMP_MSG( __VA_ARGS__ ), __kmp_msg_null )
|
||||
#define KMP_SYSFAIL( func, error ) \
|
||||
__kmp_msg( \
|
||||
kmp_ms_fatal, \
|
||||
KMP_MSG( FunctionError, func ), \
|
||||
KMP_SYSERRCODE( error ), \
|
||||
__kmp_msg_null \
|
||||
)
|
||||
#define KMP_INFORM(...) \
|
||||
__kmp_msg(kmp_ms_inform, KMP_MSG(__VA_ARGS__), __kmp_msg_null)
|
||||
#define KMP_WARNING(...) \
|
||||
__kmp_msg(kmp_ms_warning, KMP_MSG(__VA_ARGS__), __kmp_msg_null)
|
||||
#define KMP_FATAL(...) \
|
||||
__kmp_msg(kmp_ms_fatal, KMP_MSG(__VA_ARGS__), __kmp_msg_null)
|
||||
#define KMP_SYSFAIL(func, error) \
|
||||
__kmp_msg(kmp_ms_fatal, KMP_MSG(FunctionError, func), KMP_SYSERRCODE(error), \
|
||||
__kmp_msg_null)
|
||||
|
||||
// Check error, if not zero, generate fatal error message.
|
||||
#define KMP_CHECK_SYSFAIL( func, error ) \
|
||||
{ \
|
||||
if ( error ) { \
|
||||
KMP_SYSFAIL( func, error ); \
|
||||
}; \
|
||||
}
|
||||
#define KMP_CHECK_SYSFAIL(func, error) \
|
||||
{ \
|
||||
if (error) { \
|
||||
KMP_SYSFAIL(func, error); \
|
||||
}; \
|
||||
}
|
||||
|
||||
// Check status, if not zero, generate fatal error message using errno.
|
||||
#define KMP_CHECK_SYSFAIL_ERRNO( func, status ) \
|
||||
{ \
|
||||
if ( status != 0 ) { \
|
||||
int error = errno; \
|
||||
KMP_SYSFAIL( func, error ); \
|
||||
}; \
|
||||
}
|
||||
#define KMP_CHECK_SYSFAIL_ERRNO(func, status) \
|
||||
{ \
|
||||
if (status != 0) { \
|
||||
int error = errno; \
|
||||
KMP_SYSFAIL(func, error); \
|
||||
}; \
|
||||
}
|
||||
|
||||
#ifdef KMP_DEBUG
|
||||
void __kmp_i18n_dump_catalog( kmp_str_buf_t * buffer );
|
||||
void __kmp_i18n_dump_catalog(kmp_str_buf_t *buffer);
|
||||
#endif // KMP_DEBUG
|
||||
|
||||
#ifdef __cplusplus
|
||||
}; // extern "C"
|
||||
}; // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // KMP_I18N_H
|
||||
|
||||
@@ -13,26 +13,20 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------------------------
|
||||
Object generated from this source file is linked to Windows* OS DLL import library (libompmd.lib)
|
||||
only! It is not a part of regular static or dynamic OpenMP RTL. Any code that just needs to go
|
||||
in the libompmd.lib (but not in libompmt.lib and libompmd.dll) should be placed in this
|
||||
file.
|
||||
------------------------------------------------------------------------------------------------
|
||||
*/
|
||||
/* Object generated from this source file is linked to Windows* OS DLL import
|
||||
library (libompmd.lib) only! It is not a part of regular static or dynamic
|
||||
OpenMP RTL. Any code that just needs to go in the libompmd.lib (but not in
|
||||
libompmt.lib and libompmd.dll) should be placed in this file. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
These symbols are required for mutual exclusion with Microsoft OpenMP RTL (and compatibility
|
||||
with MS Compiler).
|
||||
*/
|
||||
/*These symbols are required for mutual exclusion with Microsoft OpenMP RTL
|
||||
(and compatibility with MS Compiler). */
|
||||
|
||||
int _You_must_link_with_exactly_one_OpenMP_library = 1;
|
||||
int _You_must_link_with_Intel_OpenMP_library = 1;
|
||||
int _You_must_link_with_Intel_OpenMP_library = 1;
|
||||
int _You_must_link_with_Microsoft_OpenMP_library = 1;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
+177
-195
@@ -13,236 +13,218 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#ifndef __ABSOFT_WIN
|
||||
# include <sys/types.h>
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#include "kmp_os.h"
|
||||
#include "kmp_lock.h"
|
||||
#include "kmp_str.h"
|
||||
#include "kmp_io.h"
|
||||
#include "kmp.h" // KMP_GTID_DNE, __kmp_debug_buf, etc
|
||||
#include "kmp_io.h"
|
||||
#include "kmp_lock.h"
|
||||
#include "kmp_os.h"
|
||||
#include "kmp_str.h"
|
||||
|
||||
#if KMP_OS_WINDOWS
|
||||
# pragma warning( push )
|
||||
# pragma warning( disable: 271 310 )
|
||||
# include <windows.h>
|
||||
# pragma warning( pop )
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 271 310)
|
||||
#include <windows.h>
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
kmp_bootstrap_lock_t __kmp_stdio_lock = KMP_BOOTSTRAP_LOCK_INITIALIZER( __kmp_stdio_lock ); /* Control stdio functions */
|
||||
kmp_bootstrap_lock_t __kmp_console_lock = KMP_BOOTSTRAP_LOCK_INITIALIZER( __kmp_console_lock ); /* Control console initialization */
|
||||
kmp_bootstrap_lock_t __kmp_stdio_lock = KMP_BOOTSTRAP_LOCK_INITIALIZER(
|
||||
__kmp_stdio_lock); /* Control stdio functions */
|
||||
kmp_bootstrap_lock_t __kmp_console_lock = KMP_BOOTSTRAP_LOCK_INITIALIZER(
|
||||
__kmp_console_lock); /* Control console initialization */
|
||||
|
||||
#if KMP_OS_WINDOWS
|
||||
|
||||
# ifdef KMP_DEBUG
|
||||
/* __kmp_stdout is used only for dev build */
|
||||
static HANDLE __kmp_stdout = NULL;
|
||||
# endif
|
||||
static HANDLE __kmp_stderr = NULL;
|
||||
static int __kmp_console_exists = FALSE;
|
||||
static kmp_str_buf_t __kmp_console_buf;
|
||||
#ifdef KMP_DEBUG
|
||||
/* __kmp_stdout is used only for dev build */
|
||||
static HANDLE __kmp_stdout = NULL;
|
||||
#endif
|
||||
static HANDLE __kmp_stderr = NULL;
|
||||
static int __kmp_console_exists = FALSE;
|
||||
static kmp_str_buf_t __kmp_console_buf;
|
||||
|
||||
static int
|
||||
is_console( void )
|
||||
{
|
||||
char buffer[ 128 ];
|
||||
DWORD rc = 0;
|
||||
DWORD err = 0;
|
||||
// Try to get console title.
|
||||
SetLastError( 0 );
|
||||
// GetConsoleTitle does not reset last error in case of success or short buffer,
|
||||
// so we need to clear it explicitly.
|
||||
rc = GetConsoleTitle( buffer, sizeof( buffer ) );
|
||||
if ( rc == 0 ) {
|
||||
// rc == 0 means getting console title failed. Let us find out why.
|
||||
err = GetLastError();
|
||||
// err == 0 means buffer too short (we suppose console exists).
|
||||
// In Window applications we usually have err == 6 (invalid handle).
|
||||
}; // if
|
||||
return rc > 0 || err == 0;
|
||||
static int is_console(void) {
|
||||
char buffer[128];
|
||||
DWORD rc = 0;
|
||||
DWORD err = 0;
|
||||
// Try to get console title.
|
||||
SetLastError(0);
|
||||
// GetConsoleTitle does not reset last error in case of success or short
|
||||
// buffer, so we need to clear it explicitly.
|
||||
rc = GetConsoleTitle(buffer, sizeof(buffer));
|
||||
if (rc == 0) {
|
||||
// rc == 0 means getting console title failed. Let us find out why.
|
||||
err = GetLastError();
|
||||
// err == 0 means buffer too short (we suppose console exists).
|
||||
// In Window applications we usually have err == 6 (invalid handle).
|
||||
}; // if
|
||||
return rc > 0 || err == 0;
|
||||
}
|
||||
|
||||
void __kmp_close_console(void) {
|
||||
/* wait until user presses return before closing window */
|
||||
/* TODO only close if a window was opened */
|
||||
if (__kmp_console_exists) {
|
||||
#ifdef KMP_DEBUG
|
||||
/* standard out is used only in dev build */
|
||||
__kmp_stdout = NULL;
|
||||
#endif
|
||||
__kmp_stderr = NULL;
|
||||
__kmp_str_buf_free(&__kmp_console_buf);
|
||||
__kmp_console_exists = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* For windows, call this before stdout, stderr, or stdin are used.
|
||||
It opens a console window and starts processing */
|
||||
static void __kmp_redirect_output(void) {
|
||||
__kmp_acquire_bootstrap_lock(&__kmp_console_lock);
|
||||
|
||||
if (!__kmp_console_exists) {
|
||||
#ifdef KMP_DEBUG
|
||||
/* standard out is used only in dev build */
|
||||
HANDLE ho;
|
||||
#endif
|
||||
HANDLE he;
|
||||
|
||||
__kmp_str_buf_init(&__kmp_console_buf);
|
||||
|
||||
AllocConsole();
|
||||
// We do not check the result of AllocConsole because
|
||||
// 1. the call is harmless
|
||||
// 2. it is not clear how to communicate failue
|
||||
// 3. we will detect failure later when we get handle(s)
|
||||
|
||||
#ifdef KMP_DEBUG
|
||||
ho = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
if (ho == INVALID_HANDLE_VALUE || ho == NULL) {
|
||||
|
||||
DWORD err = GetLastError();
|
||||
// TODO: output error somehow (maybe message box)
|
||||
__kmp_stdout = NULL;
|
||||
|
||||
} else {
|
||||
|
||||
__kmp_stdout = ho; // temporary code, need new global for ho
|
||||
}
|
||||
#endif
|
||||
he = GetStdHandle(STD_ERROR_HANDLE);
|
||||
if (he == INVALID_HANDLE_VALUE || he == NULL) {
|
||||
|
||||
void
|
||||
__kmp_close_console( void )
|
||||
{
|
||||
/* wait until user presses return before closing window */
|
||||
/* TODO only close if a window was opened */
|
||||
if( __kmp_console_exists ) {
|
||||
#ifdef KMP_DEBUG
|
||||
/* standard out is used only in dev build */
|
||||
__kmp_stdout = NULL;
|
||||
#endif
|
||||
__kmp_stderr = NULL;
|
||||
__kmp_str_buf_free( &__kmp_console_buf );
|
||||
__kmp_console_exists = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* For windows, call this before stdout, stderr, or stdin are used.
|
||||
* It opens a console window and starts processing */
|
||||
static void
|
||||
__kmp_redirect_output( void )
|
||||
{
|
||||
__kmp_acquire_bootstrap_lock( &__kmp_console_lock );
|
||||
|
||||
if( ! __kmp_console_exists ) {
|
||||
#ifdef KMP_DEBUG
|
||||
/* standard out is used only in dev build */
|
||||
HANDLE ho;
|
||||
#endif
|
||||
HANDLE he;
|
||||
|
||||
__kmp_str_buf_init( &__kmp_console_buf );
|
||||
|
||||
AllocConsole();
|
||||
// We do not check the result of AllocConsole because
|
||||
// 1. the call is harmless
|
||||
// 2. it is not clear how to communicate failue
|
||||
// 3. we will detect failure later when we get handle(s)
|
||||
|
||||
#ifdef KMP_DEBUG
|
||||
ho = GetStdHandle( STD_OUTPUT_HANDLE );
|
||||
if ( ho == INVALID_HANDLE_VALUE || ho == NULL ) {
|
||||
|
||||
DWORD err = GetLastError();
|
||||
// TODO: output error somehow (maybe message box)
|
||||
__kmp_stdout = NULL;
|
||||
|
||||
} else {
|
||||
|
||||
__kmp_stdout = ho; // temporary code, need new global for ho
|
||||
|
||||
}
|
||||
#endif
|
||||
he = GetStdHandle( STD_ERROR_HANDLE );
|
||||
if ( he == INVALID_HANDLE_VALUE || he == NULL ) {
|
||||
|
||||
DWORD err = GetLastError();
|
||||
// TODO: output error somehow (maybe message box)
|
||||
__kmp_stderr = NULL;
|
||||
|
||||
} else {
|
||||
|
||||
__kmp_stderr = he; // temporary code, need new global
|
||||
}
|
||||
__kmp_console_exists = TRUE;
|
||||
}
|
||||
__kmp_release_bootstrap_lock( &__kmp_console_lock );
|
||||
DWORD err = GetLastError();
|
||||
// TODO: output error somehow (maybe message box)
|
||||
__kmp_stderr = NULL;
|
||||
|
||||
} else {
|
||||
|
||||
__kmp_stderr = he; // temporary code, need new global
|
||||
}
|
||||
__kmp_console_exists = TRUE;
|
||||
}
|
||||
__kmp_release_bootstrap_lock(&__kmp_console_lock);
|
||||
}
|
||||
|
||||
#else
|
||||
#define __kmp_stderr (stderr)
|
||||
#define __kmp_stderr (stderr)
|
||||
#endif /* KMP_OS_WINDOWS */
|
||||
|
||||
void
|
||||
__kmp_vprintf( enum kmp_io __kmp_io, char const * format, va_list ap )
|
||||
{
|
||||
#if KMP_OS_WINDOWS
|
||||
if( !__kmp_console_exists ) {
|
||||
__kmp_redirect_output();
|
||||
}
|
||||
if( ! __kmp_stderr && __kmp_io == kmp_err ) {
|
||||
return;
|
||||
}
|
||||
#ifdef KMP_DEBUG
|
||||
if( ! __kmp_stdout && __kmp_io == kmp_out ) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#endif /* KMP_OS_WINDOWS */
|
||||
void __kmp_vprintf(enum kmp_io __kmp_io, char const *format, va_list ap) {
|
||||
#if KMP_OS_WINDOWS
|
||||
if (!__kmp_console_exists) {
|
||||
__kmp_redirect_output();
|
||||
}
|
||||
if (!__kmp_stderr && __kmp_io == kmp_err) {
|
||||
return;
|
||||
}
|
||||
#ifdef KMP_DEBUG
|
||||
if (!__kmp_stdout && __kmp_io == kmp_out) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#endif /* KMP_OS_WINDOWS */
|
||||
|
||||
if ( __kmp_debug_buf && __kmp_debug_buffer != NULL ) {
|
||||
if (__kmp_debug_buf && __kmp_debug_buffer != NULL) {
|
||||
|
||||
int dc = ( __kmp_debug_buf_atomic ?
|
||||
KMP_TEST_THEN_INC32( & __kmp_debug_count) : __kmp_debug_count++ )
|
||||
% __kmp_debug_buf_lines;
|
||||
char *db = & __kmp_debug_buffer[ dc * __kmp_debug_buf_chars ];
|
||||
int chars = 0;
|
||||
int dc = (__kmp_debug_buf_atomic ? KMP_TEST_THEN_INC32(&__kmp_debug_count)
|
||||
: __kmp_debug_count++) %
|
||||
__kmp_debug_buf_lines;
|
||||
char *db = &__kmp_debug_buffer[dc * __kmp_debug_buf_chars];
|
||||
int chars = 0;
|
||||
|
||||
#ifdef KMP_DEBUG_PIDS
|
||||
chars = KMP_SNPRINTF( db, __kmp_debug_buf_chars, "pid=%d: ", (kmp_int32)getpid() );
|
||||
#endif
|
||||
chars += KMP_VSNPRINTF( db, __kmp_debug_buf_chars, format, ap );
|
||||
#ifdef KMP_DEBUG_PIDS
|
||||
chars = KMP_SNPRINTF(db, __kmp_debug_buf_chars, "pid=%d: ",
|
||||
(kmp_int32)getpid());
|
||||
#endif
|
||||
chars += KMP_VSNPRINTF(db, __kmp_debug_buf_chars, format, ap);
|
||||
|
||||
if ( chars + 1 > __kmp_debug_buf_chars ) {
|
||||
if ( chars + 1 > __kmp_debug_buf_warn_chars ) {
|
||||
#if KMP_OS_WINDOWS
|
||||
DWORD count;
|
||||
__kmp_str_buf_print( &__kmp_console_buf,
|
||||
"OMP warning: Debugging buffer overflow; increase KMP_DEBUG_BUF_CHARS to %d\n",
|
||||
chars + 1 );
|
||||
WriteFile( __kmp_stderr, __kmp_console_buf.str, __kmp_console_buf.used, &count, NULL );
|
||||
__kmp_str_buf_clear( &__kmp_console_buf );
|
||||
#else
|
||||
fprintf( __kmp_stderr,
|
||||
"OMP warning: Debugging buffer overflow; increase KMP_DEBUG_BUF_CHARS to %d\n",
|
||||
chars + 1 );
|
||||
fflush( __kmp_stderr );
|
||||
#endif
|
||||
__kmp_debug_buf_warn_chars = chars + 1;
|
||||
}
|
||||
/* terminate string if overflow occurred */
|
||||
db[ __kmp_debug_buf_chars - 2 ] = '\n';
|
||||
db[ __kmp_debug_buf_chars - 1 ] = '\0';
|
||||
}
|
||||
} else {
|
||||
#if KMP_OS_WINDOWS
|
||||
DWORD count;
|
||||
#ifdef KMP_DEBUG_PIDS
|
||||
__kmp_str_buf_print( &__kmp_console_buf, "pid=%d: ",
|
||||
(kmp_int32)getpid() );
|
||||
#endif
|
||||
__kmp_str_buf_vprint( &__kmp_console_buf, format, ap );
|
||||
WriteFile(
|
||||
__kmp_stderr,
|
||||
__kmp_console_buf.str,
|
||||
__kmp_console_buf.used,
|
||||
&count,
|
||||
NULL
|
||||
);
|
||||
__kmp_str_buf_clear( &__kmp_console_buf );
|
||||
#else
|
||||
#ifdef KMP_DEBUG_PIDS
|
||||
fprintf( __kmp_stderr, "pid=%d: ", (kmp_int32)getpid() );
|
||||
#endif
|
||||
vfprintf( __kmp_stderr, format, ap );
|
||||
fflush( __kmp_stderr );
|
||||
#endif
|
||||
if (chars + 1 > __kmp_debug_buf_chars) {
|
||||
if (chars + 1 > __kmp_debug_buf_warn_chars) {
|
||||
#if KMP_OS_WINDOWS
|
||||
DWORD count;
|
||||
__kmp_str_buf_print(&__kmp_console_buf, "OMP warning: Debugging buffer "
|
||||
"overflow; increase "
|
||||
"KMP_DEBUG_BUF_CHARS to %d\n",
|
||||
chars + 1);
|
||||
WriteFile(__kmp_stderr, __kmp_console_buf.str, __kmp_console_buf.used,
|
||||
&count, NULL);
|
||||
__kmp_str_buf_clear(&__kmp_console_buf);
|
||||
#else
|
||||
fprintf(__kmp_stderr, "OMP warning: Debugging buffer overflow; "
|
||||
"increase KMP_DEBUG_BUF_CHARS to %d\n",
|
||||
chars + 1);
|
||||
fflush(__kmp_stderr);
|
||||
#endif
|
||||
__kmp_debug_buf_warn_chars = chars + 1;
|
||||
}
|
||||
/* terminate string if overflow occurred */
|
||||
db[__kmp_debug_buf_chars - 2] = '\n';
|
||||
db[__kmp_debug_buf_chars - 1] = '\0';
|
||||
}
|
||||
} else {
|
||||
#if KMP_OS_WINDOWS
|
||||
DWORD count;
|
||||
#ifdef KMP_DEBUG_PIDS
|
||||
__kmp_str_buf_print(&__kmp_console_buf, "pid=%d: ", (kmp_int32)getpid());
|
||||
#endif
|
||||
__kmp_str_buf_vprint(&__kmp_console_buf, format, ap);
|
||||
WriteFile(__kmp_stderr, __kmp_console_buf.str, __kmp_console_buf.used,
|
||||
&count, NULL);
|
||||
__kmp_str_buf_clear(&__kmp_console_buf);
|
||||
#else
|
||||
#ifdef KMP_DEBUG_PIDS
|
||||
fprintf(__kmp_stderr, "pid=%d: ", (kmp_int32)getpid());
|
||||
#endif
|
||||
vfprintf(__kmp_stderr, format, ap);
|
||||
fflush(__kmp_stderr);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
__kmp_printf( char const * format, ... )
|
||||
{
|
||||
va_list ap;
|
||||
va_start( ap, format );
|
||||
void __kmp_printf(char const *format, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
|
||||
__kmp_acquire_bootstrap_lock( & __kmp_stdio_lock );
|
||||
__kmp_vprintf( kmp_err, format, ap );
|
||||
__kmp_release_bootstrap_lock( & __kmp_stdio_lock );
|
||||
__kmp_acquire_bootstrap_lock(&__kmp_stdio_lock);
|
||||
__kmp_vprintf(kmp_err, format, ap);
|
||||
__kmp_release_bootstrap_lock(&__kmp_stdio_lock);
|
||||
|
||||
va_end( ap );
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void
|
||||
__kmp_printf_no_lock( char const * format, ... )
|
||||
{
|
||||
va_list ap;
|
||||
va_start( ap, format );
|
||||
void __kmp_printf_no_lock(char const *format, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
|
||||
__kmp_vprintf( kmp_err, format, ap );
|
||||
__kmp_vprintf(kmp_err, format, ap);
|
||||
|
||||
va_end( ap );
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
+8
-12
@@ -20,25 +20,21 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
enum kmp_io {
|
||||
kmp_out = 0,
|
||||
kmp_err
|
||||
};
|
||||
enum kmp_io { kmp_out = 0, kmp_err };
|
||||
|
||||
extern kmp_bootstrap_lock_t __kmp_stdio_lock; /* Control stdio functions */
|
||||
extern kmp_bootstrap_lock_t __kmp_console_lock; /* Control console initialization */
|
||||
extern kmp_bootstrap_lock_t __kmp_stdio_lock; /* Control stdio functions */
|
||||
extern kmp_bootstrap_lock_t
|
||||
__kmp_console_lock; /* Control console initialization */
|
||||
|
||||
extern void __kmp_vprintf( enum kmp_io __kmp_io, char const * format, va_list ap );
|
||||
extern void __kmp_printf( char const * format, ... );
|
||||
extern void __kmp_printf_no_lock( char const * format, ... );
|
||||
extern void __kmp_close_console( void );
|
||||
extern void __kmp_vprintf(enum kmp_io __kmp_io, char const *format, va_list ap);
|
||||
extern void __kmp_printf(char const *format, ...);
|
||||
extern void __kmp_printf_no_lock(char const *format, ...);
|
||||
extern void __kmp_close_console(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* KMP_IO_H */
|
||||
|
||||
|
||||
+102
-114
@@ -19,145 +19,133 @@
|
||||
#include "kmp_itt.h"
|
||||
|
||||
#if KMP_DEBUG
|
||||
#include "kmp_itt.inl"
|
||||
#include "kmp_itt.inl"
|
||||
#endif
|
||||
|
||||
|
||||
#if USE_ITT_NOTIFY
|
||||
|
||||
kmp_int32 __kmp_barrier_domain_count;
|
||||
kmp_int32 __kmp_region_domain_count;
|
||||
__itt_domain* __kmp_itt_barrier_domains[KMP_MAX_FRAME_DOMAINS];
|
||||
__itt_domain* __kmp_itt_region_domains[KMP_MAX_FRAME_DOMAINS];
|
||||
__itt_domain* __kmp_itt_imbalance_domains[KMP_MAX_FRAME_DOMAINS];
|
||||
kmp_int32 __kmp_itt_region_team_size[KMP_MAX_FRAME_DOMAINS];
|
||||
__itt_domain * metadata_domain = NULL;
|
||||
__itt_string_handle * string_handle_imbl = NULL;
|
||||
__itt_string_handle * string_handle_loop = NULL;
|
||||
__itt_string_handle * string_handle_sngl = NULL;
|
||||
kmp_int32 __kmp_barrier_domain_count;
|
||||
kmp_int32 __kmp_region_domain_count;
|
||||
__itt_domain *__kmp_itt_barrier_domains[KMP_MAX_FRAME_DOMAINS];
|
||||
__itt_domain *__kmp_itt_region_domains[KMP_MAX_FRAME_DOMAINS];
|
||||
__itt_domain *__kmp_itt_imbalance_domains[KMP_MAX_FRAME_DOMAINS];
|
||||
kmp_int32 __kmp_itt_region_team_size[KMP_MAX_FRAME_DOMAINS];
|
||||
__itt_domain *metadata_domain = NULL;
|
||||
__itt_string_handle *string_handle_imbl = NULL;
|
||||
__itt_string_handle *string_handle_loop = NULL;
|
||||
__itt_string_handle *string_handle_sngl = NULL;
|
||||
|
||||
#include "kmp_version.h"
|
||||
#include "kmp_i18n.h"
|
||||
#include "kmp_str.h"
|
||||
#include "kmp_i18n.h"
|
||||
#include "kmp_str.h"
|
||||
#include "kmp_version.h"
|
||||
|
||||
KMP_BUILD_ASSERT( sizeof( kmp_itt_mark_t ) == sizeof( __itt_mark_type ) );
|
||||
KMP_BUILD_ASSERT(sizeof(kmp_itt_mark_t) == sizeof(__itt_mark_type));
|
||||
|
||||
/*
|
||||
Previously used warnings:
|
||||
/* Previously used warnings:
|
||||
|
||||
KMP_WARNING( IttAllNotifDisabled );
|
||||
KMP_WARNING( IttObjNotifDisabled );
|
||||
KMP_WARNING( IttMarkNotifDisabled );
|
||||
KMP_WARNING( IttUnloadLibFailed, libittnotify );
|
||||
*/
|
||||
KMP_WARNING( IttAllNotifDisabled );
|
||||
KMP_WARNING( IttObjNotifDisabled );
|
||||
KMP_WARNING( IttMarkNotifDisabled );
|
||||
KMP_WARNING( IttUnloadLibFailed, libittnotify );
|
||||
*/
|
||||
|
||||
|
||||
kmp_int32 __kmp_itt_prepare_delay = 0;
|
||||
kmp_bootstrap_lock_t __kmp_itt_debug_lock = KMP_BOOTSTRAP_LOCK_INITIALIZER( __kmp_itt_debug_lock );
|
||||
kmp_int32 __kmp_itt_prepare_delay = 0;
|
||||
kmp_bootstrap_lock_t __kmp_itt_debug_lock =
|
||||
KMP_BOOTSTRAP_LOCK_INITIALIZER(__kmp_itt_debug_lock);
|
||||
|
||||
#endif // USE_ITT_NOTIFY
|
||||
|
||||
void __kmp_itt_initialize() {
|
||||
|
||||
// ITTNotify library is loaded and initialized at first call to any ittnotify function,
|
||||
// so we do not need to explicitly load it any more.
|
||||
// Jusr report OMP RTL version to ITTNotify.
|
||||
// ITTNotify library is loaded and initialized at first call to any ittnotify
|
||||
// function, so we do not need to explicitly load it any more. Just report OMP
|
||||
// RTL version to ITTNotify.
|
||||
|
||||
#if USE_ITT_NOTIFY
|
||||
// Report OpenMP RTL version.
|
||||
kmp_str_buf_t buf;
|
||||
__itt_mark_type version;
|
||||
__kmp_str_buf_init( & buf );
|
||||
__kmp_str_buf_print(
|
||||
& buf,
|
||||
"OMP RTL Version %d.%d.%d",
|
||||
__kmp_version_major,
|
||||
__kmp_version_minor,
|
||||
__kmp_version_build
|
||||
);
|
||||
if ( __itt_api_version_ptr != NULL ) {
|
||||
__kmp_str_buf_print( & buf, ":%s", __itt_api_version() );
|
||||
}; // if
|
||||
version = __itt_mark_create( buf.str );
|
||||
__itt_mark( version, NULL );
|
||||
__kmp_str_buf_free( & buf );
|
||||
#endif
|
||||
#if USE_ITT_NOTIFY
|
||||
// Report OpenMP RTL version.
|
||||
kmp_str_buf_t buf;
|
||||
__itt_mark_type version;
|
||||
__kmp_str_buf_init(&buf);
|
||||
__kmp_str_buf_print(&buf, "OMP RTL Version %d.%d.%d", __kmp_version_major,
|
||||
__kmp_version_minor, __kmp_version_build);
|
||||
if (__itt_api_version_ptr != NULL) {
|
||||
__kmp_str_buf_print(&buf, ":%s", __itt_api_version());
|
||||
}; // if
|
||||
version = __itt_mark_create(buf.str);
|
||||
__itt_mark(version, NULL);
|
||||
__kmp_str_buf_free(&buf);
|
||||
#endif
|
||||
|
||||
} // __kmp_itt_initialize
|
||||
|
||||
|
||||
void __kmp_itt_destroy() {
|
||||
#if USE_ITT_NOTIFY
|
||||
__kmp_itt_fini_ittlib();
|
||||
#endif
|
||||
#if USE_ITT_NOTIFY
|
||||
__kmp_itt_fini_ittlib();
|
||||
#endif
|
||||
} // __kmp_itt_destroy
|
||||
|
||||
extern "C" void __itt_error_handler(__itt_error_code err, va_list args) {
|
||||
|
||||
extern "C"
|
||||
void
|
||||
__itt_error_handler(
|
||||
__itt_error_code err,
|
||||
va_list args
|
||||
) {
|
||||
|
||||
switch ( err ) {
|
||||
case __itt_error_no_module : {
|
||||
char const * library = va_arg( args, char const * );
|
||||
switch (err) {
|
||||
case __itt_error_no_module: {
|
||||
char const *library = va_arg(args, char const *);
|
||||
#if KMP_OS_WINDOWS
|
||||
int sys_err = va_arg( args, int );
|
||||
kmp_msg_t err_code = KMP_SYSERRCODE( sys_err );
|
||||
__kmp_msg( kmp_ms_warning, KMP_MSG( IttLoadLibFailed, library ), err_code, __kmp_msg_null );
|
||||
if (__kmp_generate_warnings == kmp_warnings_off) {
|
||||
__kmp_str_free(&err_code.str);
|
||||
}
|
||||
int sys_err = va_arg(args, int);
|
||||
kmp_msg_t err_code = KMP_SYSERRCODE(sys_err);
|
||||
__kmp_msg(kmp_ms_warning, KMP_MSG(IttLoadLibFailed, library), err_code,
|
||||
__kmp_msg_null);
|
||||
if (__kmp_generate_warnings == kmp_warnings_off) {
|
||||
__kmp_str_free(&err_code.str);
|
||||
}
|
||||
#else
|
||||
char const * sys_err = va_arg( args, char const * );
|
||||
kmp_msg_t err_code = KMP_SYSERRMESG( sys_err );
|
||||
__kmp_msg( kmp_ms_warning, KMP_MSG( IttLoadLibFailed, library ), err_code, __kmp_msg_null );
|
||||
if (__kmp_generate_warnings == kmp_warnings_off) {
|
||||
__kmp_str_free(&err_code.str);
|
||||
}
|
||||
char const *sys_err = va_arg(args, char const *);
|
||||
kmp_msg_t err_code = KMP_SYSERRMESG(sys_err);
|
||||
__kmp_msg(kmp_ms_warning, KMP_MSG(IttLoadLibFailed, library), err_code,
|
||||
__kmp_msg_null);
|
||||
if (__kmp_generate_warnings == kmp_warnings_off) {
|
||||
__kmp_str_free(&err_code.str);
|
||||
}
|
||||
#endif
|
||||
} break;
|
||||
case __itt_error_no_symbol : {
|
||||
char const * library = va_arg( args, char const * );
|
||||
char const * symbol = va_arg( args, char const * );
|
||||
KMP_WARNING( IttLookupFailed, symbol, library );
|
||||
} break;
|
||||
case __itt_error_unknown_group : {
|
||||
char const * var = va_arg( args, char const * );
|
||||
char const * group = va_arg( args, char const * );
|
||||
KMP_WARNING( IttUnknownGroup, var, group );
|
||||
} break;
|
||||
case __itt_error_env_too_long : {
|
||||
char const * var = va_arg( args, char const * );
|
||||
size_t act_len = va_arg( args, size_t );
|
||||
size_t max_len = va_arg( args, size_t );
|
||||
KMP_WARNING( IttEnvVarTooLong, var, (unsigned long) act_len, (unsigned long) max_len );
|
||||
} break;
|
||||
case __itt_error_cant_read_env : {
|
||||
char const * var = va_arg( args, char const * );
|
||||
int sys_err = va_arg( args, int );
|
||||
kmp_msg_t err_code = KMP_ERR( sys_err );
|
||||
__kmp_msg( kmp_ms_warning, KMP_MSG( CantGetEnvVar, var ), err_code, __kmp_msg_null );
|
||||
if (__kmp_generate_warnings == kmp_warnings_off) {
|
||||
__kmp_str_free(&err_code.str);
|
||||
}
|
||||
} break;
|
||||
case __itt_error_system : {
|
||||
char const * func = va_arg( args, char const * );
|
||||
int sys_err = va_arg( args, int );
|
||||
kmp_msg_t err_code = KMP_SYSERRCODE( sys_err );
|
||||
__kmp_msg( kmp_ms_warning, KMP_MSG( IttFunctionError, func ), err_code, __kmp_msg_null );
|
||||
if (__kmp_generate_warnings == kmp_warnings_off) {
|
||||
__kmp_str_free(&err_code.str);
|
||||
}
|
||||
} break;
|
||||
default : {
|
||||
KMP_WARNING( IttUnknownError, err );
|
||||
};
|
||||
}; // switch
|
||||
|
||||
} break;
|
||||
case __itt_error_no_symbol: {
|
||||
char const *library = va_arg(args, char const *);
|
||||
char const *symbol = va_arg(args, char const *);
|
||||
KMP_WARNING(IttLookupFailed, symbol, library);
|
||||
} break;
|
||||
case __itt_error_unknown_group: {
|
||||
char const *var = va_arg(args, char const *);
|
||||
char const *group = va_arg(args, char const *);
|
||||
KMP_WARNING(IttUnknownGroup, var, group);
|
||||
} break;
|
||||
case __itt_error_env_too_long: {
|
||||
char const *var = va_arg(args, char const *);
|
||||
size_t act_len = va_arg(args, size_t);
|
||||
size_t max_len = va_arg(args, size_t);
|
||||
KMP_WARNING(IttEnvVarTooLong, var, (unsigned long)act_len,
|
||||
(unsigned long)max_len);
|
||||
} break;
|
||||
case __itt_error_cant_read_env: {
|
||||
char const *var = va_arg(args, char const *);
|
||||
int sys_err = va_arg(args, int);
|
||||
kmp_msg_t err_code = KMP_ERR(sys_err);
|
||||
__kmp_msg(kmp_ms_warning, KMP_MSG(CantGetEnvVar, var), err_code,
|
||||
__kmp_msg_null);
|
||||
if (__kmp_generate_warnings == kmp_warnings_off) {
|
||||
__kmp_str_free(&err_code.str);
|
||||
}
|
||||
} break;
|
||||
case __itt_error_system: {
|
||||
char const *func = va_arg(args, char const *);
|
||||
int sys_err = va_arg(args, int);
|
||||
kmp_msg_t err_code = KMP_SYSERRCODE(sys_err);
|
||||
__kmp_msg(kmp_ms_warning, KMP_MSG(IttFunctionError, func), err_code,
|
||||
__kmp_msg_null);
|
||||
if (__kmp_generate_warnings == kmp_warnings_off) {
|
||||
__kmp_str_free(&err_code.str);
|
||||
}
|
||||
} break;
|
||||
default: { KMP_WARNING(IttUnknownError, err); };
|
||||
}; // switch
|
||||
} // __itt_error_handler
|
||||
|
||||
#endif /* USE_ITT_BUILD */
|
||||
|
||||
+216
-194
@@ -24,104 +24,121 @@
|
||||
#include "legacy/ittnotify.h"
|
||||
|
||||
#if KMP_DEBUG
|
||||
#define __kmp_inline // Turn off inlining in debug mode.
|
||||
#define __kmp_inline // Turn off inlining in debug mode.
|
||||
#else
|
||||
#define __kmp_inline static inline
|
||||
#define __kmp_inline static inline
|
||||
#endif
|
||||
|
||||
#if USE_ITT_NOTIFY
|
||||
extern kmp_int32 __kmp_itt_prepare_delay;
|
||||
# ifdef __cplusplus
|
||||
extern "C" void __kmp_itt_fini_ittlib(void);
|
||||
# else
|
||||
extern void __kmp_itt_fini_ittlib(void);
|
||||
# endif
|
||||
extern kmp_int32 __kmp_itt_prepare_delay;
|
||||
#ifdef __cplusplus
|
||||
extern "C" void __kmp_itt_fini_ittlib(void);
|
||||
#else
|
||||
extern void __kmp_itt_fini_ittlib(void);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Simplify the handling of an argument that is only required when USE_ITT_BUILD is enabled.
|
||||
#define USE_ITT_BUILD_ARG(x) ,x
|
||||
// Simplify the handling of an argument that is only required when USE_ITT_BUILD
|
||||
// is enabled.
|
||||
#define USE_ITT_BUILD_ARG(x) , x
|
||||
|
||||
void __kmp_itt_initialize();
|
||||
void __kmp_itt_destroy();
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------------
|
||||
// New stuff for reporting high-level constructs.
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
|
||||
// Note the naming convention:
|
||||
// __kmp_itt_xxxing() function should be called before action, while
|
||||
// __kmp_itt_xxxed() function should be called after action.
|
||||
|
||||
// --- Parallel region reporting ---
|
||||
__kmp_inline void __kmp_itt_region_forking( int gtid, int team_size, int barriers ); // Master only, before forking threads.
|
||||
__kmp_inline void __kmp_itt_region_joined( int gtid ); // Master only, after joining threads.
|
||||
// (*) Note: A thread may execute tasks after this point, though.
|
||||
__kmp_inline void
|
||||
__kmp_itt_region_forking(int gtid, int team_size,
|
||||
int barriers); // Master only, before forking threads.
|
||||
__kmp_inline void
|
||||
__kmp_itt_region_joined(int gtid); // Master only, after joining threads.
|
||||
// (*) Note: A thread may execute tasks after this point, though.
|
||||
|
||||
// --- Frame reporting ---
|
||||
// region = 0 - no regions, region = 1 - parallel, region = 2 - serialized parallel
|
||||
__kmp_inline void __kmp_itt_frame_submit( int gtid, __itt_timestamp begin, __itt_timestamp end, int imbalance, ident_t *loc, int team_size, int region = 0 );
|
||||
// region=0: no regions, region=1: parallel, region=2: serialized parallel
|
||||
__kmp_inline void __kmp_itt_frame_submit(int gtid, __itt_timestamp begin,
|
||||
__itt_timestamp end, int imbalance,
|
||||
ident_t *loc, int team_size,
|
||||
int region = 0);
|
||||
|
||||
// --- Metadata reporting ---
|
||||
// begin/end - begin/end timestamps of a barrier frame, imbalance - aggregated wait time value, reduction -if this is a reduction barrier
|
||||
__kmp_inline void __kmp_itt_metadata_imbalance( int gtid, kmp_uint64 begin, kmp_uint64 end, kmp_uint64 imbalance, kmp_uint64 reduction );
|
||||
// sched_type: 0 - static, 1 - dynamic, 2 - guided, 3 - custom (all others); iterations - loop trip count, chunk - chunk size
|
||||
__kmp_inline void __kmp_itt_metadata_loop( ident_t * loc, kmp_uint64 sched_type, kmp_uint64 iterations, kmp_uint64 chunk );
|
||||
__kmp_inline void __kmp_itt_metadata_single( ident_t * loc );
|
||||
// begin/end - begin/end timestamps of a barrier frame, imbalance - aggregated
|
||||
// wait time value, reduction -if this is a reduction barrier
|
||||
__kmp_inline void __kmp_itt_metadata_imbalance(int gtid, kmp_uint64 begin,
|
||||
kmp_uint64 end,
|
||||
kmp_uint64 imbalance,
|
||||
kmp_uint64 reduction);
|
||||
// sched_type: 0 - static, 1 - dynamic, 2 - guided, 3 - custom (all others);
|
||||
// iterations - loop trip count, chunk - chunk size
|
||||
__kmp_inline void __kmp_itt_metadata_loop(ident_t *loc, kmp_uint64 sched_type,
|
||||
kmp_uint64 iterations,
|
||||
kmp_uint64 chunk);
|
||||
__kmp_inline void __kmp_itt_metadata_single(ident_t *loc);
|
||||
|
||||
// --- Barrier reporting ---
|
||||
__kmp_inline void * __kmp_itt_barrier_object( int gtid, int bt, int set_name = 0, int delta = 0 );
|
||||
__kmp_inline void __kmp_itt_barrier_starting( int gtid, void * object );
|
||||
__kmp_inline void __kmp_itt_barrier_middle( int gtid, void * object );
|
||||
__kmp_inline void __kmp_itt_barrier_finished( int gtid, void * object );
|
||||
__kmp_inline void *__kmp_itt_barrier_object(int gtid, int bt, int set_name = 0,
|
||||
int delta = 0);
|
||||
__kmp_inline void __kmp_itt_barrier_starting(int gtid, void *object);
|
||||
__kmp_inline void __kmp_itt_barrier_middle(int gtid, void *object);
|
||||
__kmp_inline void __kmp_itt_barrier_finished(int gtid, void *object);
|
||||
|
||||
// --- Taskwait reporting ---
|
||||
__kmp_inline void * __kmp_itt_taskwait_object( int gtid );
|
||||
__kmp_inline void __kmp_itt_taskwait_starting( int gtid, void * object );
|
||||
__kmp_inline void __kmp_itt_taskwait_finished( int gtid, void * object );
|
||||
__kmp_inline void *__kmp_itt_taskwait_object(int gtid);
|
||||
__kmp_inline void __kmp_itt_taskwait_starting(int gtid, void *object);
|
||||
__kmp_inline void __kmp_itt_taskwait_finished(int gtid, void *object);
|
||||
|
||||
// --- Task reporting ---
|
||||
__kmp_inline void __kmp_itt_task_starting( void * object );
|
||||
__kmp_inline void __kmp_itt_task_finished( void * object );
|
||||
__kmp_inline void __kmp_itt_task_starting(void *object);
|
||||
__kmp_inline void __kmp_itt_task_finished(void *object);
|
||||
|
||||
// --- Lock reporting ---
|
||||
#if KMP_USE_DYNAMIC_LOCK
|
||||
__kmp_inline void __kmp_itt_lock_creating( kmp_user_lock_p lock, const ident_t * );
|
||||
__kmp_inline void __kmp_itt_lock_creating(kmp_user_lock_p lock,
|
||||
const ident_t *);
|
||||
#else
|
||||
__kmp_inline void __kmp_itt_lock_creating( kmp_user_lock_p lock );
|
||||
__kmp_inline void __kmp_itt_lock_creating(kmp_user_lock_p lock);
|
||||
#endif
|
||||
__kmp_inline void __kmp_itt_lock_acquiring( kmp_user_lock_p lock );
|
||||
__kmp_inline void __kmp_itt_lock_acquired( kmp_user_lock_p lock );
|
||||
__kmp_inline void __kmp_itt_lock_releasing( kmp_user_lock_p lock );
|
||||
__kmp_inline void __kmp_itt_lock_cancelled( kmp_user_lock_p lock );
|
||||
__kmp_inline void __kmp_itt_lock_destroyed( kmp_user_lock_p lock );
|
||||
__kmp_inline void __kmp_itt_lock_acquiring(kmp_user_lock_p lock);
|
||||
__kmp_inline void __kmp_itt_lock_acquired(kmp_user_lock_p lock);
|
||||
__kmp_inline void __kmp_itt_lock_releasing(kmp_user_lock_p lock);
|
||||
__kmp_inline void __kmp_itt_lock_cancelled(kmp_user_lock_p lock);
|
||||
__kmp_inline void __kmp_itt_lock_destroyed(kmp_user_lock_p lock);
|
||||
|
||||
// --- Critical reporting ---
|
||||
#if KMP_USE_DYNAMIC_LOCK
|
||||
__kmp_inline void __kmp_itt_critical_creating( kmp_user_lock_p lock, const ident_t * );
|
||||
__kmp_inline void __kmp_itt_critical_creating(kmp_user_lock_p lock,
|
||||
const ident_t *);
|
||||
#else
|
||||
__kmp_inline void __kmp_itt_critical_creating( kmp_user_lock_p lock );
|
||||
__kmp_inline void __kmp_itt_critical_creating(kmp_user_lock_p lock);
|
||||
#endif
|
||||
__kmp_inline void __kmp_itt_critical_acquiring( kmp_user_lock_p lock );
|
||||
__kmp_inline void __kmp_itt_critical_acquired( kmp_user_lock_p lock );
|
||||
__kmp_inline void __kmp_itt_critical_releasing( kmp_user_lock_p lock );
|
||||
__kmp_inline void __kmp_itt_critical_destroyed( kmp_user_lock_p lock );
|
||||
__kmp_inline void __kmp_itt_critical_acquiring(kmp_user_lock_p lock);
|
||||
__kmp_inline void __kmp_itt_critical_acquired(kmp_user_lock_p lock);
|
||||
__kmp_inline void __kmp_itt_critical_releasing(kmp_user_lock_p lock);
|
||||
__kmp_inline void __kmp_itt_critical_destroyed(kmp_user_lock_p lock);
|
||||
|
||||
// --- Single reporting ---
|
||||
__kmp_inline void __kmp_itt_single_start( int gtid );
|
||||
__kmp_inline void __kmp_itt_single_end( int gtid );
|
||||
__kmp_inline void __kmp_itt_single_start(int gtid);
|
||||
__kmp_inline void __kmp_itt_single_end(int gtid);
|
||||
|
||||
// --- Ordered reporting ---
|
||||
__kmp_inline void __kmp_itt_ordered_init( int gtid );
|
||||
__kmp_inline void __kmp_itt_ordered_prep( int gtid );
|
||||
__kmp_inline void __kmp_itt_ordered_start( int gtid );
|
||||
__kmp_inline void __kmp_itt_ordered_end( int gtid );
|
||||
__kmp_inline void __kmp_itt_ordered_init(int gtid);
|
||||
__kmp_inline void __kmp_itt_ordered_prep(int gtid);
|
||||
__kmp_inline void __kmp_itt_ordered_start(int gtid);
|
||||
__kmp_inline void __kmp_itt_ordered_end(int gtid);
|
||||
|
||||
// --- Threads reporting ---
|
||||
__kmp_inline void __kmp_itt_thread_ignore();
|
||||
__kmp_inline void __kmp_itt_thread_name( int gtid );
|
||||
__kmp_inline void __kmp_itt_thread_ignore();
|
||||
__kmp_inline void __kmp_itt_thread_name(int gtid);
|
||||
|
||||
// --- System objects ---
|
||||
__kmp_inline void __kmp_itt_system_object_created( void * object, char const * name );
|
||||
__kmp_inline void __kmp_itt_system_object_created(void *object,
|
||||
char const *name);
|
||||
|
||||
// --- Stack stitching ---
|
||||
__kmp_inline __itt_caller __kmp_itt_stack_caller_create(void);
|
||||
@@ -129,184 +146,189 @@ __kmp_inline void __kmp_itt_stack_caller_destroy(__itt_caller);
|
||||
__kmp_inline void __kmp_itt_stack_callee_enter(__itt_caller);
|
||||
__kmp_inline void __kmp_itt_stack_callee_leave(__itt_caller);
|
||||
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------------
|
||||
// Old stuff for reporting low-level internal synchronization.
|
||||
// -------------------------------------------------------------------------------------------------
|
||||
|
||||
#if USE_ITT_NOTIFY
|
||||
|
||||
/*
|
||||
* Support for SSC marks, which are used by SDE
|
||||
* http://software.intel.com/en-us/articles/intel-software-development-emulator
|
||||
* to mark points in instruction traces that represent spin-loops and are
|
||||
* therefore uninteresting when collecting traces for architecture simulation.
|
||||
*/
|
||||
#ifndef INCLUDE_SSC_MARKS
|
||||
# define INCLUDE_SSC_MARKS (KMP_OS_LINUX && KMP_ARCH_X86_64)
|
||||
#endif
|
||||
/* Support for SSC marks, which are used by SDE
|
||||
http://software.intel.com/en-us/articles/intel-software-development-emulator
|
||||
to mark points in instruction traces that represent spin-loops and are
|
||||
therefore uninteresting when collecting traces for architecture simulation.
|
||||
*/
|
||||
#ifndef INCLUDE_SSC_MARKS
|
||||
#define INCLUDE_SSC_MARKS (KMP_OS_LINUX && KMP_ARCH_X86_64)
|
||||
#endif
|
||||
|
||||
/* Linux 64 only for now */
|
||||
#if (INCLUDE_SSC_MARKS && KMP_OS_LINUX && KMP_ARCH_X86_64)
|
||||
// Portable (at least for gcc and icc) code to insert the necessary instructions
|
||||
// to set %ebx and execute the unlikely no-op.
|
||||
#if defined( __INTEL_COMPILER )
|
||||
# define INSERT_SSC_MARK(tag) __SSC_MARK(tag)
|
||||
#else
|
||||
# define INSERT_SSC_MARK(tag) \
|
||||
__asm__ __volatile__ ("movl %0, %%ebx; .byte 0x64, 0x67, 0x90 " ::"i"(tag):"%ebx")
|
||||
#endif
|
||||
#else
|
||||
# define INSERT_SSC_MARK(tag) ((void)0)
|
||||
#endif
|
||||
/* Linux 64 only for now */
|
||||
#if (INCLUDE_SSC_MARKS && KMP_OS_LINUX && KMP_ARCH_X86_64)
|
||||
// Portable (at least for gcc and icc) code to insert the necessary instructions
|
||||
// to set %ebx and execute the unlikely no-op.
|
||||
#if defined(__INTEL_COMPILER)
|
||||
#define INSERT_SSC_MARK(tag) __SSC_MARK(tag)
|
||||
#else
|
||||
#define INSERT_SSC_MARK(tag) \
|
||||
__asm__ __volatile__("movl %0, %%ebx; .byte 0x64, 0x67, 0x90 " ::"i"(tag) \
|
||||
: "%ebx")
|
||||
#endif
|
||||
#else
|
||||
#define INSERT_SSC_MARK(tag) ((void)0)
|
||||
#endif
|
||||
|
||||
/* Markers for the start and end of regions that represent polling and
|
||||
* are therefore uninteresting to architectural simulations 0x4376 and
|
||||
* 0x4377 are arbitrary numbers that should be unique in the space of
|
||||
* SSC tags, but there is no central issuing authority rather
|
||||
* randomness is expected to work.
|
||||
*/
|
||||
#define SSC_MARK_SPIN_START() INSERT_SSC_MARK(0x4376)
|
||||
#define SSC_MARK_SPIN_END() INSERT_SSC_MARK(0x4377)
|
||||
/* Markers for the start and end of regions that represent polling and are
|
||||
therefore uninteresting to architectural simulations 0x4376 and 0x4377 are
|
||||
arbitrary numbers that should be unique in the space of SSC tags, but there
|
||||
is no central issuing authority rather randomness is expected to work. */
|
||||
#define SSC_MARK_SPIN_START() INSERT_SSC_MARK(0x4376)
|
||||
#define SSC_MARK_SPIN_END() INSERT_SSC_MARK(0x4377)
|
||||
|
||||
// Markers for architecture simulation.
|
||||
// FORKING : Before the master thread forks.
|
||||
// JOINING : At the start of the join.
|
||||
// INVOKING : Before the threads invoke microtasks.
|
||||
// DISPATCH_INIT: At the start of dynamically scheduled loop.
|
||||
// DISPATCH_NEXT: After claming next iteration of dynamically scheduled loop.
|
||||
#define SSC_MARK_FORKING() INSERT_SSC_MARK(0xd693)
|
||||
#define SSC_MARK_JOINING() INSERT_SSC_MARK(0xd694)
|
||||
#define SSC_MARK_INVOKING() INSERT_SSC_MARK(0xd695)
|
||||
#define SSC_MARK_DISPATCH_INIT() INSERT_SSC_MARK(0xd696)
|
||||
#define SSC_MARK_DISPATCH_NEXT() INSERT_SSC_MARK(0xd697)
|
||||
// Markers for architecture simulation.
|
||||
// FORKING : Before the master thread forks.
|
||||
// JOINING : At the start of the join.
|
||||
// INVOKING : Before the threads invoke microtasks.
|
||||
// DISPATCH_INIT: At the start of dynamically scheduled loop.
|
||||
// DISPATCH_NEXT: After claming next iteration of dynamically scheduled loop.
|
||||
#define SSC_MARK_FORKING() INSERT_SSC_MARK(0xd693)
|
||||
#define SSC_MARK_JOINING() INSERT_SSC_MARK(0xd694)
|
||||
#define SSC_MARK_INVOKING() INSERT_SSC_MARK(0xd695)
|
||||
#define SSC_MARK_DISPATCH_INIT() INSERT_SSC_MARK(0xd696)
|
||||
#define SSC_MARK_DISPATCH_NEXT() INSERT_SSC_MARK(0xd697)
|
||||
|
||||
// The object is an address that associates a specific set of the prepare, acquire, release,
|
||||
// and cancel operations.
|
||||
// The object is an address that associates a specific set of the prepare,
|
||||
// acquire, release, and cancel operations.
|
||||
|
||||
/* Sync prepare indicates a thread is going to start waiting for another thread
|
||||
to send a release event. This operation should be done just before the thread
|
||||
begins checking for the existence of the release event */
|
||||
/* Sync prepare indicates a thread is going to start waiting for another thread
|
||||
to send a release event. This operation should be done just before the
|
||||
thread begins checking for the existence of the release event */
|
||||
|
||||
/* Sync cancel indicates a thread is cancelling a wait on another thread anc
|
||||
continuing execution without waiting for the other thread to release it */
|
||||
/* Sync cancel indicates a thread is cancelling a wait on another thread and
|
||||
continuing execution without waiting for the other thread to release it */
|
||||
|
||||
/* Sync acquired indicates a thread has received a release event from another
|
||||
thread and has stopped waiting. This operation must occur only after the release
|
||||
event is received. */
|
||||
/* Sync acquired indicates a thread has received a release event from another
|
||||
thread and has stopped waiting. This operation must occur only after the
|
||||
release event is received. */
|
||||
|
||||
/* Sync release indicates a thread is going to send a release event to another thread
|
||||
so it will stop waiting and continue execution. This operation must just happen before
|
||||
the release event. */
|
||||
/* Sync release indicates a thread is going to send a release event to another
|
||||
thread so it will stop waiting and continue execution. This operation must
|
||||
just happen before the release event. */
|
||||
|
||||
#define KMP_FSYNC_PREPARE( obj ) __itt_fsync_prepare( (void *)( obj ) )
|
||||
#define KMP_FSYNC_CANCEL( obj ) __itt_fsync_cancel( (void *)( obj ) )
|
||||
#define KMP_FSYNC_ACQUIRED( obj ) __itt_fsync_acquired( (void *)( obj ) )
|
||||
#define KMP_FSYNC_RELEASING( obj ) __itt_fsync_releasing( (void *)( obj ) )
|
||||
#define KMP_FSYNC_PREPARE(obj) __itt_fsync_prepare((void *)(obj))
|
||||
#define KMP_FSYNC_CANCEL(obj) __itt_fsync_cancel((void *)(obj))
|
||||
#define KMP_FSYNC_ACQUIRED(obj) __itt_fsync_acquired((void *)(obj))
|
||||
#define KMP_FSYNC_RELEASING(obj) __itt_fsync_releasing((void *)(obj))
|
||||
|
||||
/*
|
||||
In case of waiting in a spin loop, ITT wants KMP_FSYNC_PREPARE() to be called with a delay
|
||||
(and not called at all if waiting time is small). So, in spin loops, do not use
|
||||
KMP_FSYNC_PREPARE(), but use KMP_FSYNC_SPIN_INIT() (before spin loop),
|
||||
KMP_FSYNC_SPIN_PREPARE() (whithin the spin loop), and KMP_FSYNC_SPIN_ACQUIRED().
|
||||
See KMP_WAIT_YIELD() for example.
|
||||
*/
|
||||
/* In case of waiting in a spin loop, ITT wants KMP_FSYNC_PREPARE() to be called
|
||||
with a delay (and not called at all if waiting time is small). So, in spin
|
||||
loops, do not use KMP_FSYNC_PREPARE(), but use KMP_FSYNC_SPIN_INIT() (before
|
||||
spin loop), KMP_FSYNC_SPIN_PREPARE() (whithin the spin loop), and
|
||||
KMP_FSYNC_SPIN_ACQUIRED(). See KMP_WAIT_YIELD() for example. */
|
||||
|
||||
#undef KMP_FSYNC_SPIN_INIT
|
||||
#define KMP_FSYNC_SPIN_INIT( obj, spin ) \
|
||||
int sync_iters = 0; \
|
||||
if ( __itt_fsync_prepare_ptr ) { \
|
||||
if ( obj == NULL ) { \
|
||||
obj = spin; \
|
||||
} /* if */ \
|
||||
} /* if */ \
|
||||
SSC_MARK_SPIN_START()
|
||||
#undef KMP_FSYNC_SPIN_INIT
|
||||
#define KMP_FSYNC_SPIN_INIT(obj, spin) \
|
||||
int sync_iters = 0; \
|
||||
if (__itt_fsync_prepare_ptr) { \
|
||||
if (obj == NULL) { \
|
||||
obj = spin; \
|
||||
} /* if */ \
|
||||
} /* if */ \
|
||||
SSC_MARK_SPIN_START()
|
||||
|
||||
#undef KMP_FSYNC_SPIN_PREPARE
|
||||
#define KMP_FSYNC_SPIN_PREPARE( obj ) do { \
|
||||
if ( __itt_fsync_prepare_ptr && sync_iters < __kmp_itt_prepare_delay ) { \
|
||||
++ sync_iters; \
|
||||
if ( sync_iters >= __kmp_itt_prepare_delay ) { \
|
||||
KMP_FSYNC_PREPARE( (void*) obj ); \
|
||||
} /* if */ \
|
||||
} /* if */ \
|
||||
} while (0)
|
||||
#undef KMP_FSYNC_SPIN_ACQUIRED
|
||||
#define KMP_FSYNC_SPIN_ACQUIRED( obj ) do { \
|
||||
SSC_MARK_SPIN_END(); \
|
||||
if ( sync_iters >= __kmp_itt_prepare_delay ) { \
|
||||
KMP_FSYNC_ACQUIRED( (void*) obj ); \
|
||||
} /* if */ \
|
||||
} while (0)
|
||||
#undef KMP_FSYNC_SPIN_PREPARE
|
||||
#define KMP_FSYNC_SPIN_PREPARE(obj) \
|
||||
do { \
|
||||
if (__itt_fsync_prepare_ptr && sync_iters < __kmp_itt_prepare_delay) { \
|
||||
++sync_iters; \
|
||||
if (sync_iters >= __kmp_itt_prepare_delay) { \
|
||||
KMP_FSYNC_PREPARE((void *)obj); \
|
||||
} /* if */ \
|
||||
} /* if */ \
|
||||
} while (0)
|
||||
#undef KMP_FSYNC_SPIN_ACQUIRED
|
||||
#define KMP_FSYNC_SPIN_ACQUIRED(obj) \
|
||||
do { \
|
||||
SSC_MARK_SPIN_END(); \
|
||||
if (sync_iters >= __kmp_itt_prepare_delay) { \
|
||||
KMP_FSYNC_ACQUIRED((void *)obj); \
|
||||
} /* if */ \
|
||||
} while (0)
|
||||
|
||||
/* ITT will not report objects created within KMP_ITT_IGNORE(), e. g.:
|
||||
KMP_ITT_IGNORE(
|
||||
ptr = malloc( size );
|
||||
);
|
||||
*/
|
||||
#define KMP_ITT_IGNORE( statement ) do { \
|
||||
__itt_state_t __itt_state_; \
|
||||
if ( __itt_state_get_ptr ) { \
|
||||
__itt_state_ = __itt_state_get(); \
|
||||
__itt_obj_mode_set( __itt_obj_prop_ignore, __itt_obj_state_set ); \
|
||||
} /* if */ \
|
||||
{ statement } \
|
||||
if ( __itt_state_get_ptr ) { \
|
||||
__itt_state_set( __itt_state_ ); \
|
||||
} /* if */ \
|
||||
} while (0)
|
||||
/* ITT will not report objects created within KMP_ITT_IGNORE(), e. g.:
|
||||
KMP_ITT_IGNORE(
|
||||
ptr = malloc( size );
|
||||
);
|
||||
*/
|
||||
#define KMP_ITT_IGNORE(statement) \
|
||||
do { \
|
||||
__itt_state_t __itt_state_; \
|
||||
if (__itt_state_get_ptr) { \
|
||||
__itt_state_ = __itt_state_get(); \
|
||||
__itt_obj_mode_set(__itt_obj_prop_ignore, __itt_obj_state_set); \
|
||||
} /* if */ \
|
||||
{ statement } \
|
||||
if (__itt_state_get_ptr) { \
|
||||
__itt_state_set(__itt_state_); \
|
||||
} /* if */ \
|
||||
} while (0)
|
||||
|
||||
const int KMP_MAX_FRAME_DOMAINS = 512; // Maximum number of frame domains to use (maps to
|
||||
// different OpenMP regions in the user source code).
|
||||
extern kmp_int32 __kmp_barrier_domain_count;
|
||||
extern kmp_int32 __kmp_region_domain_count;
|
||||
extern __itt_domain* __kmp_itt_barrier_domains[KMP_MAX_FRAME_DOMAINS];
|
||||
extern __itt_domain* __kmp_itt_region_domains[KMP_MAX_FRAME_DOMAINS];
|
||||
extern __itt_domain* __kmp_itt_imbalance_domains[KMP_MAX_FRAME_DOMAINS];
|
||||
extern kmp_int32 __kmp_itt_region_team_size[KMP_MAX_FRAME_DOMAINS];
|
||||
extern __itt_domain * metadata_domain;
|
||||
extern __itt_string_handle * string_handle_imbl;
|
||||
extern __itt_string_handle * string_handle_loop;
|
||||
extern __itt_string_handle * string_handle_sngl;
|
||||
const int KMP_MAX_FRAME_DOMAINS =
|
||||
512; // Maximum number of frame domains to use (maps to
|
||||
// different OpenMP regions in the user source code).
|
||||
extern kmp_int32 __kmp_barrier_domain_count;
|
||||
extern kmp_int32 __kmp_region_domain_count;
|
||||
extern __itt_domain *__kmp_itt_barrier_domains[KMP_MAX_FRAME_DOMAINS];
|
||||
extern __itt_domain *__kmp_itt_region_domains[KMP_MAX_FRAME_DOMAINS];
|
||||
extern __itt_domain *__kmp_itt_imbalance_domains[KMP_MAX_FRAME_DOMAINS];
|
||||
extern kmp_int32 __kmp_itt_region_team_size[KMP_MAX_FRAME_DOMAINS];
|
||||
extern __itt_domain *metadata_domain;
|
||||
extern __itt_string_handle *string_handle_imbl;
|
||||
extern __itt_string_handle *string_handle_loop;
|
||||
extern __itt_string_handle *string_handle_sngl;
|
||||
|
||||
#else
|
||||
|
||||
// Null definitions of the synchronization tracing functions.
|
||||
# define KMP_FSYNC_PREPARE( obj ) ((void)0)
|
||||
# define KMP_FSYNC_CANCEL( obj ) ((void)0)
|
||||
# define KMP_FSYNC_ACQUIRED( obj ) ((void)0)
|
||||
# define KMP_FSYNC_RELEASING( obj ) ((void)0)
|
||||
#define KMP_FSYNC_PREPARE(obj) ((void)0)
|
||||
#define KMP_FSYNC_CANCEL(obj) ((void)0)
|
||||
#define KMP_FSYNC_ACQUIRED(obj) ((void)0)
|
||||
#define KMP_FSYNC_RELEASING(obj) ((void)0)
|
||||
|
||||
# define KMP_FSYNC_SPIN_INIT( obj, spin ) ((void)0)
|
||||
# define KMP_FSYNC_SPIN_PREPARE( obj ) ((void)0)
|
||||
# define KMP_FSYNC_SPIN_ACQUIRED( obj ) ((void)0)
|
||||
#define KMP_FSYNC_SPIN_INIT(obj, spin) ((void)0)
|
||||
#define KMP_FSYNC_SPIN_PREPARE(obj) ((void)0)
|
||||
#define KMP_FSYNC_SPIN_ACQUIRED(obj) ((void)0)
|
||||
|
||||
# define KMP_ITT_IGNORE(stmt ) do { stmt } while (0)
|
||||
#define KMP_ITT_IGNORE(stmt) \
|
||||
do { \
|
||||
stmt \
|
||||
} while (0)
|
||||
|
||||
#endif // USE_ITT_NOTIFY
|
||||
|
||||
#if ! KMP_DEBUG
|
||||
// In release mode include definitions of inline functions.
|
||||
#include "kmp_itt.inl"
|
||||
#if !KMP_DEBUG
|
||||
// In release mode include definitions of inline functions.
|
||||
#include "kmp_itt.inl"
|
||||
#endif
|
||||
|
||||
#endif // KMP_ITT_H
|
||||
|
||||
#else /* USE_ITT_BUILD */
|
||||
#else /* USE_ITT_BUILD */
|
||||
|
||||
// Null definitions of the synchronization tracing functions.
|
||||
// If USE_ITT_BULID is not enabled, USE_ITT_NOTIFY cannot be either.
|
||||
// By defining these we avoid unpleasant ifdef tests in many places.
|
||||
# define KMP_FSYNC_PREPARE( obj ) ((void)0)
|
||||
# define KMP_FSYNC_CANCEL( obj ) ((void)0)
|
||||
# define KMP_FSYNC_ACQUIRED( obj ) ((void)0)
|
||||
# define KMP_FSYNC_RELEASING( obj ) ((void)0)
|
||||
#define KMP_FSYNC_PREPARE(obj) ((void)0)
|
||||
#define KMP_FSYNC_CANCEL(obj) ((void)0)
|
||||
#define KMP_FSYNC_ACQUIRED(obj) ((void)0)
|
||||
#define KMP_FSYNC_RELEASING(obj) ((void)0)
|
||||
|
||||
# define KMP_FSYNC_SPIN_INIT( obj, spin ) ((void)0)
|
||||
# define KMP_FSYNC_SPIN_PREPARE( obj ) ((void)0)
|
||||
# define KMP_FSYNC_SPIN_ACQUIRED( obj ) ((void)0)
|
||||
#define KMP_FSYNC_SPIN_INIT(obj, spin) ((void)0)
|
||||
#define KMP_FSYNC_SPIN_PREPARE(obj) ((void)0)
|
||||
#define KMP_FSYNC_SPIN_ACQUIRED(obj) ((void)0)
|
||||
|
||||
# define KMP_ITT_IGNORE(stmt ) do { stmt } while (0)
|
||||
#define KMP_ITT_IGNORE(stmt) \
|
||||
do { \
|
||||
stmt \
|
||||
} while (0)
|
||||
|
||||
# define USE_ITT_BUILD_ARG(x)
|
||||
#define USE_ITT_BUILD_ARG(x)
|
||||
|
||||
#endif /* USE_ITT_BUILD */
|
||||
|
||||
+786
-890
File diff suppressed because it is too large
Load Diff
+2997
-3390
File diff suppressed because it is too large
Load Diff
+717
-741
File diff suppressed because it is too large
Load Diff
+173
-165
@@ -16,216 +16,224 @@
|
||||
|
||||
|
||||
/* THIS FILE SHOULD NOT BE MODIFIED IN IDB INTERFACE LIBRARY CODE
|
||||
* It should instead be modified in the OpenMP runtime and copied
|
||||
* to the interface library code. This way we can minimize the
|
||||
* problems that this is sure to cause having two copies of the
|
||||
* same file.
|
||||
*
|
||||
* files live in libomp and libomp_db/src/include
|
||||
*/
|
||||
It should instead be modified in the OpenMP runtime and copied to the
|
||||
interface library code. This way we can minimize the problems that this is
|
||||
sure to cause having two copies of the same file.
|
||||
|
||||
Files live in libomp and libomp_db/src/include */
|
||||
|
||||
/* CHANGE THIS WHEN STRUCTURES BELOW CHANGE
|
||||
* Before we release this to a customer, please don't change this value. After it is released and
|
||||
* stable, then any new updates to the structures or data structure traversal algorithms need to
|
||||
* change this value.
|
||||
*/
|
||||
Before we release this to a customer, please don't change this value. After
|
||||
it is released and stable, then any new updates to the structures or data
|
||||
structure traversal algorithms need to change this value. */
|
||||
#define KMP_OMP_VERSION 9
|
||||
|
||||
typedef struct {
|
||||
kmp_int32 offset;
|
||||
kmp_int32 size;
|
||||
kmp_int32 offset;
|
||||
kmp_int32 size;
|
||||
} offset_and_size_t;
|
||||
|
||||
typedef struct {
|
||||
kmp_uint64 addr;
|
||||
kmp_int32 size;
|
||||
kmp_int32 padding;
|
||||
kmp_uint64 addr;
|
||||
kmp_int32 size;
|
||||
kmp_int32 padding;
|
||||
} addr_and_size_t;
|
||||
|
||||
typedef struct {
|
||||
kmp_uint64 flags; // Flags for future extensions.
|
||||
kmp_uint64 file; // Pointer to name of source file where the parallel region is.
|
||||
kmp_uint64 func; // Pointer to name of routine where the parallel region is.
|
||||
kmp_int32 begin; // Beginning of source line range.
|
||||
kmp_int32 end; // End of source line range.
|
||||
kmp_int32 num_threads; // Specified number of threads.
|
||||
kmp_uint64 flags; // Flags for future extensions.
|
||||
kmp_uint64
|
||||
file; // Pointer to name of source file where the parallel region is.
|
||||
kmp_uint64 func; // Pointer to name of routine where the parallel region is.
|
||||
kmp_int32 begin; // Beginning of source line range.
|
||||
kmp_int32 end; // End of source line range.
|
||||
kmp_int32 num_threads; // Specified number of threads.
|
||||
} kmp_omp_nthr_item_t;
|
||||
|
||||
typedef struct {
|
||||
kmp_int32 num; // Number of items in the arrray.
|
||||
kmp_uint64 array; // Address of array of kmp_omp_num_threads_item_t.
|
||||
kmp_int32 num; // Number of items in the arrray.
|
||||
kmp_uint64 array; // Address of array of kmp_omp_num_threads_item_t.
|
||||
} kmp_omp_nthr_info_t;
|
||||
|
||||
|
||||
/* This structure is known to the idb interface library */
|
||||
typedef struct {
|
||||
|
||||
/* Change this only if you make a fundamental data structure change here */
|
||||
kmp_int32 lib_version;
|
||||
/* Change this only if you make a fundamental data structure change here */
|
||||
kmp_int32 lib_version;
|
||||
|
||||
/* sanity check. Only should be checked if versions are identical
|
||||
* This is also used for backward compatibility to get the runtime
|
||||
* structure size if it the runtime is older than the interface */
|
||||
kmp_int32 sizeof_this_structure;
|
||||
/* sanity check. Only should be checked if versions are identical
|
||||
* This is also used for backward compatibility to get the runtime
|
||||
* structure size if it the runtime is older than the interface */
|
||||
kmp_int32 sizeof_this_structure;
|
||||
|
||||
/* OpenMP RTL version info. */
|
||||
addr_and_size_t major;
|
||||
addr_and_size_t minor;
|
||||
addr_and_size_t build;
|
||||
addr_and_size_t openmp_version;
|
||||
addr_and_size_t banner;
|
||||
/* OpenMP RTL version info. */
|
||||
addr_and_size_t major;
|
||||
addr_and_size_t minor;
|
||||
addr_and_size_t build;
|
||||
addr_and_size_t openmp_version;
|
||||
addr_and_size_t banner;
|
||||
|
||||
/* Various globals. */
|
||||
addr_and_size_t threads; // Pointer to __kmp_threads.
|
||||
addr_and_size_t roots; // Pointer to __kmp_root.
|
||||
addr_and_size_t capacity; // Pointer to __kmp_threads_capacity.
|
||||
addr_and_size_t monitor; // Pointer to __kmp_monitor.
|
||||
#if ! KMP_USE_DYNAMIC_LOCK
|
||||
addr_and_size_t lock_table; // Pointer to __kmp_lock_table.
|
||||
/* Various globals. */
|
||||
addr_and_size_t threads; // Pointer to __kmp_threads.
|
||||
addr_and_size_t roots; // Pointer to __kmp_root.
|
||||
addr_and_size_t capacity; // Pointer to __kmp_threads_capacity.
|
||||
addr_and_size_t monitor; // Pointer to __kmp_monitor.
|
||||
#if !KMP_USE_DYNAMIC_LOCK
|
||||
addr_and_size_t lock_table; // Pointer to __kmp_lock_table.
|
||||
#endif
|
||||
addr_and_size_t func_microtask;
|
||||
addr_and_size_t func_fork;
|
||||
addr_and_size_t func_fork_teams;
|
||||
addr_and_size_t team_counter;
|
||||
addr_and_size_t task_counter;
|
||||
addr_and_size_t nthr_info;
|
||||
kmp_int32 address_width;
|
||||
kmp_int32 indexed_locks;
|
||||
kmp_int32 last_barrier; // The end in enum barrier_type
|
||||
kmp_int32 deque_size; // TASK_DEQUE_SIZE
|
||||
addr_and_size_t func_microtask;
|
||||
addr_and_size_t func_fork;
|
||||
addr_and_size_t func_fork_teams;
|
||||
addr_and_size_t team_counter;
|
||||
addr_and_size_t task_counter;
|
||||
addr_and_size_t nthr_info;
|
||||
kmp_int32 address_width;
|
||||
kmp_int32 indexed_locks;
|
||||
kmp_int32 last_barrier; // The end in enum barrier_type
|
||||
kmp_int32 deque_size; // TASK_DEQUE_SIZE
|
||||
|
||||
/* thread structure information. */
|
||||
kmp_int32 th_sizeof_struct;
|
||||
offset_and_size_t th_info; // descriptor for thread
|
||||
offset_and_size_t th_team; // team for this thread
|
||||
offset_and_size_t th_root; // root for this thread
|
||||
offset_and_size_t th_serial_team; // serial team under this thread
|
||||
offset_and_size_t th_ident; // location for this thread (if available)
|
||||
offset_and_size_t th_spin_here; // is thread waiting for lock (if available)
|
||||
offset_and_size_t th_next_waiting; // next thread waiting for lock (if available)
|
||||
offset_and_size_t th_task_team; // task team struct
|
||||
offset_and_size_t th_current_task; // innermost task being executed
|
||||
offset_and_size_t th_task_state; // alternating 0/1 for task team identification
|
||||
offset_and_size_t th_bar;
|
||||
offset_and_size_t th_b_worker_arrived; // the worker increases it by 1 when it arrives to the barrier
|
||||
/* thread structure information. */
|
||||
kmp_int32 th_sizeof_struct;
|
||||
offset_and_size_t th_info; // descriptor for thread
|
||||
offset_and_size_t th_team; // team for this thread
|
||||
offset_and_size_t th_root; // root for this thread
|
||||
offset_and_size_t th_serial_team; // serial team under this thread
|
||||
offset_and_size_t th_ident; // location for this thread (if available)
|
||||
offset_and_size_t th_spin_here; // is thread waiting for lock (if available)
|
||||
offset_and_size_t
|
||||
th_next_waiting; // next thread waiting for lock (if available)
|
||||
offset_and_size_t th_task_team; // task team struct
|
||||
offset_and_size_t th_current_task; // innermost task being executed
|
||||
offset_and_size_t
|
||||
th_task_state; // alternating 0/1 for task team identification
|
||||
offset_and_size_t th_bar;
|
||||
offset_and_size_t th_b_worker_arrived; // the worker increases it by 1 when it
|
||||
// arrives to the barrier
|
||||
|
||||
#if OMP_40_ENABLED
|
||||
/* teams information */
|
||||
offset_and_size_t th_teams_microtask;// entry address for teams construct
|
||||
offset_and_size_t th_teams_level; // initial level of teams construct
|
||||
offset_and_size_t th_teams_nteams; // number of teams in a league
|
||||
offset_and_size_t th_teams_nth; // number of threads in each team of the league
|
||||
/* teams information */
|
||||
offset_and_size_t th_teams_microtask; // entry address for teams construct
|
||||
offset_and_size_t th_teams_level; // initial level of teams construct
|
||||
offset_and_size_t th_teams_nteams; // number of teams in a league
|
||||
offset_and_size_t
|
||||
th_teams_nth; // number of threads in each team of the league
|
||||
#endif
|
||||
|
||||
/* kmp_desc structure (for info field above) */
|
||||
kmp_int32 ds_sizeof_struct;
|
||||
offset_and_size_t ds_tid; // team thread id
|
||||
offset_and_size_t ds_gtid; // global thread id
|
||||
offset_and_size_t ds_thread; // native thread id
|
||||
/* kmp_desc structure (for info field above) */
|
||||
kmp_int32 ds_sizeof_struct;
|
||||
offset_and_size_t ds_tid; // team thread id
|
||||
offset_and_size_t ds_gtid; // global thread id
|
||||
offset_and_size_t ds_thread; // native thread id
|
||||
|
||||
/* team structure information */
|
||||
kmp_int32 t_sizeof_struct;
|
||||
offset_and_size_t t_master_tid; // tid of master in parent team
|
||||
offset_and_size_t t_ident; // location of parallel region
|
||||
offset_and_size_t t_parent; // parent team
|
||||
offset_and_size_t t_nproc; // # team threads
|
||||
offset_and_size_t t_threads; // array of threads
|
||||
offset_and_size_t t_serialized; // # levels of serialized teams
|
||||
offset_and_size_t t_id; // unique team id
|
||||
offset_and_size_t t_pkfn;
|
||||
offset_and_size_t t_task_team; // task team structure
|
||||
offset_and_size_t t_implicit_task; // taskdata for the thread's implicit task
|
||||
/* team structure information */
|
||||
kmp_int32 t_sizeof_struct;
|
||||
offset_and_size_t t_master_tid; // tid of master in parent team
|
||||
offset_and_size_t t_ident; // location of parallel region
|
||||
offset_and_size_t t_parent; // parent team
|
||||
offset_and_size_t t_nproc; // # team threads
|
||||
offset_and_size_t t_threads; // array of threads
|
||||
offset_and_size_t t_serialized; // # levels of serialized teams
|
||||
offset_and_size_t t_id; // unique team id
|
||||
offset_and_size_t t_pkfn;
|
||||
offset_and_size_t t_task_team; // task team structure
|
||||
offset_and_size_t t_implicit_task; // taskdata for the thread's implicit task
|
||||
#if OMP_40_ENABLED
|
||||
offset_and_size_t t_cancel_request;
|
||||
offset_and_size_t t_cancel_request;
|
||||
#endif
|
||||
offset_and_size_t t_bar;
|
||||
offset_and_size_t t_b_master_arrived; // increased by 1 when master arrives to a barrier
|
||||
offset_and_size_t t_b_team_arrived; // increased by one when all the threads arrived
|
||||
offset_and_size_t t_bar;
|
||||
offset_and_size_t
|
||||
t_b_master_arrived; // increased by 1 when master arrives to a barrier
|
||||
offset_and_size_t
|
||||
t_b_team_arrived; // increased by one when all the threads arrived
|
||||
|
||||
/* root structure information */
|
||||
kmp_int32 r_sizeof_struct;
|
||||
offset_and_size_t r_root_team; // team at root
|
||||
offset_and_size_t r_hot_team; // hot team for this root
|
||||
offset_and_size_t r_uber_thread; // root thread
|
||||
offset_and_size_t r_root_id; // unique root id (if available)
|
||||
/* root structure information */
|
||||
kmp_int32 r_sizeof_struct;
|
||||
offset_and_size_t r_root_team; // team at root
|
||||
offset_and_size_t r_hot_team; // hot team for this root
|
||||
offset_and_size_t r_uber_thread; // root thread
|
||||
offset_and_size_t r_root_id; // unique root id (if available)
|
||||
|
||||
/* ident structure information */
|
||||
kmp_int32 id_sizeof_struct;
|
||||
offset_and_size_t id_psource; /* address of string ";file;func;line1;line2;;". */
|
||||
offset_and_size_t id_flags;
|
||||
/* ident structure information */
|
||||
kmp_int32 id_sizeof_struct;
|
||||
offset_and_size_t
|
||||
id_psource; /* address of string ";file;func;line1;line2;;". */
|
||||
offset_and_size_t id_flags;
|
||||
|
||||
/* lock structure information */
|
||||
kmp_int32 lk_sizeof_struct;
|
||||
offset_and_size_t lk_initialized;
|
||||
offset_and_size_t lk_location;
|
||||
offset_and_size_t lk_tail_id;
|
||||
offset_and_size_t lk_head_id;
|
||||
offset_and_size_t lk_next_ticket;
|
||||
offset_and_size_t lk_now_serving;
|
||||
offset_and_size_t lk_owner_id;
|
||||
offset_and_size_t lk_depth_locked;
|
||||
offset_and_size_t lk_lock_flags;
|
||||
/* lock structure information */
|
||||
kmp_int32 lk_sizeof_struct;
|
||||
offset_and_size_t lk_initialized;
|
||||
offset_and_size_t lk_location;
|
||||
offset_and_size_t lk_tail_id;
|
||||
offset_and_size_t lk_head_id;
|
||||
offset_and_size_t lk_next_ticket;
|
||||
offset_and_size_t lk_now_serving;
|
||||
offset_and_size_t lk_owner_id;
|
||||
offset_and_size_t lk_depth_locked;
|
||||
offset_and_size_t lk_lock_flags;
|
||||
|
||||
#if ! KMP_USE_DYNAMIC_LOCK
|
||||
/* lock_table_t */
|
||||
kmp_int32 lt_size_of_struct; /* Size and layout of kmp_lock_table_t. */
|
||||
offset_and_size_t lt_used;
|
||||
offset_and_size_t lt_allocated;
|
||||
offset_and_size_t lt_table;
|
||||
#if !KMP_USE_DYNAMIC_LOCK
|
||||
/* lock_table_t */
|
||||
kmp_int32 lt_size_of_struct; /* Size and layout of kmp_lock_table_t. */
|
||||
offset_and_size_t lt_used;
|
||||
offset_and_size_t lt_allocated;
|
||||
offset_and_size_t lt_table;
|
||||
#endif
|
||||
|
||||
/* task_team_t */
|
||||
kmp_int32 tt_sizeof_struct;
|
||||
offset_and_size_t tt_threads_data;
|
||||
offset_and_size_t tt_found_tasks;
|
||||
offset_and_size_t tt_nproc;
|
||||
offset_and_size_t tt_unfinished_threads;
|
||||
offset_and_size_t tt_active;
|
||||
/* task_team_t */
|
||||
kmp_int32 tt_sizeof_struct;
|
||||
offset_and_size_t tt_threads_data;
|
||||
offset_and_size_t tt_found_tasks;
|
||||
offset_and_size_t tt_nproc;
|
||||
offset_and_size_t tt_unfinished_threads;
|
||||
offset_and_size_t tt_active;
|
||||
|
||||
/* kmp_taskdata_t */
|
||||
kmp_int32 td_sizeof_struct;
|
||||
offset_and_size_t td_task_id; // task id
|
||||
offset_and_size_t td_flags; // task flags
|
||||
offset_and_size_t td_team; // team for this task
|
||||
offset_and_size_t td_parent; // parent task
|
||||
offset_and_size_t td_level; // task testing level
|
||||
offset_and_size_t td_ident; // task identifier
|
||||
offset_and_size_t td_allocated_child_tasks; // child tasks (+ current task) not yet deallocated
|
||||
offset_and_size_t td_incomplete_child_tasks; // child tasks not yet complete
|
||||
/* kmp_taskdata_t */
|
||||
kmp_int32 td_sizeof_struct;
|
||||
offset_and_size_t td_task_id; // task id
|
||||
offset_and_size_t td_flags; // task flags
|
||||
offset_and_size_t td_team; // team for this task
|
||||
offset_and_size_t td_parent; // parent task
|
||||
offset_and_size_t td_level; // task testing level
|
||||
offset_and_size_t td_ident; // task identifier
|
||||
offset_and_size_t td_allocated_child_tasks; // child tasks (+ current task)
|
||||
// not yet deallocated
|
||||
offset_and_size_t td_incomplete_child_tasks; // child tasks not yet complete
|
||||
|
||||
/* Taskwait */
|
||||
offset_and_size_t td_taskwait_ident;
|
||||
offset_and_size_t td_taskwait_counter;
|
||||
offset_and_size_t td_taskwait_thread; // gtid + 1 of thread encountered taskwait
|
||||
/* Taskwait */
|
||||
offset_and_size_t td_taskwait_ident;
|
||||
offset_and_size_t td_taskwait_counter;
|
||||
offset_and_size_t
|
||||
td_taskwait_thread; // gtid + 1 of thread encountered taskwait
|
||||
|
||||
#if OMP_40_ENABLED
|
||||
/* Taskgroup */
|
||||
offset_and_size_t td_taskgroup; // pointer to the current taskgroup
|
||||
offset_and_size_t td_task_count; // number of allocated and not yet complete tasks
|
||||
offset_and_size_t td_cancel; // request for cancellation of this taskgroup
|
||||
/* Taskgroup */
|
||||
offset_and_size_t td_taskgroup; // pointer to the current taskgroup
|
||||
offset_and_size_t
|
||||
td_task_count; // number of allocated and not yet complete tasks
|
||||
offset_and_size_t td_cancel; // request for cancellation of this taskgroup
|
||||
|
||||
/* Task dependency */
|
||||
offset_and_size_t td_depnode; // pointer to graph node if the task has dependencies
|
||||
offset_and_size_t dn_node;
|
||||
offset_and_size_t dn_next;
|
||||
offset_and_size_t dn_successors;
|
||||
offset_and_size_t dn_task;
|
||||
offset_and_size_t dn_npredecessors;
|
||||
offset_and_size_t dn_nrefs;
|
||||
/* Task dependency */
|
||||
offset_and_size_t
|
||||
td_depnode; // pointer to graph node if the task has dependencies
|
||||
offset_and_size_t dn_node;
|
||||
offset_and_size_t dn_next;
|
||||
offset_and_size_t dn_successors;
|
||||
offset_and_size_t dn_task;
|
||||
offset_and_size_t dn_npredecessors;
|
||||
offset_and_size_t dn_nrefs;
|
||||
#endif
|
||||
offset_and_size_t dn_routine;
|
||||
offset_and_size_t dn_routine;
|
||||
|
||||
/* kmp_thread_data_t */
|
||||
kmp_int32 hd_sizeof_struct;
|
||||
offset_and_size_t hd_deque;
|
||||
offset_and_size_t hd_deque_size;
|
||||
offset_and_size_t hd_deque_head;
|
||||
offset_and_size_t hd_deque_tail;
|
||||
offset_and_size_t hd_deque_ntasks;
|
||||
offset_and_size_t hd_deque_last_stolen;
|
||||
/* kmp_thread_data_t */
|
||||
kmp_int32 hd_sizeof_struct;
|
||||
offset_and_size_t hd_deque;
|
||||
offset_and_size_t hd_deque_size;
|
||||
offset_and_size_t hd_deque_head;
|
||||
offset_and_size_t hd_deque_tail;
|
||||
offset_and_size_t hd_deque_ntasks;
|
||||
offset_and_size_t hd_deque_last_stolen;
|
||||
|
||||
// The last field of stable version.
|
||||
kmp_uint64 last_field;
|
||||
// The last field of stable version.
|
||||
kmp_uint64 last_field;
|
||||
|
||||
} kmp_omp_struct_info_t;
|
||||
|
||||
|
||||
+606
-464
File diff suppressed because it is too large
Load Diff
+110
-101
@@ -2,6 +2,7 @@
|
||||
* kmp_platform.h -- header for determining operating system and architecture
|
||||
*/
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
@@ -11,171 +12,179 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
#ifndef KMP_PLATFORM_H
|
||||
#define KMP_PLATFORM_H
|
||||
|
||||
/* ---------------------- Operating system recognition ------------------- */
|
||||
|
||||
#define KMP_OS_LINUX 0
|
||||
#define KMP_OS_FREEBSD 0
|
||||
#define KMP_OS_NETBSD 0
|
||||
#define KMP_OS_DARWIN 0
|
||||
#define KMP_OS_WINDOWS 0
|
||||
#define KMP_OS_CNK 0
|
||||
#define KMP_OS_UNIX 0 /* disjunction of KMP_OS_LINUX, KMP_OS_DARWIN etc. */
|
||||
|
||||
#define KMP_OS_LINUX 0
|
||||
#define KMP_OS_FREEBSD 0
|
||||
#define KMP_OS_NETBSD 0
|
||||
#define KMP_OS_DARWIN 0
|
||||
#define KMP_OS_WINDOWS 0
|
||||
#define KMP_OS_CNK 0
|
||||
#define KMP_OS_UNIX 0 /* disjunction of KMP_OS_LINUX, KMP_OS_DARWIN etc. */
|
||||
|
||||
#ifdef _WIN32
|
||||
# undef KMP_OS_WINDOWS
|
||||
# define KMP_OS_WINDOWS 1
|
||||
#undef KMP_OS_WINDOWS
|
||||
#define KMP_OS_WINDOWS 1
|
||||
#endif
|
||||
|
||||
#if ( defined __APPLE__ && defined __MACH__ )
|
||||
# undef KMP_OS_DARWIN
|
||||
# define KMP_OS_DARWIN 1
|
||||
#if (defined __APPLE__ && defined __MACH__)
|
||||
#undef KMP_OS_DARWIN
|
||||
#define KMP_OS_DARWIN 1
|
||||
#endif
|
||||
|
||||
// in some ppc64 linux installations, only the second condition is met
|
||||
#if ( defined __linux )
|
||||
# undef KMP_OS_LINUX
|
||||
# define KMP_OS_LINUX 1
|
||||
#elif ( defined __linux__)
|
||||
# undef KMP_OS_LINUX
|
||||
# define KMP_OS_LINUX 1
|
||||
#if (defined __linux)
|
||||
#undef KMP_OS_LINUX
|
||||
#define KMP_OS_LINUX 1
|
||||
#elif (defined __linux__)
|
||||
#undef KMP_OS_LINUX
|
||||
#define KMP_OS_LINUX 1
|
||||
#else
|
||||
#endif
|
||||
|
||||
#if ( defined __FreeBSD__ )
|
||||
# undef KMP_OS_FREEBSD
|
||||
# define KMP_OS_FREEBSD 1
|
||||
#if (defined __FreeBSD__)
|
||||
#undef KMP_OS_FREEBSD
|
||||
#define KMP_OS_FREEBSD 1
|
||||
#endif
|
||||
|
||||
#if ( defined __NetBSD__ )
|
||||
# undef KMP_OS_NETBSD
|
||||
# define KMP_OS_NETBSD 1
|
||||
#if (defined __NetBSD__)
|
||||
#undef KMP_OS_NETBSD
|
||||
#define KMP_OS_NETBSD 1
|
||||
#endif
|
||||
|
||||
#if ( defined __bgq__ )
|
||||
# undef KMP_OS_CNK
|
||||
# define KMP_OS_CNK 1
|
||||
#if (defined __bgq__)
|
||||
#undef KMP_OS_CNK
|
||||
#define KMP_OS_CNK 1
|
||||
#endif
|
||||
|
||||
#if (1 != KMP_OS_LINUX + KMP_OS_FREEBSD + KMP_OS_NETBSD + KMP_OS_DARWIN + KMP_OS_WINDOWS)
|
||||
# error Unknown OS
|
||||
#if (1 != \
|
||||
KMP_OS_LINUX + KMP_OS_FREEBSD + KMP_OS_NETBSD + KMP_OS_DARWIN + \
|
||||
KMP_OS_WINDOWS)
|
||||
#error Unknown OS
|
||||
#endif
|
||||
|
||||
#if KMP_OS_LINUX || KMP_OS_FREEBSD || KMP_OS_NETBSD || KMP_OS_DARWIN
|
||||
# undef KMP_OS_UNIX
|
||||
# define KMP_OS_UNIX 1
|
||||
#undef KMP_OS_UNIX
|
||||
#define KMP_OS_UNIX 1
|
||||
#endif
|
||||
|
||||
/* ---------------------- Architecture recognition ------------------- */
|
||||
|
||||
#define KMP_ARCH_X86 0
|
||||
#define KMP_ARCH_X86_64 0
|
||||
#define KMP_ARCH_AARCH64 0
|
||||
#define KMP_ARCH_PPC64_BE 0
|
||||
#define KMP_ARCH_PPC64_LE 0
|
||||
#define KMP_ARCH_X86 0
|
||||
#define KMP_ARCH_X86_64 0
|
||||
#define KMP_ARCH_AARCH64 0
|
||||
#define KMP_ARCH_PPC64_BE 0
|
||||
#define KMP_ARCH_PPC64_LE 0
|
||||
#define KMP_ARCH_PPC64 (KMP_ARCH_PPC64_LE || KMP_ARCH_PPC64_BE)
|
||||
#define KMP_ARCH_MIPS 0
|
||||
#define KMP_ARCH_MIPS64 0
|
||||
#define KMP_ARCH_MIPS 0
|
||||
#define KMP_ARCH_MIPS64 0
|
||||
|
||||
#if KMP_OS_WINDOWS
|
||||
# if defined _M_AMD64
|
||||
# undef KMP_ARCH_X86_64
|
||||
# define KMP_ARCH_X86_64 1
|
||||
# else
|
||||
# undef KMP_ARCH_X86
|
||||
# define KMP_ARCH_X86 1
|
||||
# endif
|
||||
#if defined _M_AMD64
|
||||
#undef KMP_ARCH_X86_64
|
||||
#define KMP_ARCH_X86_64 1
|
||||
#else
|
||||
#undef KMP_ARCH_X86
|
||||
#define KMP_ARCH_X86 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if KMP_OS_UNIX
|
||||
# if defined __x86_64
|
||||
# undef KMP_ARCH_X86_64
|
||||
# define KMP_ARCH_X86_64 1
|
||||
# elif defined __i386
|
||||
# undef KMP_ARCH_X86
|
||||
# define KMP_ARCH_X86 1
|
||||
# elif defined __powerpc64__
|
||||
# if defined __LITTLE_ENDIAN__
|
||||
# undef KMP_ARCH_PPC64_LE
|
||||
# define KMP_ARCH_PPC64_LE 1
|
||||
# else
|
||||
# undef KMP_ARCH_PPC64_BE
|
||||
# define KMP_ARCH_PPC64_BE 1
|
||||
# endif
|
||||
# elif defined __aarch64__
|
||||
# undef KMP_ARCH_AARCH64
|
||||
# define KMP_ARCH_AARCH64 1
|
||||
# elif defined __mips__
|
||||
# if defined __mips64
|
||||
# undef KMP_ARCH_MIPS64
|
||||
# define KMP_ARCH_MIPS64 1
|
||||
# else
|
||||
# undef KMP_ARCH_MIPS
|
||||
# define KMP_ARCH_MIPS 1
|
||||
# endif
|
||||
# endif
|
||||
#if defined __x86_64
|
||||
#undef KMP_ARCH_X86_64
|
||||
#define KMP_ARCH_X86_64 1
|
||||
#elif defined __i386
|
||||
#undef KMP_ARCH_X86
|
||||
#define KMP_ARCH_X86 1
|
||||
#elif defined __powerpc64__
|
||||
#if defined __LITTLE_ENDIAN__
|
||||
#undef KMP_ARCH_PPC64_LE
|
||||
#define KMP_ARCH_PPC64_LE 1
|
||||
#else
|
||||
#undef KMP_ARCH_PPC64_BE
|
||||
#define KMP_ARCH_PPC64_BE 1
|
||||
#endif
|
||||
#elif defined __aarch64__
|
||||
#undef KMP_ARCH_AARCH64
|
||||
#define KMP_ARCH_AARCH64 1
|
||||
#elif defined __mips__
|
||||
#if defined __mips64
|
||||
#undef KMP_ARCH_MIPS64
|
||||
#define KMP_ARCH_MIPS64 1
|
||||
#else
|
||||
#undef KMP_ARCH_MIPS
|
||||
#define KMP_ARCH_MIPS 1
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7R__) || \
|
||||
#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7R__) || \
|
||||
defined(__ARM_ARCH_7A__)
|
||||
# define KMP_ARCH_ARMV7 1
|
||||
#define KMP_ARCH_ARMV7 1
|
||||
#endif
|
||||
|
||||
#if defined(KMP_ARCH_ARMV7) || defined(__ARM_ARCH_6__) || \
|
||||
defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || \
|
||||
defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6T2__) || \
|
||||
#if defined(KMP_ARCH_ARMV7) || defined(__ARM_ARCH_6__) || \
|
||||
defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || \
|
||||
defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6T2__) || \
|
||||
defined(__ARM_ARCH_6ZK__)
|
||||
# define KMP_ARCH_ARMV6 1
|
||||
#define KMP_ARCH_ARMV6 1
|
||||
#endif
|
||||
|
||||
#if defined(KMP_ARCH_ARMV6) || defined(__ARM_ARCH_5T__) || \
|
||||
defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) || \
|
||||
#if defined(KMP_ARCH_ARMV6) || defined(__ARM_ARCH_5T__) || \
|
||||
defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) || \
|
||||
defined(__ARM_ARCH_5TEJ__)
|
||||
# define KMP_ARCH_ARMV5 1
|
||||
#define KMP_ARCH_ARMV5 1
|
||||
#endif
|
||||
|
||||
#if defined(KMP_ARCH_ARMV5) || defined(__ARM_ARCH_4__) || \
|
||||
#if defined(KMP_ARCH_ARMV5) || defined(__ARM_ARCH_4__) || \
|
||||
defined(__ARM_ARCH_4T__)
|
||||
# define KMP_ARCH_ARMV4 1
|
||||
#define KMP_ARCH_ARMV4 1
|
||||
#endif
|
||||
|
||||
#if defined(KMP_ARCH_ARMV4) || defined(__ARM_ARCH_3__) || \
|
||||
#if defined(KMP_ARCH_ARMV4) || defined(__ARM_ARCH_3__) || \
|
||||
defined(__ARM_ARCH_3M__)
|
||||
# define KMP_ARCH_ARMV3 1
|
||||
#define KMP_ARCH_ARMV3 1
|
||||
#endif
|
||||
|
||||
#if defined(KMP_ARCH_ARMV3) || defined(__ARM_ARCH_2__)
|
||||
# define KMP_ARCH_ARMV2 1
|
||||
#if defined(KMP_ARCH_ARMV3) || defined(__ARM_ARCH_2__)
|
||||
#define KMP_ARCH_ARMV2 1
|
||||
#endif
|
||||
|
||||
#if defined(KMP_ARCH_ARMV2)
|
||||
# define KMP_ARCH_ARM 1
|
||||
#define KMP_ARCH_ARM 1
|
||||
#endif
|
||||
|
||||
#if defined(__MIC__) || defined(__MIC2__)
|
||||
# define KMP_MIC 1
|
||||
# if __MIC2__ || __KNC__
|
||||
# define KMP_MIC1 0
|
||||
# define KMP_MIC2 1
|
||||
# else
|
||||
# define KMP_MIC1 1
|
||||
# define KMP_MIC2 0
|
||||
# endif
|
||||
#define KMP_MIC 1
|
||||
#if __MIC2__ || __KNC__
|
||||
#define KMP_MIC1 0
|
||||
#define KMP_MIC2 1
|
||||
#else
|
||||
# define KMP_MIC 0
|
||||
# define KMP_MIC1 0
|
||||
# define KMP_MIC2 0
|
||||
#define KMP_MIC1 1
|
||||
#define KMP_MIC2 0
|
||||
#endif
|
||||
#else
|
||||
#define KMP_MIC 0
|
||||
#define KMP_MIC1 0
|
||||
#define KMP_MIC2 0
|
||||
#endif
|
||||
|
||||
/* Specify 32 bit architectures here */
|
||||
#define KMP_32_BIT_ARCH (KMP_ARCH_X86 || KMP_ARCH_ARM || KMP_ARCH_MIPS)
|
||||
|
||||
// Platforms which support Intel(R) Many Integrated Core Architecture
|
||||
#define KMP_MIC_SUPPORTED \
|
||||
((KMP_ARCH_X86 || KMP_ARCH_X86_64) && (KMP_OS_LINUX || KMP_OS_WINDOWS))
|
||||
|
||||
// TODO: Fixme - This is clever, but really fugly
|
||||
#if (1 != KMP_ARCH_X86 + KMP_ARCH_X86_64 + KMP_ARCH_ARM + KMP_ARCH_PPC64 + KMP_ARCH_AARCH64 + KMP_ARCH_MIPS + KMP_ARCH_MIPS64)
|
||||
# error Unknown or unsupported architecture
|
||||
#if (1 != \
|
||||
KMP_ARCH_X86 + KMP_ARCH_X86_64 + KMP_ARCH_ARM + KMP_ARCH_PPC64 + \
|
||||
KMP_ARCH_AARCH64 + KMP_ARCH_MIPS + KMP_ARCH_MIPS64)
|
||||
#error Unknown or unsupported architecture
|
||||
#endif
|
||||
|
||||
#endif // KMP_PLATFORM_H
|
||||
|
||||
+6026
-6087
File diff suppressed because it is too large
Load Diff
@@ -12,50 +12,49 @@
|
||||
#ifndef KMP_SAFE_C_API_H
|
||||
#define KMP_SAFE_C_API_H
|
||||
|
||||
//
|
||||
// Replacement for banned C API
|
||||
//
|
||||
|
||||
// Not every unsafe call listed here is handled now, but keeping everything
|
||||
// in one place should be handy for future maintenance.
|
||||
#if KMP_OS_WINDOWS
|
||||
|
||||
# define RSIZE_MAX_STR ( 4UL << 10 ) // 4KB
|
||||
#define RSIZE_MAX_STR (4UL << 10) // 4KB
|
||||
|
||||
// _malloca was suggested, but it is not a drop-in replacement for _alloca
|
||||
# define KMP_ALLOCA _alloca
|
||||
#define KMP_ALLOCA _alloca
|
||||
|
||||
# define KMP_MEMCPY_S memcpy_s
|
||||
# define KMP_SNPRINTF sprintf_s
|
||||
# define KMP_SSCANF sscanf_s
|
||||
# define KMP_STRCPY_S strcpy_s
|
||||
# define KMP_STRNCPY_S strncpy_s
|
||||
#define KMP_MEMCPY_S memcpy_s
|
||||
#define KMP_SNPRINTF sprintf_s
|
||||
#define KMP_SSCANF sscanf_s
|
||||
#define KMP_STRCPY_S strcpy_s
|
||||
#define KMP_STRNCPY_S strncpy_s
|
||||
|
||||
// Use this only when buffer size is unknown
|
||||
# define KMP_MEMCPY(dst, src, cnt) memcpy_s(dst, cnt, src, cnt)
|
||||
#define KMP_MEMCPY(dst, src, cnt) memcpy_s(dst, cnt, src, cnt)
|
||||
|
||||
# define KMP_STRLEN(str) strnlen_s(str, RSIZE_MAX_STR)
|
||||
#define KMP_STRLEN(str) strnlen_s(str, RSIZE_MAX_STR)
|
||||
|
||||
// Use this only when buffer size is unknown
|
||||
# define KMP_STRNCPY(dst, src, cnt) strncpy_s(dst, cnt, src, cnt)
|
||||
#define KMP_STRNCPY(dst, src, cnt) strncpy_s(dst, cnt, src, cnt)
|
||||
|
||||
// _TRUNCATE insures buffer size > max string to print.
|
||||
# define KMP_VSNPRINTF(dst, cnt, fmt, arg) vsnprintf_s(dst, cnt, _TRUNCATE, fmt, arg)
|
||||
#define KMP_VSNPRINTF(dst, cnt, fmt, arg) \
|
||||
vsnprintf_s(dst, cnt, _TRUNCATE, fmt, arg)
|
||||
|
||||
#else // KMP_OS_WINDOWS
|
||||
|
||||
// For now, these macros use the existing API.
|
||||
|
||||
# define KMP_ALLOCA alloca
|
||||
# define KMP_MEMCPY_S(dst, bsz, src, cnt) memcpy(dst, src, cnt)
|
||||
# define KMP_SNPRINTF snprintf
|
||||
# define KMP_SSCANF sscanf
|
||||
# define KMP_STRCPY_S(dst, bsz, src) strcpy(dst, src)
|
||||
# define KMP_STRNCPY_S(dst, bsz, src, cnt) strncpy(dst, src, cnt)
|
||||
# define KMP_VSNPRINTF vsnprintf
|
||||
# define KMP_STRNCPY strncpy
|
||||
# define KMP_STRLEN strlen
|
||||
# define KMP_MEMCPY memcpy
|
||||
#define KMP_ALLOCA alloca
|
||||
#define KMP_MEMCPY_S(dst, bsz, src, cnt) memcpy(dst, src, cnt)
|
||||
#define KMP_SNPRINTF snprintf
|
||||
#define KMP_SSCANF sscanf
|
||||
#define KMP_STRCPY_S(dst, bsz, src) strcpy(dst, src)
|
||||
#define KMP_STRNCPY_S(dst, bsz, src, cnt) strncpy(dst, src, cnt)
|
||||
#define KMP_VSNPRINTF vsnprintf
|
||||
#define KMP_STRNCPY strncpy
|
||||
#define KMP_STRLEN strlen
|
||||
#define KMP_MEMCPY memcpy
|
||||
|
||||
#endif // KMP_OS_WINDOWS
|
||||
|
||||
|
||||
+733
-772
File diff suppressed because it is too large
Load Diff
+4362
-4612
File diff suppressed because it is too large
Load Diff
+35
-18
@@ -16,35 +16,52 @@
|
||||
#ifndef KMP_SETTINGS_H
|
||||
#define KMP_SETTINGS_H
|
||||
|
||||
void __kmp_reset_global_vars( void );
|
||||
void __kmp_env_initialize( char const * );
|
||||
void __kmp_reset_global_vars(void);
|
||||
void __kmp_env_initialize(char const *);
|
||||
void __kmp_env_print();
|
||||
#if OMP_40_ENABLED
|
||||
void __kmp_env_print_2();
|
||||
#endif // OMP_40_ENABLED
|
||||
|
||||
int __kmp_initial_threads_capacity( int req_nproc );
|
||||
int __kmp_initial_threads_capacity(int req_nproc);
|
||||
void __kmp_init_dflt_team_nth();
|
||||
int __kmp_convert_to_milliseconds( char const * );
|
||||
int __kmp_default_tp_capacity( int, int, int);
|
||||
int __kmp_convert_to_milliseconds(char const *);
|
||||
int __kmp_default_tp_capacity(int, int, int);
|
||||
|
||||
#if KMP_MIC
|
||||
#define KMP_STR_BUF_PRINT_NAME __kmp_str_buf_print( buffer, " %s %s", KMP_I18N_STR(Device), name )
|
||||
#define KMP_STR_BUF_PRINT_NAME_EX(x) __kmp_str_buf_print( buffer, " %s %s='", KMP_I18N_STR(Device), x )
|
||||
#define KMP_STR_BUF_PRINT_BOOL __kmp_str_buf_print( buffer, " %s %s='%s'\n", KMP_I18N_STR(Device), name, value ? "TRUE" : "FALSE" );
|
||||
#define KMP_STR_BUF_PRINT_INT __kmp_str_buf_print( buffer, " %s %s='%d'\n", KMP_I18N_STR(Device), name, value )
|
||||
#define KMP_STR_BUF_PRINT_UINT64 __kmp_str_buf_print( buffer, " %s %s='%" KMP_UINT64_SPEC "'\n", KMP_I18N_STR(Device), name, value );
|
||||
#define KMP_STR_BUF_PRINT_STR __kmp_str_buf_print( buffer, " %s %s='%s'\n", KMP_I18N_STR(Device), name, value )
|
||||
#define KMP_STR_BUF_PRINT_NAME \
|
||||
__kmp_str_buf_print(buffer, " %s %s", KMP_I18N_STR(Device), name)
|
||||
#define KMP_STR_BUF_PRINT_NAME_EX(x) \
|
||||
__kmp_str_buf_print(buffer, " %s %s='", KMP_I18N_STR(Device), x)
|
||||
#define KMP_STR_BUF_PRINT_BOOL \
|
||||
__kmp_str_buf_print(buffer, " %s %s='%s'\n", KMP_I18N_STR(Device), name, \
|
||||
value ? "TRUE" : "FALSE");
|
||||
#define KMP_STR_BUF_PRINT_INT \
|
||||
__kmp_str_buf_print(buffer, " %s %s='%d'\n", KMP_I18N_STR(Device), name, \
|
||||
value)
|
||||
#define KMP_STR_BUF_PRINT_UINT64 \
|
||||
__kmp_str_buf_print(buffer, " %s %s='%" KMP_UINT64_SPEC "'\n", \
|
||||
KMP_I18N_STR(Device), name, value);
|
||||
#define KMP_STR_BUF_PRINT_STR \
|
||||
__kmp_str_buf_print(buffer, " %s %s='%s'\n", KMP_I18N_STR(Device), name, \
|
||||
value)
|
||||
#else
|
||||
#define KMP_STR_BUF_PRINT_NAME __kmp_str_buf_print( buffer, " %s %s", KMP_I18N_STR(Host), name )
|
||||
#define KMP_STR_BUF_PRINT_NAME_EX(x) __kmp_str_buf_print( buffer, " %s %s='", KMP_I18N_STR(Host), x )
|
||||
#define KMP_STR_BUF_PRINT_BOOL __kmp_str_buf_print( buffer, " %s %s='%s'\n", KMP_I18N_STR(Host), name, value ? "TRUE" : "FALSE" );
|
||||
#define KMP_STR_BUF_PRINT_INT __kmp_str_buf_print( buffer, " %s %s='%d'\n", KMP_I18N_STR(Host), name, value )
|
||||
#define KMP_STR_BUF_PRINT_UINT64 __kmp_str_buf_print( buffer, " %s %s='%" KMP_UINT64_SPEC "'\n", KMP_I18N_STR(Host), name, value );
|
||||
#define KMP_STR_BUF_PRINT_STR __kmp_str_buf_print( buffer, " %s %s='%s'\n", KMP_I18N_STR(Host), name, value )
|
||||
#define KMP_STR_BUF_PRINT_NAME \
|
||||
__kmp_str_buf_print(buffer, " %s %s", KMP_I18N_STR(Host), name)
|
||||
#define KMP_STR_BUF_PRINT_NAME_EX(x) \
|
||||
__kmp_str_buf_print(buffer, " %s %s='", KMP_I18N_STR(Host), x)
|
||||
#define KMP_STR_BUF_PRINT_BOOL \
|
||||
__kmp_str_buf_print(buffer, " %s %s='%s'\n", KMP_I18N_STR(Host), name, \
|
||||
value ? "TRUE" : "FALSE");
|
||||
#define KMP_STR_BUF_PRINT_INT \
|
||||
__kmp_str_buf_print(buffer, " %s %s='%d'\n", KMP_I18N_STR(Host), name, value)
|
||||
#define KMP_STR_BUF_PRINT_UINT64 \
|
||||
__kmp_str_buf_print(buffer, " %s %s='%" KMP_UINT64_SPEC "'\n", \
|
||||
KMP_I18N_STR(Host), name, value);
|
||||
#define KMP_STR_BUF_PRINT_STR \
|
||||
__kmp_str_buf_print(buffer, " %s %s='%s'\n", KMP_I18N_STR(Host), name, value)
|
||||
#endif
|
||||
|
||||
#endif // KMP_SETTINGS_H
|
||||
|
||||
// end of file //
|
||||
|
||||
|
||||
+509
-517
File diff suppressed because it is too large
Load Diff
+580
-507
File diff suppressed because it is too large
Load Diff
@@ -16,8 +16,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#include "kmp.h"
|
||||
@@ -26,119 +26,107 @@
|
||||
using namespace std;
|
||||
|
||||
#if KMP_HAVE_TICK_TIME
|
||||
# if KMP_MIC
|
||||
double tsc_tick_count::tick_time()
|
||||
{
|
||||
// pretty bad assumption of 1GHz clock for MIC
|
||||
return 1/((double)1000*1.e6);
|
||||
#if KMP_MIC
|
||||
double tsc_tick_count::tick_time() {
|
||||
// pretty bad assumption of 1GHz clock for MIC
|
||||
return 1 / ((double)1000 * 1.e6);
|
||||
}
|
||||
# elif KMP_ARCH_X86 || KMP_ARCH_X86_64
|
||||
# include <string.h>
|
||||
#elif KMP_ARCH_X86 || KMP_ARCH_X86_64
|
||||
#include <string.h>
|
||||
// Extract the value from the CPUID information
|
||||
double tsc_tick_count::tick_time()
|
||||
{
|
||||
static double result = 0.0;
|
||||
double tsc_tick_count::tick_time() {
|
||||
static double result = 0.0;
|
||||
|
||||
if (result == 0.0)
|
||||
{
|
||||
kmp_cpuid_t cpuinfo;
|
||||
char brand[256];
|
||||
if (result == 0.0) {
|
||||
kmp_cpuid_t cpuinfo;
|
||||
char brand[256];
|
||||
|
||||
__kmp_x86_cpuid(0x80000000, 0, &cpuinfo);
|
||||
memset(brand, 0, sizeof(brand));
|
||||
int ids = cpuinfo.eax;
|
||||
__kmp_x86_cpuid(0x80000000, 0, &cpuinfo);
|
||||
memset(brand, 0, sizeof(brand));
|
||||
int ids = cpuinfo.eax;
|
||||
|
||||
for (unsigned int i=2; i<(ids^0x80000000)+2; i++)
|
||||
__kmp_x86_cpuid(i | 0x80000000, 0, (kmp_cpuid_t*)(brand+(i-2)*sizeof(kmp_cpuid_t)));
|
||||
for (unsigned int i = 2; i < (ids ^ 0x80000000) + 2; i++)
|
||||
__kmp_x86_cpuid(i | 0x80000000, 0,
|
||||
(kmp_cpuid_t *)(brand + (i - 2) * sizeof(kmp_cpuid_t)));
|
||||
|
||||
char * start = &brand[0];
|
||||
for (;*start == ' '; start++)
|
||||
;
|
||||
char *start = &brand[0];
|
||||
for (; *start == ' '; start++)
|
||||
;
|
||||
|
||||
char * end = brand + KMP_STRLEN(brand) - 3;
|
||||
uint64_t multiplier;
|
||||
char *end = brand + KMP_STRLEN(brand) - 3;
|
||||
uint64_t multiplier;
|
||||
|
||||
if (*end == 'M') multiplier = 1000LL*1000LL;
|
||||
else if (*end == 'G') multiplier = 1000LL*1000LL*1000LL;
|
||||
else if (*end == 'T') multiplier = 1000LL*1000LL*1000LL*1000LL;
|
||||
else
|
||||
{
|
||||
cout << "Error determining multiplier '" << *end << "'\n";
|
||||
exit (-1);
|
||||
}
|
||||
*end = 0;
|
||||
while (*end != ' ') end--;
|
||||
end++;
|
||||
|
||||
double freq = strtod(end, &start);
|
||||
if (freq == 0.0)
|
||||
{
|
||||
cout << "Error calculating frequency " << end << "\n";
|
||||
exit (-1);
|
||||
}
|
||||
|
||||
result = ((double)1.0)/(freq * multiplier);
|
||||
if (*end == 'M')
|
||||
multiplier = 1000LL * 1000LL;
|
||||
else if (*end == 'G')
|
||||
multiplier = 1000LL * 1000LL * 1000LL;
|
||||
else if (*end == 'T')
|
||||
multiplier = 1000LL * 1000LL * 1000LL * 1000LL;
|
||||
else {
|
||||
cout << "Error determining multiplier '" << *end << "'\n";
|
||||
exit(-1);
|
||||
}
|
||||
return result;
|
||||
*end = 0;
|
||||
while (*end != ' ')
|
||||
end--;
|
||||
end++;
|
||||
|
||||
double freq = strtod(end, &start);
|
||||
if (freq == 0.0) {
|
||||
cout << "Error calculating frequency " << end << "\n";
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
result = ((double)1.0) / (freq * multiplier);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static bool useSI = true;
|
||||
|
||||
// Return a formatted string after normalising the value into
|
||||
// engineering style and using a suitable unit prefix (e.g. ms, us, ns).
|
||||
std::string formatSI(double interval, int width, char unit)
|
||||
{
|
||||
std::stringstream os;
|
||||
std::string formatSI(double interval, int width, char unit) {
|
||||
std::stringstream os;
|
||||
|
||||
if (useSI)
|
||||
{
|
||||
// Preserve accuracy for small numbers, since we only multiply and the positive powers
|
||||
// of ten are precisely representable.
|
||||
static struct { double scale; char prefix; } ranges[] = {
|
||||
{1.e12,'f'},
|
||||
{1.e9, 'p'},
|
||||
{1.e6, 'n'},
|
||||
{1.e3, 'u'},
|
||||
{1.0, 'm'},
|
||||
{1.e-3,' '},
|
||||
{1.e-6,'k'},
|
||||
{1.e-9,'M'},
|
||||
{1.e-12,'G'},
|
||||
{1.e-15,'T'},
|
||||
{1.e-18,'P'},
|
||||
{1.e-21,'E'},
|
||||
{1.e-24,'Z'},
|
||||
{1.e-27,'Y'}
|
||||
};
|
||||
if (useSI) {
|
||||
// Preserve accuracy for small numbers, since we only multiply and the
|
||||
// positive powers of ten are precisely representable.
|
||||
static struct {
|
||||
double scale;
|
||||
char prefix;
|
||||
} ranges[] = {{1.e12, 'f'}, {1.e9, 'p'}, {1.e6, 'n'}, {1.e3, 'u'},
|
||||
{1.0, 'm'}, {1.e-3, ' '}, {1.e-6, 'k'}, {1.e-9, 'M'},
|
||||
{1.e-12, 'G'}, {1.e-15, 'T'}, {1.e-18, 'P'}, {1.e-21, 'E'},
|
||||
{1.e-24, 'Z'}, {1.e-27, 'Y'}};
|
||||
|
||||
if (interval == 0.0)
|
||||
{
|
||||
os << std::setw(width-3) << std::right << "0.00" << std::setw(3) << unit;
|
||||
return os.str();
|
||||
}
|
||||
|
||||
bool negative = false;
|
||||
if (interval < 0.0)
|
||||
{
|
||||
negative = true;
|
||||
interval = -interval;
|
||||
}
|
||||
|
||||
for (int i=0; i<(int)(sizeof(ranges)/sizeof(ranges[0])); i++)
|
||||
{
|
||||
if (interval*ranges[i].scale < 1.e0)
|
||||
{
|
||||
interval = interval * 1000.e0 * ranges[i].scale;
|
||||
os << std::fixed << std::setprecision(2) << std::setw(width-3) << std::right <<
|
||||
(negative ? -interval : interval) << std::setw(2) << ranges[i].prefix << std::setw(1) << unit;
|
||||
|
||||
return os.str();
|
||||
}
|
||||
}
|
||||
if (interval == 0.0) {
|
||||
os << std::setw(width - 3) << std::right << "0.00" << std::setw(3)
|
||||
<< unit;
|
||||
return os.str();
|
||||
}
|
||||
os << std::setprecision(2) << std::fixed << std::right << std::setw(width-3) << interval << std::setw(3) << unit;
|
||||
|
||||
return os.str();
|
||||
bool negative = false;
|
||||
if (interval < 0.0) {
|
||||
negative = true;
|
||||
interval = -interval;
|
||||
}
|
||||
|
||||
for (int i = 0; i < (int)(sizeof(ranges) / sizeof(ranges[0])); i++) {
|
||||
if (interval * ranges[i].scale < 1.e0) {
|
||||
interval = interval * 1000.e0 * ranges[i].scale;
|
||||
os << std::fixed << std::setprecision(2) << std::setw(width - 3)
|
||||
<< std::right << (negative ? -interval : interval) << std::setw(2)
|
||||
<< ranges[i].prefix << std::setw(1) << unit;
|
||||
|
||||
return os.str();
|
||||
}
|
||||
}
|
||||
}
|
||||
os << std::setprecision(2) << std::fixed << std::right << std::setw(width - 3)
|
||||
<< interval << std::setw(3) << unit;
|
||||
|
||||
return os.str();
|
||||
}
|
||||
|
||||
@@ -16,97 +16,103 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
|
||||
#include "kmp_os.h"
|
||||
#include <limits>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <limits>
|
||||
#include "kmp_os.h"
|
||||
#if KMP_HAVE_X86INTRIN_H
|
||||
# include <x86intrin.h>
|
||||
#include <x86intrin.h>
|
||||
#endif
|
||||
|
||||
class tsc_tick_count {
|
||||
private:
|
||||
int64_t my_count;
|
||||
private:
|
||||
int64_t my_count;
|
||||
|
||||
public:
|
||||
class tsc_interval_t {
|
||||
int64_t value;
|
||||
explicit tsc_interval_t(int64_t _value) : value(_value) {}
|
||||
|
||||
public:
|
||||
class tsc_interval_t {
|
||||
int64_t value;
|
||||
explicit tsc_interval_t(int64_t _value) : value(_value) {}
|
||||
public:
|
||||
tsc_interval_t() : value(0) {}; // Construct 0 time duration
|
||||
tsc_interval_t() : value(0){}; // Construct 0 time duration
|
||||
#if KMP_HAVE_TICK_TIME
|
||||
double seconds() const; // Return the length of a time interval in seconds
|
||||
double seconds() const; // Return the length of a time interval in seconds
|
||||
#endif
|
||||
double ticks() const { return double(value); }
|
||||
int64_t getValue() const { return value; }
|
||||
tsc_interval_t& operator=(int64_t nvalue) { value = nvalue; return *this; }
|
||||
double ticks() const { return double(value); }
|
||||
int64_t getValue() const { return value; }
|
||||
tsc_interval_t &operator=(int64_t nvalue) {
|
||||
value = nvalue;
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend class tsc_tick_count;
|
||||
friend class tsc_tick_count;
|
||||
|
||||
friend tsc_interval_t operator-(const tsc_tick_count& t1,
|
||||
const tsc_tick_count& t0);
|
||||
friend tsc_interval_t operator-(const tsc_tick_count::tsc_interval_t& i1,
|
||||
const tsc_tick_count::tsc_interval_t& i0);
|
||||
friend tsc_interval_t& operator+=(tsc_tick_count::tsc_interval_t& i1,
|
||||
const tsc_tick_count::tsc_interval_t& i0);
|
||||
};
|
||||
friend tsc_interval_t operator-(const tsc_tick_count &t1,
|
||||
const tsc_tick_count &t0);
|
||||
friend tsc_interval_t operator-(const tsc_tick_count::tsc_interval_t &i1,
|
||||
const tsc_tick_count::tsc_interval_t &i0);
|
||||
friend tsc_interval_t &operator+=(tsc_tick_count::tsc_interval_t &i1,
|
||||
const tsc_tick_count::tsc_interval_t &i0);
|
||||
};
|
||||
|
||||
#if KMP_HAVE___BUILTIN_READCYCLECOUNTER
|
||||
tsc_tick_count() : my_count(static_cast<int64_t>(__builtin_readcyclecounter())) {}
|
||||
tsc_tick_count()
|
||||
: my_count(static_cast<int64_t>(__builtin_readcyclecounter())) {}
|
||||
#elif KMP_HAVE___RDTSC
|
||||
tsc_tick_count() : my_count(static_cast<int64_t>(__rdtsc())) {};
|
||||
tsc_tick_count() : my_count(static_cast<int64_t>(__rdtsc())){};
|
||||
#else
|
||||
# error Must have high resolution timer defined
|
||||
#error Must have high resolution timer defined
|
||||
#endif
|
||||
tsc_tick_count(int64_t value) : my_count(value) {};
|
||||
int64_t getValue() const { return my_count; }
|
||||
tsc_tick_count later (tsc_tick_count const other) const {
|
||||
return my_count > other.my_count ? (*this) : other;
|
||||
}
|
||||
tsc_tick_count earlier(tsc_tick_count const other) const {
|
||||
return my_count < other.my_count ? (*this) : other;
|
||||
}
|
||||
tsc_tick_count(int64_t value) : my_count(value){};
|
||||
int64_t getValue() const { return my_count; }
|
||||
tsc_tick_count later(tsc_tick_count const other) const {
|
||||
return my_count > other.my_count ? (*this) : other;
|
||||
}
|
||||
tsc_tick_count earlier(tsc_tick_count const other) const {
|
||||
return my_count < other.my_count ? (*this) : other;
|
||||
}
|
||||
#if KMP_HAVE_TICK_TIME
|
||||
static double tick_time(); // returns seconds per cycle (period) of clock
|
||||
static double tick_time(); // returns seconds per cycle (period) of clock
|
||||
#endif
|
||||
static tsc_tick_count now() { return tsc_tick_count(); } // returns the rdtsc register value
|
||||
friend tsc_tick_count::tsc_interval_t operator-(const tsc_tick_count& t1, const tsc_tick_count& t0);
|
||||
static tsc_tick_count now() {
|
||||
return tsc_tick_count();
|
||||
} // returns the rdtsc register value
|
||||
friend tsc_tick_count::tsc_interval_t operator-(const tsc_tick_count &t1,
|
||||
const tsc_tick_count &t0);
|
||||
};
|
||||
|
||||
inline tsc_tick_count::tsc_interval_t operator-(const tsc_tick_count& t1, const tsc_tick_count& t0)
|
||||
{
|
||||
return tsc_tick_count::tsc_interval_t( t1.my_count-t0.my_count );
|
||||
inline tsc_tick_count::tsc_interval_t operator-(const tsc_tick_count &t1,
|
||||
const tsc_tick_count &t0) {
|
||||
return tsc_tick_count::tsc_interval_t(t1.my_count - t0.my_count);
|
||||
}
|
||||
|
||||
inline tsc_tick_count::tsc_interval_t operator-(const tsc_tick_count::tsc_interval_t& i1, const tsc_tick_count::tsc_interval_t& i0)
|
||||
{
|
||||
return tsc_tick_count::tsc_interval_t( i1.value-i0.value );
|
||||
inline tsc_tick_count::tsc_interval_t
|
||||
operator-(const tsc_tick_count::tsc_interval_t &i1,
|
||||
const tsc_tick_count::tsc_interval_t &i0) {
|
||||
return tsc_tick_count::tsc_interval_t(i1.value - i0.value);
|
||||
}
|
||||
|
||||
inline tsc_tick_count::tsc_interval_t& operator+=(tsc_tick_count::tsc_interval_t& i1, const tsc_tick_count::tsc_interval_t& i0)
|
||||
{
|
||||
i1.value += i0.value;
|
||||
return i1;
|
||||
inline tsc_tick_count::tsc_interval_t &
|
||||
operator+=(tsc_tick_count::tsc_interval_t &i1,
|
||||
const tsc_tick_count::tsc_interval_t &i0) {
|
||||
i1.value += i0.value;
|
||||
return i1;
|
||||
}
|
||||
|
||||
#if KMP_HAVE_TICK_TIME
|
||||
inline double tsc_tick_count::tsc_interval_t::seconds() const
|
||||
{
|
||||
return value*tick_time();
|
||||
inline double tsc_tick_count::tsc_interval_t::seconds() const {
|
||||
return value * tick_time();
|
||||
}
|
||||
#endif
|
||||
|
||||
extern std::string formatSI(double interval, int width, char unit);
|
||||
|
||||
inline std::string formatSeconds(double interval, int width)
|
||||
{
|
||||
return formatSI(interval, width, 'S');
|
||||
inline std::string formatSeconds(double interval, int width) {
|
||||
return formatSI(interval, width, 'S');
|
||||
}
|
||||
|
||||
inline std::string formatTicks(double interval, int width)
|
||||
{
|
||||
return formatSI(interval, width, 'T');
|
||||
inline std::string formatTicks(double interval, int width) {
|
||||
return formatSI(interval, width, 'T');
|
||||
}
|
||||
|
||||
#endif // KMP_STATS_TIMING_H
|
||||
|
||||
+585
-730
File diff suppressed because it is too large
Load Diff
+71
-63
@@ -16,104 +16,112 @@
|
||||
#ifndef KMP_STR_H
|
||||
#define KMP_STR_H
|
||||
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "kmp_os.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
#if KMP_OS_WINDOWS
|
||||
# define strdup _strdup
|
||||
#define strdup _strdup
|
||||
#endif
|
||||
|
||||
/* some macros to replace ctype.h functions */
|
||||
#define TOLOWER(c) ((((c) >= 'A') && ((c) <= 'Z')) ? ((c) + 'a' - 'A') : (c))
|
||||
#define TOLOWER(c) ((((c) >= 'A') && ((c) <= 'Z')) ? ((c) + 'a' - 'A') : (c))
|
||||
|
||||
struct kmp_str_buf {
|
||||
char * str; // Pointer to buffer content, read only.
|
||||
unsigned int size; // Do not change this field!
|
||||
int used; // Number of characters printed to buffer, read only.
|
||||
char bulk[ 512 ]; // Do not use this field!
|
||||
char *str; // Pointer to buffer content, read only.
|
||||
unsigned int size; // Do not change this field!
|
||||
int used; // Number of characters printed to buffer, read only.
|
||||
char bulk[512]; // Do not use this field!
|
||||
}; // struct kmp_str_buf
|
||||
typedef struct kmp_str_buf kmp_str_buf_t;
|
||||
typedef struct kmp_str_buf kmp_str_buf_t;
|
||||
|
||||
#define __kmp_str_buf_init( b ) { (b)->str = (b)->bulk; (b)->size = sizeof( (b)->bulk ); (b)->used = 0; (b)->bulk[ 0 ] = 0; }
|
||||
#define __kmp_str_buf_init(b) \
|
||||
{ \
|
||||
(b)->str = (b)->bulk; \
|
||||
(b)->size = sizeof((b)->bulk); \
|
||||
(b)->used = 0; \
|
||||
(b)->bulk[0] = 0; \
|
||||
}
|
||||
|
||||
void __kmp_str_buf_clear( kmp_str_buf_t * buffer );
|
||||
void __kmp_str_buf_reserve( kmp_str_buf_t * buffer, int size );
|
||||
void __kmp_str_buf_detach( kmp_str_buf_t * buffer );
|
||||
void __kmp_str_buf_free( kmp_str_buf_t * buffer );
|
||||
void __kmp_str_buf_cat( kmp_str_buf_t * buffer, char const * str, int len );
|
||||
void __kmp_str_buf_vprint( kmp_str_buf_t * buffer, char const * format, va_list args );
|
||||
void __kmp_str_buf_print( kmp_str_buf_t * buffer, char const * format, ... );
|
||||
void __kmp_str_buf_print_size( kmp_str_buf_t * buffer, size_t size );
|
||||
void __kmp_str_buf_clear(kmp_str_buf_t *buffer);
|
||||
void __kmp_str_buf_reserve(kmp_str_buf_t *buffer, int size);
|
||||
void __kmp_str_buf_detach(kmp_str_buf_t *buffer);
|
||||
void __kmp_str_buf_free(kmp_str_buf_t *buffer);
|
||||
void __kmp_str_buf_cat(kmp_str_buf_t *buffer, char const *str, int len);
|
||||
void __kmp_str_buf_vprint(kmp_str_buf_t *buffer, char const *format,
|
||||
va_list args);
|
||||
void __kmp_str_buf_print(kmp_str_buf_t *buffer, char const *format, ...);
|
||||
void __kmp_str_buf_print_size(kmp_str_buf_t *buffer, size_t size);
|
||||
|
||||
/*
|
||||
File name parser. Usage:
|
||||
|
||||
kmp_str_fname_t fname = __kmp_str_fname_init( path );
|
||||
// Use fname.path (copy of original path ), fname.dir, fname.base.
|
||||
// Note fname.dir concatenated with fname.base gives exact copy of path.
|
||||
__kmp_str_fname_free( & fname );
|
||||
/* File name parser.
|
||||
Usage:
|
||||
|
||||
kmp_str_fname_t fname = __kmp_str_fname_init( path );
|
||||
// Use fname.path (copy of original path ), fname.dir, fname.base.
|
||||
// Note fname.dir concatenated with fname.base gives exact copy of path.
|
||||
__kmp_str_fname_free( & fname );
|
||||
*/
|
||||
struct kmp_str_fname {
|
||||
char * path;
|
||||
char * dir;
|
||||
char * base;
|
||||
char *path;
|
||||
char *dir;
|
||||
char *base;
|
||||
}; // struct kmp_str_fname
|
||||
typedef struct kmp_str_fname kmp_str_fname_t;
|
||||
void __kmp_str_fname_init( kmp_str_fname_t * fname, char const * path );
|
||||
void __kmp_str_fname_free( kmp_str_fname_t * fname );
|
||||
// Compares file name with specified patern. If pattern is NULL, any fname matched.
|
||||
int __kmp_str_fname_match( kmp_str_fname_t const * fname, char const * pattern );
|
||||
void __kmp_str_fname_init(kmp_str_fname_t *fname, char const *path);
|
||||
void __kmp_str_fname_free(kmp_str_fname_t *fname);
|
||||
// Compares file name with specified patern. If pattern is NULL, any fname
|
||||
// matched.
|
||||
int __kmp_str_fname_match(kmp_str_fname_t const *fname, char const *pattern);
|
||||
|
||||
/*
|
||||
The compiler provides source locations in string form ";file;func;line;col;;". It not not
|
||||
convenient for manupulation. These structure keeps source location in more convenient form.
|
||||
Usage:
|
||||
/* The compiler provides source locations in string form
|
||||
";file;func;line;col;;". It is not convenient for manupulation. This
|
||||
structure keeps source location in more convenient form.
|
||||
Usage:
|
||||
|
||||
kmp_str_loc_t loc = __kmp_str_loc_init( ident->psource, 0 );
|
||||
// use loc.file, loc.func, loc.line, loc.col.
|
||||
// loc.fname is available if the second argument of __kmp_str_loc_init is true.
|
||||
__kmp_str_loc_free( & loc );
|
||||
kmp_str_loc_t loc = __kmp_str_loc_init( ident->psource, 0 );
|
||||
// use loc.file, loc.func, loc.line, loc.col.
|
||||
// loc.fname is available if second argument of __kmp_str_loc_init is true.
|
||||
__kmp_str_loc_free( & loc );
|
||||
|
||||
If psource is NULL or does not follow format above, file and/or func may be NULL pointers.
|
||||
If psource is NULL or does not follow format above, file and/or func may be
|
||||
NULL pointers.
|
||||
*/
|
||||
struct kmp_str_loc {
|
||||
char * _bulk; // Do not use thid field.
|
||||
kmp_str_fname_t fname; // Will be initialized if init_fname is true.
|
||||
char * file;
|
||||
char * func;
|
||||
int line;
|
||||
int col;
|
||||
char *_bulk; // Do not use thid field.
|
||||
kmp_str_fname_t fname; // Will be initialized if init_fname is true.
|
||||
char *file;
|
||||
char *func;
|
||||
int line;
|
||||
int col;
|
||||
}; // struct kmp_str_loc
|
||||
typedef struct kmp_str_loc kmp_str_loc_t;
|
||||
kmp_str_loc_t __kmp_str_loc_init( char const * psource, int init_fname );
|
||||
void __kmp_str_loc_free( kmp_str_loc_t * loc );
|
||||
kmp_str_loc_t __kmp_str_loc_init(char const *psource, int init_fname);
|
||||
void __kmp_str_loc_free(kmp_str_loc_t *loc);
|
||||
|
||||
int __kmp_str_eqf( char const * lhs, char const * rhs );
|
||||
char * __kmp_str_format( char const * format, ... );
|
||||
void __kmp_str_free( char const * * str );
|
||||
int __kmp_str_match( char const * target, int len, char const * data );
|
||||
int __kmp_str_match_false( char const * data );
|
||||
int __kmp_str_match_true( char const * data );
|
||||
void __kmp_str_replace( char * str, char search_for, char replace_with );
|
||||
void __kmp_str_split( char * str, char delim, char ** head, char ** tail );
|
||||
char * __kmp_str_token( char * str, char const * delim, char ** buf );
|
||||
int __kmp_str_to_int( char const * str, char sentinel );
|
||||
int __kmp_str_eqf(char const *lhs, char const *rhs);
|
||||
char *__kmp_str_format(char const *format, ...);
|
||||
void __kmp_str_free(char const **str);
|
||||
int __kmp_str_match(char const *target, int len, char const *data);
|
||||
int __kmp_str_match_false(char const *data);
|
||||
int __kmp_str_match_true(char const *data);
|
||||
void __kmp_str_replace(char *str, char search_for, char replace_with);
|
||||
void __kmp_str_split(char *str, char delim, char **head, char **tail);
|
||||
char *__kmp_str_token(char *str, char const *delim, char **buf);
|
||||
int __kmp_str_to_int(char const *str, char sentinel);
|
||||
|
||||
void __kmp_str_to_size( char const * str, size_t * out, size_t dfactor, char const * * error );
|
||||
void __kmp_str_to_uint( char const * str, kmp_uint64 * out, char const * * error );
|
||||
void __kmp_str_to_size(char const *str, size_t *out, size_t dfactor,
|
||||
char const **error);
|
||||
void __kmp_str_to_uint(char const *str, kmp_uint64 *out, char const **error);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // KMP_STR_H
|
||||
|
||||
// end of file //
|
||||
|
||||
|
||||
+221
-175
@@ -13,258 +13,304 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "omp.h" // Function renamings.
|
||||
#include "kmp.h" // KMP_DEFAULT_STKSIZE
|
||||
#include "kmp.h" // KMP_DEFAULT_STKSIZE
|
||||
#include "kmp_stub.h"
|
||||
#include "omp.h" // Function renamings.
|
||||
|
||||
#if KMP_OS_WINDOWS
|
||||
#include <windows.h>
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
// Moved from omp.h
|
||||
#define omp_set_max_active_levels ompc_set_max_active_levels
|
||||
#define omp_set_schedule ompc_set_schedule
|
||||
#define omp_get_ancestor_thread_num ompc_get_ancestor_thread_num
|
||||
#define omp_get_team_size ompc_get_team_size
|
||||
#define omp_set_max_active_levels ompc_set_max_active_levels
|
||||
#define omp_set_schedule ompc_set_schedule
|
||||
#define omp_get_ancestor_thread_num ompc_get_ancestor_thread_num
|
||||
#define omp_get_team_size ompc_get_team_size
|
||||
|
||||
#define omp_set_num_threads ompc_set_num_threads
|
||||
#define omp_set_dynamic ompc_set_dynamic
|
||||
#define omp_set_nested ompc_set_nested
|
||||
#define kmp_set_stacksize kmpc_set_stacksize
|
||||
#define kmp_set_stacksize_s kmpc_set_stacksize_s
|
||||
#define kmp_set_blocktime kmpc_set_blocktime
|
||||
#define kmp_set_library kmpc_set_library
|
||||
#define kmp_set_defaults kmpc_set_defaults
|
||||
#define kmp_set_disp_num_buffers kmpc_set_disp_num_buffers
|
||||
#define kmp_malloc kmpc_malloc
|
||||
#define kmp_aligned_malloc kmpc_aligned_malloc
|
||||
#define kmp_calloc kmpc_calloc
|
||||
#define kmp_realloc kmpc_realloc
|
||||
#define kmp_free kmpc_free
|
||||
#define omp_set_num_threads ompc_set_num_threads
|
||||
#define omp_set_dynamic ompc_set_dynamic
|
||||
#define omp_set_nested ompc_set_nested
|
||||
#define kmp_set_stacksize kmpc_set_stacksize
|
||||
#define kmp_set_stacksize_s kmpc_set_stacksize_s
|
||||
#define kmp_set_blocktime kmpc_set_blocktime
|
||||
#define kmp_set_library kmpc_set_library
|
||||
#define kmp_set_defaults kmpc_set_defaults
|
||||
#define kmp_set_disp_num_buffers kmpc_set_disp_num_buffers
|
||||
#define kmp_malloc kmpc_malloc
|
||||
#define kmp_aligned_malloc kmpc_aligned_malloc
|
||||
#define kmp_calloc kmpc_calloc
|
||||
#define kmp_realloc kmpc_realloc
|
||||
#define kmp_free kmpc_free
|
||||
|
||||
static double frequency = 0.0;
|
||||
|
||||
// Helper functions.
|
||||
static size_t __kmps_init() {
|
||||
static int initialized = 0;
|
||||
static size_t dummy = 0;
|
||||
if ( ! initialized ) {
|
||||
static int initialized = 0;
|
||||
static size_t dummy = 0;
|
||||
if (!initialized) {
|
||||
// TODO: Analyze KMP_VERSION environment variable, print
|
||||
// __kmp_version_copyright and __kmp_version_build_time.
|
||||
// WARNING: Do not use "fprintf(stderr, ...)" because it will cause
|
||||
// unresolved "__iob" symbol (see C70080). We need to extract __kmp_printf()
|
||||
// stuff from kmp_runtime.cpp and use it.
|
||||
|
||||
// TODO: Analyze KMP_VERSION environment variable, print
|
||||
// __kmp_version_copyright and __kmp_version_build_time.
|
||||
// WARNING: Do not use "fprintf( stderr, ... )" because it will cause
|
||||
// unresolved "__iob" symbol (see C70080). We need to extract
|
||||
// __kmp_printf() stuff from kmp_runtime.cpp and use it.
|
||||
// Trick with dummy variable forces linker to keep __kmp_version_copyright
|
||||
// and __kmp_version_build_time strings in executable file (in case of
|
||||
// static linkage). When KMP_VERSION analysis is implemented, dummy
|
||||
// variable should be deleted, function should return void.
|
||||
dummy = __kmp_version_copyright - __kmp_version_build_time;
|
||||
|
||||
// Trick with dummy variable forces linker to keep __kmp_version_copyright
|
||||
// and __kmp_version_build_time strings in executable file (in case of
|
||||
// static linkage). When KMP_VERSION analysis is implemented, dummy
|
||||
// variable should be deleted, function should return void.
|
||||
dummy = __kmp_version_copyright - __kmp_version_build_time;
|
||||
|
||||
#if KMP_OS_WINDOWS
|
||||
LARGE_INTEGER freq;
|
||||
BOOL status = QueryPerformanceFrequency( & freq );
|
||||
if ( status ) {
|
||||
frequency = double( freq.QuadPart );
|
||||
}; // if
|
||||
#endif
|
||||
|
||||
initialized = 1;
|
||||
#if KMP_OS_WINDOWS
|
||||
LARGE_INTEGER freq;
|
||||
BOOL status = QueryPerformanceFrequency(&freq);
|
||||
if (status) {
|
||||
frequency = double(freq.QuadPart);
|
||||
}; // if
|
||||
return dummy;
|
||||
#endif
|
||||
|
||||
initialized = 1;
|
||||
}; // if
|
||||
return dummy;
|
||||
}; // __kmps_init
|
||||
|
||||
#define i __kmps_init();
|
||||
|
||||
/* set API functions */
|
||||
void omp_set_num_threads( omp_int_t num_threads ) { i; }
|
||||
void omp_set_dynamic( omp_int_t dynamic ) { i; __kmps_set_dynamic( dynamic ); }
|
||||
void omp_set_nested( omp_int_t nested ) { i; __kmps_set_nested( nested ); }
|
||||
void omp_set_max_active_levels( omp_int_t max_active_levels ) { i; }
|
||||
void omp_set_schedule( omp_sched_t kind, omp_int_t modifier ) { i; __kmps_set_schedule( (kmp_sched_t)kind, modifier ); }
|
||||
int omp_get_ancestor_thread_num( omp_int_t level ) { i; return ( level ) ? ( -1 ) : ( 0 ); }
|
||||
int omp_get_team_size( omp_int_t level ) { i; return ( level ) ? ( -1 ) : ( 1 ); }
|
||||
int kmpc_set_affinity_mask_proc( int proc, void **mask ) { i; return -1; }
|
||||
int kmpc_unset_affinity_mask_proc( int proc, void **mask ) { i; return -1; }
|
||||
int kmpc_get_affinity_mask_proc( int proc, void **mask ) { i; return -1; }
|
||||
void omp_set_num_threads(omp_int_t num_threads) { i; }
|
||||
void omp_set_dynamic(omp_int_t dynamic) {
|
||||
i;
|
||||
__kmps_set_dynamic(dynamic);
|
||||
}
|
||||
void omp_set_nested(omp_int_t nested) {
|
||||
i;
|
||||
__kmps_set_nested(nested);
|
||||
}
|
||||
void omp_set_max_active_levels(omp_int_t max_active_levels) { i; }
|
||||
void omp_set_schedule(omp_sched_t kind, omp_int_t modifier) {
|
||||
i;
|
||||
__kmps_set_schedule((kmp_sched_t)kind, modifier);
|
||||
}
|
||||
int omp_get_ancestor_thread_num(omp_int_t level) {
|
||||
i;
|
||||
return (level) ? (-1) : (0);
|
||||
}
|
||||
int omp_get_team_size(omp_int_t level) {
|
||||
i;
|
||||
return (level) ? (-1) : (1);
|
||||
}
|
||||
int kmpc_set_affinity_mask_proc(int proc, void **mask) {
|
||||
i;
|
||||
return -1;
|
||||
}
|
||||
int kmpc_unset_affinity_mask_proc(int proc, void **mask) {
|
||||
i;
|
||||
return -1;
|
||||
}
|
||||
int kmpc_get_affinity_mask_proc(int proc, void **mask) {
|
||||
i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* kmp API functions */
|
||||
void kmp_set_stacksize( omp_int_t arg ) { i; __kmps_set_stacksize( arg ); }
|
||||
void kmp_set_stacksize_s( size_t arg ) { i; __kmps_set_stacksize( arg ); }
|
||||
void kmp_set_blocktime( omp_int_t arg ) { i; __kmps_set_blocktime( arg ); }
|
||||
void kmp_set_library( omp_int_t arg ) { i; __kmps_set_library( arg ); }
|
||||
void kmp_set_defaults( char const * str ) { i; }
|
||||
void kmp_set_disp_num_buffers( omp_int_t arg ) { i; }
|
||||
void kmp_set_stacksize(omp_int_t arg) {
|
||||
i;
|
||||
__kmps_set_stacksize(arg);
|
||||
}
|
||||
void kmp_set_stacksize_s(size_t arg) {
|
||||
i;
|
||||
__kmps_set_stacksize(arg);
|
||||
}
|
||||
void kmp_set_blocktime(omp_int_t arg) {
|
||||
i;
|
||||
__kmps_set_blocktime(arg);
|
||||
}
|
||||
void kmp_set_library(omp_int_t arg) {
|
||||
i;
|
||||
__kmps_set_library(arg);
|
||||
}
|
||||
void kmp_set_defaults(char const *str) { i; }
|
||||
void kmp_set_disp_num_buffers(omp_int_t arg) { i; }
|
||||
|
||||
/* KMP memory management functions. */
|
||||
void * kmp_malloc( size_t size ) { i; return malloc( size ); }
|
||||
void * kmp_aligned_malloc( size_t sz, size_t a ) {
|
||||
i;
|
||||
void *kmp_malloc(size_t size) {
|
||||
i;
|
||||
return malloc(size);
|
||||
}
|
||||
void *kmp_aligned_malloc(size_t sz, size_t a) {
|
||||
i;
|
||||
#if KMP_OS_WINDOWS
|
||||
errno = ENOSYS; // not supported
|
||||
return NULL; // no standard aligned allocator on Windows (pre - C11)
|
||||
errno = ENOSYS; // not supported
|
||||
return NULL; // no standard aligned allocator on Windows (pre - C11)
|
||||
#else
|
||||
void *res;
|
||||
int err;
|
||||
if( err = posix_memalign( &res, a, sz ) ) {
|
||||
errno = err; // can be EINVAL or ENOMEM
|
||||
return NULL;
|
||||
}
|
||||
return res;
|
||||
void *res;
|
||||
int err;
|
||||
if (err = posix_memalign(&res, a, sz)) {
|
||||
errno = err; // can be EINVAL or ENOMEM
|
||||
return NULL;
|
||||
}
|
||||
return res;
|
||||
#endif
|
||||
}
|
||||
void * kmp_calloc( size_t nelem, size_t elsize ) { i; return calloc( nelem, elsize ); }
|
||||
void * kmp_realloc( void *ptr, size_t size ) { i; return realloc( ptr, size ); }
|
||||
void kmp_free( void * ptr ) { i; free( ptr ); }
|
||||
void *kmp_calloc(size_t nelem, size_t elsize) {
|
||||
i;
|
||||
return calloc(nelem, elsize);
|
||||
}
|
||||
void *kmp_realloc(void *ptr, size_t size) {
|
||||
i;
|
||||
return realloc(ptr, size);
|
||||
}
|
||||
void kmp_free(void *ptr) {
|
||||
i;
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
static int __kmps_blocktime = INT_MAX;
|
||||
|
||||
void __kmps_set_blocktime( int arg ) {
|
||||
i;
|
||||
__kmps_blocktime = arg;
|
||||
void __kmps_set_blocktime(int arg) {
|
||||
i;
|
||||
__kmps_blocktime = arg;
|
||||
} // __kmps_set_blocktime
|
||||
|
||||
int __kmps_get_blocktime( void ) {
|
||||
i;
|
||||
return __kmps_blocktime;
|
||||
int __kmps_get_blocktime(void) {
|
||||
i;
|
||||
return __kmps_blocktime;
|
||||
} // __kmps_get_blocktime
|
||||
|
||||
static int __kmps_dynamic = 0;
|
||||
|
||||
void __kmps_set_dynamic( int arg ) {
|
||||
i;
|
||||
__kmps_dynamic = arg;
|
||||
void __kmps_set_dynamic(int arg) {
|
||||
i;
|
||||
__kmps_dynamic = arg;
|
||||
} // __kmps_set_dynamic
|
||||
|
||||
int __kmps_get_dynamic( void ) {
|
||||
i;
|
||||
return __kmps_dynamic;
|
||||
int __kmps_get_dynamic(void) {
|
||||
i;
|
||||
return __kmps_dynamic;
|
||||
} // __kmps_get_dynamic
|
||||
|
||||
static int __kmps_library = 1000;
|
||||
|
||||
void __kmps_set_library( int arg ) {
|
||||
i;
|
||||
__kmps_library = arg;
|
||||
void __kmps_set_library(int arg) {
|
||||
i;
|
||||
__kmps_library = arg;
|
||||
} // __kmps_set_library
|
||||
|
||||
int __kmps_get_library( void ) {
|
||||
i;
|
||||
return __kmps_library;
|
||||
int __kmps_get_library(void) {
|
||||
i;
|
||||
return __kmps_library;
|
||||
} // __kmps_get_library
|
||||
|
||||
static int __kmps_nested = 0;
|
||||
|
||||
void __kmps_set_nested( int arg ) {
|
||||
i;
|
||||
__kmps_nested = arg;
|
||||
void __kmps_set_nested(int arg) {
|
||||
i;
|
||||
__kmps_nested = arg;
|
||||
} // __kmps_set_nested
|
||||
|
||||
int __kmps_get_nested( void ) {
|
||||
i;
|
||||
return __kmps_nested;
|
||||
int __kmps_get_nested(void) {
|
||||
i;
|
||||
return __kmps_nested;
|
||||
} // __kmps_get_nested
|
||||
|
||||
static size_t __kmps_stacksize = KMP_DEFAULT_STKSIZE;
|
||||
|
||||
void __kmps_set_stacksize( int arg ) {
|
||||
i;
|
||||
__kmps_stacksize = arg;
|
||||
void __kmps_set_stacksize(int arg) {
|
||||
i;
|
||||
__kmps_stacksize = arg;
|
||||
} // __kmps_set_stacksize
|
||||
|
||||
int __kmps_get_stacksize( void ) {
|
||||
i;
|
||||
return __kmps_stacksize;
|
||||
int __kmps_get_stacksize(void) {
|
||||
i;
|
||||
return __kmps_stacksize;
|
||||
} // __kmps_get_stacksize
|
||||
|
||||
static kmp_sched_t __kmps_sched_kind = kmp_sched_default;
|
||||
static int __kmps_sched_modifier = 0;
|
||||
static kmp_sched_t __kmps_sched_kind = kmp_sched_default;
|
||||
static int __kmps_sched_modifier = 0;
|
||||
|
||||
void __kmps_set_schedule( kmp_sched_t kind, int modifier ) {
|
||||
i;
|
||||
__kmps_sched_kind = kind;
|
||||
__kmps_sched_modifier = modifier;
|
||||
} // __kmps_set_schedule
|
||||
void __kmps_set_schedule(kmp_sched_t kind, int modifier) {
|
||||
i;
|
||||
__kmps_sched_kind = kind;
|
||||
__kmps_sched_modifier = modifier;
|
||||
} // __kmps_set_schedule
|
||||
|
||||
void __kmps_get_schedule( kmp_sched_t *kind, int *modifier ) {
|
||||
i;
|
||||
*kind = __kmps_sched_kind;
|
||||
*modifier = __kmps_sched_modifier;
|
||||
} // __kmps_get_schedule
|
||||
void __kmps_get_schedule(kmp_sched_t *kind, int *modifier) {
|
||||
i;
|
||||
*kind = __kmps_sched_kind;
|
||||
*modifier = __kmps_sched_modifier;
|
||||
} // __kmps_get_schedule
|
||||
|
||||
#if OMP_40_ENABLED
|
||||
|
||||
static kmp_proc_bind_t __kmps_proc_bind = proc_bind_false;
|
||||
|
||||
void __kmps_set_proc_bind( kmp_proc_bind_t arg ) {
|
||||
i;
|
||||
__kmps_proc_bind = arg;
|
||||
void __kmps_set_proc_bind(kmp_proc_bind_t arg) {
|
||||
i;
|
||||
__kmps_proc_bind = arg;
|
||||
} // __kmps_set_proc_bind
|
||||
|
||||
kmp_proc_bind_t __kmps_get_proc_bind( void ) {
|
||||
i;
|
||||
return __kmps_proc_bind;
|
||||
kmp_proc_bind_t __kmps_get_proc_bind(void) {
|
||||
i;
|
||||
return __kmps_proc_bind;
|
||||
} // __kmps_get_proc_bind
|
||||
|
||||
#endif /* OMP_40_ENABLED */
|
||||
|
||||
double __kmps_get_wtime( void ) {
|
||||
// Elapsed wall clock time (in second) from "sometime in the past".
|
||||
double wtime = 0.0;
|
||||
i;
|
||||
#if KMP_OS_WINDOWS
|
||||
if ( frequency > 0.0 ) {
|
||||
LARGE_INTEGER now;
|
||||
BOOL status = QueryPerformanceCounter( & now );
|
||||
if ( status ) {
|
||||
wtime = double( now.QuadPart ) / frequency;
|
||||
}; // if
|
||||
}; // if
|
||||
#else
|
||||
// gettimeofday() returns seconds and microseconds since the Epoch.
|
||||
struct timeval tval;
|
||||
int rc;
|
||||
rc = gettimeofday( & tval, NULL );
|
||||
if ( rc == 0 ) {
|
||||
wtime = (double)( tval.tv_sec ) + 1.0E-06 * (double)( tval.tv_usec );
|
||||
} else {
|
||||
// TODO: Assert or abort here.
|
||||
}; // if
|
||||
#endif
|
||||
return wtime;
|
||||
double __kmps_get_wtime(void) {
|
||||
// Elapsed wall clock time (in second) from "sometime in the past".
|
||||
double wtime = 0.0;
|
||||
i;
|
||||
#if KMP_OS_WINDOWS
|
||||
if (frequency > 0.0) {
|
||||
LARGE_INTEGER now;
|
||||
BOOL status = QueryPerformanceCounter(&now);
|
||||
if (status) {
|
||||
wtime = double(now.QuadPart) / frequency;
|
||||
}; // if
|
||||
}; // if
|
||||
#else
|
||||
// gettimeofday() returns seconds and microseconds since the Epoch.
|
||||
struct timeval tval;
|
||||
int rc;
|
||||
rc = gettimeofday(&tval, NULL);
|
||||
if (rc == 0) {
|
||||
wtime = (double)(tval.tv_sec) + 1.0E-06 * (double)(tval.tv_usec);
|
||||
} else {
|
||||
// TODO: Assert or abort here.
|
||||
}; // if
|
||||
#endif
|
||||
return wtime;
|
||||
}; // __kmps_get_wtime
|
||||
|
||||
double __kmps_get_wtick( void ) {
|
||||
// Number of seconds between successive clock ticks.
|
||||
double wtick = 0.0;
|
||||
i;
|
||||
#if KMP_OS_WINDOWS
|
||||
{
|
||||
DWORD increment;
|
||||
DWORD adjustment;
|
||||
BOOL disabled;
|
||||
BOOL rc;
|
||||
rc = GetSystemTimeAdjustment( & adjustment, & increment, & disabled );
|
||||
if ( rc ) {
|
||||
wtick = 1.0E-07 * (double)( disabled ? increment : adjustment );
|
||||
} else {
|
||||
// TODO: Assert or abort here.
|
||||
wtick = 1.0E-03;
|
||||
}; // if
|
||||
}
|
||||
#else
|
||||
// TODO: gettimeofday() returns in microseconds, but what the precision?
|
||||
wtick = 1.0E-06;
|
||||
#endif
|
||||
return wtick;
|
||||
double __kmps_get_wtick(void) {
|
||||
// Number of seconds between successive clock ticks.
|
||||
double wtick = 0.0;
|
||||
i;
|
||||
#if KMP_OS_WINDOWS
|
||||
{
|
||||
DWORD increment;
|
||||
DWORD adjustment;
|
||||
BOOL disabled;
|
||||
BOOL rc;
|
||||
rc = GetSystemTimeAdjustment(&adjustment, &increment, &disabled);
|
||||
if (rc) {
|
||||
wtick = 1.0E-07 * (double)(disabled ? increment : adjustment);
|
||||
} else {
|
||||
// TODO: Assert or abort here.
|
||||
wtick = 1.0E-03;
|
||||
}; // if
|
||||
}
|
||||
#else
|
||||
// TODO: gettimeofday() returns in microseconds, but what the precision?
|
||||
wtick = 1.0E-06;
|
||||
#endif
|
||||
return wtick;
|
||||
}; // __kmps_get_wtick
|
||||
|
||||
// end of file //
|
||||
|
||||
|
||||
+21
-21
@@ -17,43 +17,43 @@
|
||||
#define KMP_STUB_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
void __kmps_set_blocktime( int arg );
|
||||
int __kmps_get_blocktime( void );
|
||||
void __kmps_set_dynamic( int arg );
|
||||
int __kmps_get_dynamic( void );
|
||||
void __kmps_set_library( int arg );
|
||||
int __kmps_get_library( void );
|
||||
void __kmps_set_nested( int arg );
|
||||
int __kmps_get_nested( void );
|
||||
void __kmps_set_stacksize( int arg );
|
||||
int __kmps_get_stacksize();
|
||||
void __kmps_set_blocktime(int arg);
|
||||
int __kmps_get_blocktime(void);
|
||||
void __kmps_set_dynamic(int arg);
|
||||
int __kmps_get_dynamic(void);
|
||||
void __kmps_set_library(int arg);
|
||||
int __kmps_get_library(void);
|
||||
void __kmps_set_nested(int arg);
|
||||
int __kmps_get_nested(void);
|
||||
void __kmps_set_stacksize(int arg);
|
||||
int __kmps_get_stacksize();
|
||||
|
||||
#ifndef KMP_SCHED_TYPE_DEFINED
|
||||
#define KMP_SCHED_TYPE_DEFINED
|
||||
typedef enum kmp_sched {
|
||||
kmp_sched_static = 1, // mapped to kmp_sch_static_chunked (33)
|
||||
kmp_sched_dynamic = 2, // mapped to kmp_sch_dynamic_chunked (35)
|
||||
kmp_sched_guided = 3, // mapped to kmp_sch_guided_chunked (36)
|
||||
kmp_sched_auto = 4, // mapped to kmp_sch_auto (38)
|
||||
kmp_sched_default = kmp_sched_static // default scheduling
|
||||
kmp_sched_static = 1, // mapped to kmp_sch_static_chunked (33)
|
||||
kmp_sched_dynamic = 2, // mapped to kmp_sch_dynamic_chunked (35)
|
||||
kmp_sched_guided = 3, // mapped to kmp_sch_guided_chunked (36)
|
||||
kmp_sched_auto = 4, // mapped to kmp_sch_auto (38)
|
||||
kmp_sched_default = kmp_sched_static // default scheduling
|
||||
} kmp_sched_t;
|
||||
#endif
|
||||
void __kmps_set_schedule( kmp_sched_t kind, int modifier );
|
||||
void __kmps_get_schedule( kmp_sched_t *kind, int *modifier );
|
||||
void __kmps_set_schedule(kmp_sched_t kind, int modifier);
|
||||
void __kmps_get_schedule(kmp_sched_t *kind, int *modifier);
|
||||
|
||||
#if OMP_40_ENABLED
|
||||
void __kmps_set_proc_bind( kmp_proc_bind_t arg );
|
||||
kmp_proc_bind_t __kmps_get_proc_bind( void );
|
||||
void __kmps_set_proc_bind(kmp_proc_bind_t arg);
|
||||
kmp_proc_bind_t __kmps_get_proc_bind(void);
|
||||
#endif /* OMP_40_ENABLED */
|
||||
|
||||
double __kmps_get_wtime();
|
||||
double __kmps_get_wtick();
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // KMP_STUB_H
|
||||
|
||||
+429
-386
@@ -21,511 +21,545 @@
|
||||
|
||||
#if OMP_40_ENABLED
|
||||
|
||||
//TODO: Improve memory allocation? keep a list of pre-allocated structures? allocate in blocks? re-use list finished list entries?
|
||||
//TODO: don't use atomic ref counters for stack-allocated nodes.
|
||||
//TODO: find an alternate to atomic refs for heap-allocated nodes?
|
||||
//TODO: Finish graph output support
|
||||
//TODO: kmp_lock_t seems a tad to big (and heavy weight) for this. Check other runtime locks
|
||||
//TODO: Any ITT support needed?
|
||||
// TODO: Improve memory allocation? keep a list of pre-allocated structures?
|
||||
// allocate in blocks? re-use list finished list entries?
|
||||
// TODO: don't use atomic ref counters for stack-allocated nodes.
|
||||
// TODO: find an alternate to atomic refs for heap-allocated nodes?
|
||||
// TODO: Finish graph output support
|
||||
// TODO: kmp_lock_t seems a tad to big (and heavy weight) for this. Check other
|
||||
// runtime locks
|
||||
// TODO: Any ITT support needed?
|
||||
|
||||
#ifdef KMP_SUPPORT_GRAPH_OUTPUT
|
||||
static kmp_int32 kmp_node_id_seed = 0;
|
||||
#endif
|
||||
|
||||
static void
|
||||
__kmp_init_node ( kmp_depnode_t *node )
|
||||
{
|
||||
node->dn.task = NULL; // set to null initially, it will point to the right task once dependences have been processed
|
||||
node->dn.successors = NULL;
|
||||
__kmp_init_lock(&node->dn.lock);
|
||||
node->dn.nrefs = 1; // init creates the first reference to the node
|
||||
static void __kmp_init_node(kmp_depnode_t *node) {
|
||||
node->dn.task = NULL; // set to null initially, it will point to the right
|
||||
// task once dependences have been processed
|
||||
node->dn.successors = NULL;
|
||||
__kmp_init_lock(&node->dn.lock);
|
||||
node->dn.nrefs = 1; // init creates the first reference to the node
|
||||
#ifdef KMP_SUPPORT_GRAPH_OUTPUT
|
||||
node->dn.id = KMP_TEST_THEN_INC32(&kmp_node_id_seed);
|
||||
node->dn.id = KMP_TEST_THEN_INC32(&kmp_node_id_seed);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline kmp_depnode_t *
|
||||
__kmp_node_ref ( kmp_depnode_t *node )
|
||||
{
|
||||
KMP_TEST_THEN_INC32(&node->dn.nrefs);
|
||||
return node;
|
||||
static inline kmp_depnode_t *__kmp_node_ref(kmp_depnode_t *node) {
|
||||
KMP_TEST_THEN_INC32(CCAST(kmp_int32 *, &node->dn.nrefs));
|
||||
return node;
|
||||
}
|
||||
|
||||
static inline void
|
||||
__kmp_node_deref ( kmp_info_t *thread, kmp_depnode_t *node )
|
||||
{
|
||||
if (!node) return;
|
||||
static inline void __kmp_node_deref(kmp_info_t *thread, kmp_depnode_t *node) {
|
||||
if (!node)
|
||||
return;
|
||||
|
||||
kmp_int32 n = KMP_TEST_THEN_DEC32(&node->dn.nrefs) - 1;
|
||||
if ( n == 0 ) {
|
||||
KMP_ASSERT(node->dn.nrefs == 0);
|
||||
kmp_int32 n = KMP_TEST_THEN_DEC32(CCAST(kmp_int32 *, &node->dn.nrefs)) - 1;
|
||||
if (n == 0) {
|
||||
KMP_ASSERT(node->dn.nrefs == 0);
|
||||
#if USE_FAST_MEMORY
|
||||
__kmp_fast_free(thread,node);
|
||||
__kmp_fast_free(thread, node);
|
||||
#else
|
||||
__kmp_thread_free(thread,node);
|
||||
__kmp_thread_free(thread, node);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define KMP_ACQUIRE_DEPNODE(gtid,n) __kmp_acquire_lock(&(n)->dn.lock,(gtid))
|
||||
#define KMP_RELEASE_DEPNODE(gtid,n) __kmp_release_lock(&(n)->dn.lock,(gtid))
|
||||
#define KMP_ACQUIRE_DEPNODE(gtid, n) __kmp_acquire_lock(&(n)->dn.lock, (gtid))
|
||||
#define KMP_RELEASE_DEPNODE(gtid, n) __kmp_release_lock(&(n)->dn.lock, (gtid))
|
||||
|
||||
static void
|
||||
__kmp_depnode_list_free ( kmp_info_t *thread, kmp_depnode_list *list );
|
||||
static void __kmp_depnode_list_free(kmp_info_t *thread, kmp_depnode_list *list);
|
||||
|
||||
enum {
|
||||
KMP_DEPHASH_OTHER_SIZE = 97,
|
||||
KMP_DEPHASH_MASTER_SIZE = 997
|
||||
};
|
||||
enum { KMP_DEPHASH_OTHER_SIZE = 97, KMP_DEPHASH_MASTER_SIZE = 997 };
|
||||
|
||||
static inline kmp_int32
|
||||
__kmp_dephash_hash ( kmp_intptr_t addr, size_t hsize )
|
||||
{
|
||||
//TODO alternate to try: set = (((Addr64)(addrUsefulBits * 9.618)) % m_num_sets );
|
||||
return ((addr >> 6) ^ (addr >> 2)) % hsize;
|
||||
static inline kmp_int32 __kmp_dephash_hash(kmp_intptr_t addr, size_t hsize) {
|
||||
// TODO alternate to try: set = (((Addr64)(addrUsefulBits * 9.618)) %
|
||||
// m_num_sets );
|
||||
return ((addr >> 6) ^ (addr >> 2)) % hsize;
|
||||
}
|
||||
|
||||
static kmp_dephash_t *
|
||||
__kmp_dephash_create ( kmp_info_t *thread, kmp_taskdata_t *current_task )
|
||||
{
|
||||
kmp_dephash_t *h;
|
||||
static kmp_dephash_t *__kmp_dephash_create(kmp_info_t *thread,
|
||||
kmp_taskdata_t *current_task) {
|
||||
kmp_dephash_t *h;
|
||||
|
||||
size_t h_size;
|
||||
size_t h_size;
|
||||
|
||||
if ( current_task->td_flags.tasktype == TASK_IMPLICIT )
|
||||
h_size = KMP_DEPHASH_MASTER_SIZE;
|
||||
else
|
||||
h_size = KMP_DEPHASH_OTHER_SIZE;
|
||||
if (current_task->td_flags.tasktype == TASK_IMPLICIT)
|
||||
h_size = KMP_DEPHASH_MASTER_SIZE;
|
||||
else
|
||||
h_size = KMP_DEPHASH_OTHER_SIZE;
|
||||
|
||||
kmp_int32 size =
|
||||
h_size * sizeof(kmp_dephash_entry_t *) + sizeof(kmp_dephash_t);
|
||||
kmp_int32 size =
|
||||
h_size * sizeof(kmp_dephash_entry_t *) + sizeof(kmp_dephash_t);
|
||||
|
||||
#if USE_FAST_MEMORY
|
||||
h = (kmp_dephash_t *) __kmp_fast_allocate( thread, size );
|
||||
h = (kmp_dephash_t *)__kmp_fast_allocate(thread, size);
|
||||
#else
|
||||
h = (kmp_dephash_t *) __kmp_thread_malloc( thread, size );
|
||||
h = (kmp_dephash_t *)__kmp_thread_malloc(thread, size);
|
||||
#endif
|
||||
h->size = h_size;
|
||||
h->size = h_size;
|
||||
|
||||
#ifdef KMP_DEBUG
|
||||
h->nelements = 0;
|
||||
h->nconflicts = 0;
|
||||
h->nelements = 0;
|
||||
h->nconflicts = 0;
|
||||
#endif
|
||||
h->buckets = (kmp_dephash_entry **)(h+1);
|
||||
h->buckets = (kmp_dephash_entry **)(h + 1);
|
||||
|
||||
for ( size_t i = 0; i < h_size; i++ )
|
||||
h->buckets[i] = 0;
|
||||
for (size_t i = 0; i < h_size; i++)
|
||||
h->buckets[i] = 0;
|
||||
|
||||
return h;
|
||||
return h;
|
||||
}
|
||||
|
||||
void
|
||||
__kmp_dephash_free_entries(kmp_info_t *thread, kmp_dephash_t *h)
|
||||
{
|
||||
for (size_t i = 0; i < h->size; i++) {
|
||||
if (h->buckets[i]) {
|
||||
kmp_dephash_entry_t *next;
|
||||
for (kmp_dephash_entry_t *entry = h->buckets[i]; entry; entry = next) {
|
||||
next = entry->next_in_bucket;
|
||||
__kmp_depnode_list_free(thread,entry->last_ins);
|
||||
__kmp_node_deref(thread,entry->last_out);
|
||||
void __kmp_dephash_free_entries(kmp_info_t *thread, kmp_dephash_t *h) {
|
||||
for (size_t i = 0; i < h->size; i++) {
|
||||
if (h->buckets[i]) {
|
||||
kmp_dephash_entry_t *next;
|
||||
for (kmp_dephash_entry_t *entry = h->buckets[i]; entry; entry = next) {
|
||||
next = entry->next_in_bucket;
|
||||
__kmp_depnode_list_free(thread, entry->last_ins);
|
||||
__kmp_node_deref(thread, entry->last_out);
|
||||
#if USE_FAST_MEMORY
|
||||
__kmp_fast_free(thread,entry);
|
||||
__kmp_fast_free(thread, entry);
|
||||
#else
|
||||
__kmp_thread_free(thread,entry);
|
||||
__kmp_thread_free(thread, entry);
|
||||
#endif
|
||||
}
|
||||
h->buckets[i] = 0;
|
||||
}
|
||||
}
|
||||
h->buckets[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
__kmp_dephash_free(kmp_info_t *thread, kmp_dephash_t *h)
|
||||
{
|
||||
__kmp_dephash_free_entries(thread, h);
|
||||
void __kmp_dephash_free(kmp_info_t *thread, kmp_dephash_t *h) {
|
||||
__kmp_dephash_free_entries(thread, h);
|
||||
#if USE_FAST_MEMORY
|
||||
__kmp_fast_free(thread,h);
|
||||
__kmp_fast_free(thread, h);
|
||||
#else
|
||||
__kmp_thread_free(thread,h);
|
||||
__kmp_thread_free(thread, h);
|
||||
#endif
|
||||
}
|
||||
|
||||
static kmp_dephash_entry *
|
||||
__kmp_dephash_find ( kmp_info_t *thread, kmp_dephash_t *h, kmp_intptr_t addr )
|
||||
{
|
||||
kmp_int32 bucket = __kmp_dephash_hash(addr,h->size);
|
||||
__kmp_dephash_find(kmp_info_t *thread, kmp_dephash_t *h, kmp_intptr_t addr) {
|
||||
kmp_int32 bucket = __kmp_dephash_hash(addr, h->size);
|
||||
|
||||
kmp_dephash_entry_t *entry;
|
||||
for ( entry = h->buckets[bucket]; entry; entry = entry->next_in_bucket )
|
||||
if ( entry->addr == addr ) break;
|
||||
kmp_dephash_entry_t *entry;
|
||||
for (entry = h->buckets[bucket]; entry; entry = entry->next_in_bucket)
|
||||
if (entry->addr == addr)
|
||||
break;
|
||||
|
||||
if ( entry == NULL ) {
|
||||
// create entry. This is only done by one thread so no locking required
|
||||
if (entry == NULL) {
|
||||
// create entry. This is only done by one thread so no locking required
|
||||
#if USE_FAST_MEMORY
|
||||
entry = (kmp_dephash_entry_t *) __kmp_fast_allocate( thread, sizeof(kmp_dephash_entry_t) );
|
||||
entry = (kmp_dephash_entry_t *)__kmp_fast_allocate(
|
||||
thread, sizeof(kmp_dephash_entry_t));
|
||||
#else
|
||||
entry = (kmp_dephash_entry_t *) __kmp_thread_malloc( thread, sizeof(kmp_dephash_entry_t) );
|
||||
entry = (kmp_dephash_entry_t *)__kmp_thread_malloc(
|
||||
thread, sizeof(kmp_dephash_entry_t));
|
||||
#endif
|
||||
entry->addr = addr;
|
||||
entry->last_out = NULL;
|
||||
entry->last_ins = NULL;
|
||||
entry->next_in_bucket = h->buckets[bucket];
|
||||
h->buckets[bucket] = entry;
|
||||
entry->addr = addr;
|
||||
entry->last_out = NULL;
|
||||
entry->last_ins = NULL;
|
||||
entry->next_in_bucket = h->buckets[bucket];
|
||||
h->buckets[bucket] = entry;
|
||||
#ifdef KMP_DEBUG
|
||||
h->nelements++;
|
||||
if ( entry->next_in_bucket ) h->nconflicts++;
|
||||
h->nelements++;
|
||||
if (entry->next_in_bucket)
|
||||
h->nconflicts++;
|
||||
#endif
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
static kmp_depnode_list_t *
|
||||
__kmp_add_node ( kmp_info_t *thread, kmp_depnode_list_t *list, kmp_depnode_t *node )
|
||||
{
|
||||
kmp_depnode_list_t *new_head;
|
||||
static kmp_depnode_list_t *__kmp_add_node(kmp_info_t *thread,
|
||||
kmp_depnode_list_t *list,
|
||||
kmp_depnode_t *node) {
|
||||
kmp_depnode_list_t *new_head;
|
||||
|
||||
#if USE_FAST_MEMORY
|
||||
new_head = (kmp_depnode_list_t *) __kmp_fast_allocate(thread,sizeof(kmp_depnode_list_t));
|
||||
new_head = (kmp_depnode_list_t *)__kmp_fast_allocate(
|
||||
thread, sizeof(kmp_depnode_list_t));
|
||||
#else
|
||||
new_head = (kmp_depnode_list_t *) __kmp_thread_malloc(thread,sizeof(kmp_depnode_list_t));
|
||||
new_head = (kmp_depnode_list_t *)__kmp_thread_malloc(
|
||||
thread, sizeof(kmp_depnode_list_t));
|
||||
#endif
|
||||
|
||||
new_head->node = __kmp_node_ref(node);
|
||||
new_head->next = list;
|
||||
new_head->node = __kmp_node_ref(node);
|
||||
new_head->next = list;
|
||||
|
||||
return new_head;
|
||||
return new_head;
|
||||
}
|
||||
|
||||
static void
|
||||
__kmp_depnode_list_free ( kmp_info_t *thread, kmp_depnode_list *list )
|
||||
{
|
||||
kmp_depnode_list *next;
|
||||
static void __kmp_depnode_list_free(kmp_info_t *thread,
|
||||
kmp_depnode_list *list) {
|
||||
kmp_depnode_list *next;
|
||||
|
||||
for ( ; list ; list = next ) {
|
||||
next = list->next;
|
||||
for (; list; list = next) {
|
||||
next = list->next;
|
||||
|
||||
__kmp_node_deref(thread,list->node);
|
||||
__kmp_node_deref(thread, list->node);
|
||||
#if USE_FAST_MEMORY
|
||||
__kmp_fast_free(thread,list);
|
||||
__kmp_fast_free(thread, list);
|
||||
#else
|
||||
__kmp_thread_free(thread,list);
|
||||
__kmp_thread_free(thread, list);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
__kmp_track_dependence ( kmp_depnode_t *source, kmp_depnode_t *sink,
|
||||
kmp_task_t *sink_task )
|
||||
{
|
||||
static inline void __kmp_track_dependence(kmp_depnode_t *source,
|
||||
kmp_depnode_t *sink,
|
||||
kmp_task_t *sink_task) {
|
||||
#ifdef KMP_SUPPORT_GRAPH_OUTPUT
|
||||
kmp_taskdata_t * task_source = KMP_TASK_TO_TASKDATA(source->dn.task);
|
||||
// do not use sink->dn.task as that is only filled after the dependencies
|
||||
// are already processed!
|
||||
kmp_taskdata_t * task_sink = KMP_TASK_TO_TASKDATA(sink_task);
|
||||
kmp_taskdata_t *task_source = KMP_TASK_TO_TASKDATA(source->dn.task);
|
||||
// do not use sink->dn.task as that is only filled after the dependencies
|
||||
// are already processed!
|
||||
kmp_taskdata_t *task_sink = KMP_TASK_TO_TASKDATA(sink_task);
|
||||
|
||||
__kmp_printf("%d(%s) -> %d(%s)\n", source->dn.id, task_source->td_ident->psource, sink->dn.id, task_sink->td_ident->psource);
|
||||
__kmp_printf("%d(%s) -> %d(%s)\n", source->dn.id,
|
||||
task_source->td_ident->psource, sink->dn.id,
|
||||
task_sink->td_ident->psource);
|
||||
#endif
|
||||
#if OMPT_SUPPORT && OMPT_TRACE
|
||||
/* OMPT tracks dependences between task (a=source, b=sink) in which
|
||||
task a blocks the execution of b through the ompt_new_dependence_callback */
|
||||
if (ompt_enabled &&
|
||||
ompt_callbacks.ompt_callback(ompt_event_task_dependence_pair))
|
||||
{
|
||||
kmp_taskdata_t * task_source = KMP_TASK_TO_TASKDATA(source->dn.task);
|
||||
kmp_taskdata_t * task_sink = KMP_TASK_TO_TASKDATA(sink_task);
|
||||
// OMPT tracks dependences between task (a=source, b=sink) in which
|
||||
// task a blocks the execution of b through the ompt_new_dependence_callback
|
||||
if (ompt_enabled &&
|
||||
ompt_callbacks.ompt_callback(ompt_event_task_dependence_pair)) {
|
||||
kmp_taskdata_t *task_source = KMP_TASK_TO_TASKDATA(source->dn.task);
|
||||
kmp_taskdata_t *task_sink = KMP_TASK_TO_TASKDATA(sink_task);
|
||||
|
||||
ompt_callbacks.ompt_callback(ompt_event_task_dependence_pair)(
|
||||
task_source->ompt_task_info.task_id,
|
||||
task_sink->ompt_task_info.task_id);
|
||||
}
|
||||
ompt_callbacks.ompt_callback(ompt_event_task_dependence_pair)(
|
||||
task_source->ompt_task_info.task_id, task_sink->ompt_task_info.task_id);
|
||||
}
|
||||
#endif /* OMPT_SUPPORT && OMPT_TRACE */
|
||||
}
|
||||
|
||||
template< bool filter >
|
||||
template <bool filter>
|
||||
static inline kmp_int32
|
||||
__kmp_process_deps ( kmp_int32 gtid, kmp_depnode_t *node, kmp_dephash_t *hash,
|
||||
bool dep_barrier,kmp_int32 ndeps, kmp_depend_info_t *dep_list,
|
||||
kmp_task_t *task )
|
||||
{
|
||||
KA_TRACE(30, ("__kmp_process_deps<%d>: T#%d processing %d dependencies : dep_barrier = %d\n", filter, gtid, ndeps, dep_barrier ) );
|
||||
__kmp_process_deps(kmp_int32 gtid, kmp_depnode_t *node, kmp_dephash_t *hash,
|
||||
bool dep_barrier, kmp_int32 ndeps,
|
||||
kmp_depend_info_t *dep_list, kmp_task_t *task) {
|
||||
KA_TRACE(30, ("__kmp_process_deps<%d>: T#%d processing %d dependencies : "
|
||||
"dep_barrier = %d\n",
|
||||
filter, gtid, ndeps, dep_barrier));
|
||||
|
||||
kmp_info_t *thread = __kmp_threads[ gtid ];
|
||||
kmp_int32 npredecessors=0;
|
||||
for ( kmp_int32 i = 0; i < ndeps ; i++ ) {
|
||||
const kmp_depend_info_t * dep = &dep_list[i];
|
||||
kmp_info_t *thread = __kmp_threads[gtid];
|
||||
kmp_int32 npredecessors = 0;
|
||||
for (kmp_int32 i = 0; i < ndeps; i++) {
|
||||
const kmp_depend_info_t *dep = &dep_list[i];
|
||||
|
||||
KMP_DEBUG_ASSERT(dep->flags.in);
|
||||
KMP_DEBUG_ASSERT(dep->flags.in);
|
||||
|
||||
if ( filter && dep->base_addr == 0 ) continue; // skip filtered entries
|
||||
if (filter && dep->base_addr == 0)
|
||||
continue; // skip filtered entries
|
||||
|
||||
kmp_dephash_entry_t *info = __kmp_dephash_find(thread,hash,dep->base_addr);
|
||||
kmp_depnode_t *last_out = info->last_out;
|
||||
kmp_dephash_entry_t *info =
|
||||
__kmp_dephash_find(thread, hash, dep->base_addr);
|
||||
kmp_depnode_t *last_out = info->last_out;
|
||||
|
||||
if ( dep->flags.out && info->last_ins ) {
|
||||
for ( kmp_depnode_list_t * p = info->last_ins; p; p = p->next ) {
|
||||
kmp_depnode_t * indep = p->node;
|
||||
if ( indep->dn.task ) {
|
||||
KMP_ACQUIRE_DEPNODE(gtid,indep);
|
||||
if ( indep->dn.task ) {
|
||||
__kmp_track_dependence(indep,node,task);
|
||||
indep->dn.successors = __kmp_add_node(thread, indep->dn.successors, node);
|
||||
KA_TRACE(40,("__kmp_process_deps<%d>: T#%d adding dependence from %p to %p\n",
|
||||
filter,gtid, KMP_TASK_TO_TASKDATA(indep->dn.task), KMP_TASK_TO_TASKDATA(task)));
|
||||
npredecessors++;
|
||||
}
|
||||
KMP_RELEASE_DEPNODE(gtid,indep);
|
||||
}
|
||||
}
|
||||
|
||||
__kmp_depnode_list_free(thread,info->last_ins);
|
||||
info->last_ins = NULL;
|
||||
|
||||
} else if ( last_out && last_out->dn.task ) {
|
||||
KMP_ACQUIRE_DEPNODE(gtid,last_out);
|
||||
if ( last_out->dn.task ) {
|
||||
__kmp_track_dependence(last_out,node,task);
|
||||
last_out->dn.successors = __kmp_add_node(thread, last_out->dn.successors, node);
|
||||
KA_TRACE(40,("__kmp_process_deps<%d>: T#%d adding dependence from %p to %p\n",
|
||||
filter,gtid, KMP_TASK_TO_TASKDATA(last_out->dn.task), KMP_TASK_TO_TASKDATA(task)));
|
||||
|
||||
npredecessors++;
|
||||
}
|
||||
KMP_RELEASE_DEPNODE(gtid,last_out);
|
||||
if (dep->flags.out && info->last_ins) {
|
||||
for (kmp_depnode_list_t *p = info->last_ins; p; p = p->next) {
|
||||
kmp_depnode_t *indep = p->node;
|
||||
if (indep->dn.task) {
|
||||
KMP_ACQUIRE_DEPNODE(gtid, indep);
|
||||
if (indep->dn.task) {
|
||||
__kmp_track_dependence(indep, node, task);
|
||||
indep->dn.successors =
|
||||
__kmp_add_node(thread, indep->dn.successors, node);
|
||||
KA_TRACE(40, ("__kmp_process_deps<%d>: T#%d adding dependence from "
|
||||
"%p to %p\n",
|
||||
filter, gtid, KMP_TASK_TO_TASKDATA(indep->dn.task),
|
||||
KMP_TASK_TO_TASKDATA(task)));
|
||||
npredecessors++;
|
||||
}
|
||||
KMP_RELEASE_DEPNODE(gtid, indep);
|
||||
}
|
||||
}
|
||||
|
||||
if ( dep_barrier ) {
|
||||
// if this is a sync point in the serial sequence, then the previous outputs are guaranteed to be completed after
|
||||
// the execution of this task so the previous output nodes can be cleared.
|
||||
__kmp_node_deref(thread,last_out);
|
||||
info->last_out = NULL;
|
||||
} else {
|
||||
if ( dep->flags.out ) {
|
||||
__kmp_node_deref(thread,last_out);
|
||||
info->last_out = __kmp_node_ref(node);
|
||||
} else
|
||||
info->last_ins = __kmp_add_node(thread, info->last_ins, node);
|
||||
}
|
||||
__kmp_depnode_list_free(thread, info->last_ins);
|
||||
info->last_ins = NULL;
|
||||
|
||||
} else if (last_out && last_out->dn.task) {
|
||||
KMP_ACQUIRE_DEPNODE(gtid, last_out);
|
||||
if (last_out->dn.task) {
|
||||
__kmp_track_dependence(last_out, node, task);
|
||||
last_out->dn.successors =
|
||||
__kmp_add_node(thread, last_out->dn.successors, node);
|
||||
KA_TRACE(
|
||||
40,
|
||||
("__kmp_process_deps<%d>: T#%d adding dependence from %p to %p\n",
|
||||
filter, gtid, KMP_TASK_TO_TASKDATA(last_out->dn.task),
|
||||
KMP_TASK_TO_TASKDATA(task)));
|
||||
|
||||
npredecessors++;
|
||||
}
|
||||
KMP_RELEASE_DEPNODE(gtid, last_out);
|
||||
}
|
||||
|
||||
KA_TRACE(30, ("__kmp_process_deps<%d>: T#%d found %d predecessors\n", filter, gtid, npredecessors ) );
|
||||
if (dep_barrier) {
|
||||
// if this is a sync point in the serial sequence, then the previous
|
||||
// outputs are guaranteed to be completed after
|
||||
// the execution of this task so the previous output nodes can be cleared.
|
||||
__kmp_node_deref(thread, last_out);
|
||||
info->last_out = NULL;
|
||||
} else {
|
||||
if (dep->flags.out) {
|
||||
__kmp_node_deref(thread, last_out);
|
||||
info->last_out = __kmp_node_ref(node);
|
||||
} else
|
||||
info->last_ins = __kmp_add_node(thread, info->last_ins, node);
|
||||
}
|
||||
}
|
||||
|
||||
return npredecessors;
|
||||
KA_TRACE(30, ("__kmp_process_deps<%d>: T#%d found %d predecessors\n", filter,
|
||||
gtid, npredecessors));
|
||||
|
||||
return npredecessors;
|
||||
}
|
||||
|
||||
#define NO_DEP_BARRIER (false)
|
||||
#define DEP_BARRIER (true)
|
||||
|
||||
// returns true if the task has any outstanding dependence
|
||||
static bool
|
||||
__kmp_check_deps ( kmp_int32 gtid, kmp_depnode_t *node, kmp_task_t *task, kmp_dephash_t *hash, bool dep_barrier,
|
||||
kmp_int32 ndeps, kmp_depend_info_t *dep_list,
|
||||
kmp_int32 ndeps_noalias, kmp_depend_info_t *noalias_dep_list )
|
||||
{
|
||||
int i;
|
||||
static bool __kmp_check_deps(kmp_int32 gtid, kmp_depnode_t *node,
|
||||
kmp_task_t *task, kmp_dephash_t *hash,
|
||||
bool dep_barrier, kmp_int32 ndeps,
|
||||
kmp_depend_info_t *dep_list,
|
||||
kmp_int32 ndeps_noalias,
|
||||
kmp_depend_info_t *noalias_dep_list) {
|
||||
int i;
|
||||
|
||||
#if KMP_DEBUG
|
||||
kmp_taskdata_t * taskdata = KMP_TASK_TO_TASKDATA(task);
|
||||
kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(task);
|
||||
#endif
|
||||
KA_TRACE(20, ("__kmp_check_deps: T#%d checking dependencies for task %p : %d possibly aliased dependencies, %d non-aliased depedencies : dep_barrier=%d .\n", gtid, taskdata, ndeps, ndeps_noalias, dep_barrier ) );
|
||||
KA_TRACE(20, ("__kmp_check_deps: T#%d checking dependencies for task %p : %d "
|
||||
"possibly aliased dependencies, %d non-aliased depedencies : "
|
||||
"dep_barrier=%d .\n",
|
||||
gtid, taskdata, ndeps, ndeps_noalias, dep_barrier));
|
||||
|
||||
// Filter deps in dep_list
|
||||
// TODO: Different algorithm for large dep_list ( > 10 ? )
|
||||
for ( i = 0; i < ndeps; i ++ ) {
|
||||
if ( dep_list[i].base_addr != 0 )
|
||||
for ( int j = i+1; j < ndeps; j++ )
|
||||
if ( dep_list[i].base_addr == dep_list[j].base_addr ) {
|
||||
dep_list[i].flags.in |= dep_list[j].flags.in;
|
||||
dep_list[i].flags.out |= dep_list[j].flags.out;
|
||||
dep_list[j].base_addr = 0; // Mark j element as void
|
||||
}
|
||||
}
|
||||
// Filter deps in dep_list
|
||||
// TODO: Different algorithm for large dep_list ( > 10 ? )
|
||||
for (i = 0; i < ndeps; i++) {
|
||||
if (dep_list[i].base_addr != 0)
|
||||
for (int j = i + 1; j < ndeps; j++)
|
||||
if (dep_list[i].base_addr == dep_list[j].base_addr) {
|
||||
dep_list[i].flags.in |= dep_list[j].flags.in;
|
||||
dep_list[i].flags.out |= dep_list[j].flags.out;
|
||||
dep_list[j].base_addr = 0; // Mark j element as void
|
||||
}
|
||||
}
|
||||
|
||||
// doesn't need to be atomic as no other thread is going to be accessing this node just yet
|
||||
// npredecessors is set -1 to ensure that none of the releasing tasks queues this task before we have finished processing all the dependencies
|
||||
node->dn.npredecessors = -1;
|
||||
// doesn't need to be atomic as no other thread is going to be accessing this
|
||||
// node just yet.
|
||||
// npredecessors is set -1 to ensure that none of the releasing tasks queues
|
||||
// this task before we have finished processing all the dependencies
|
||||
node->dn.npredecessors = -1;
|
||||
|
||||
// used to pack all npredecessors additions into a single atomic operation at the end
|
||||
int npredecessors;
|
||||
// used to pack all npredecessors additions into a single atomic operation at
|
||||
// the end
|
||||
int npredecessors;
|
||||
|
||||
npredecessors = __kmp_process_deps<true>(gtid, node, hash, dep_barrier,
|
||||
ndeps, dep_list, task);
|
||||
npredecessors += __kmp_process_deps<false>(gtid, node, hash, dep_barrier,
|
||||
ndeps_noalias, noalias_dep_list, task);
|
||||
npredecessors = __kmp_process_deps<true>(gtid, node, hash, dep_barrier, ndeps,
|
||||
dep_list, task);
|
||||
npredecessors += __kmp_process_deps<false>(
|
||||
gtid, node, hash, dep_barrier, ndeps_noalias, noalias_dep_list, task);
|
||||
|
||||
node->dn.task = task;
|
||||
KMP_MB();
|
||||
node->dn.task = task;
|
||||
KMP_MB();
|
||||
|
||||
// Account for our initial fake value
|
||||
npredecessors++;
|
||||
// Account for our initial fake value
|
||||
npredecessors++;
|
||||
|
||||
// Update predecessors and obtain current value to check if there are still any outstandig dependences (some tasks may have finished while we processed the dependences)
|
||||
npredecessors = KMP_TEST_THEN_ADD32(&node->dn.npredecessors, npredecessors) + npredecessors;
|
||||
// Update predecessors and obtain current value to check if there are still
|
||||
// any outstandig dependences (some tasks may have finished while we processed
|
||||
// the dependences)
|
||||
npredecessors =
|
||||
KMP_TEST_THEN_ADD32(CCAST(kmp_int32 *, &node->dn.npredecessors),
|
||||
npredecessors) +
|
||||
npredecessors;
|
||||
|
||||
KA_TRACE(20, ("__kmp_check_deps: T#%d found %d predecessors for task %p \n", gtid, npredecessors, taskdata ) );
|
||||
KA_TRACE(20, ("__kmp_check_deps: T#%d found %d predecessors for task %p \n",
|
||||
gtid, npredecessors, taskdata));
|
||||
|
||||
// beyond this point the task could be queued (and executed) by a releasing task...
|
||||
return npredecessors > 0 ? true : false;
|
||||
// beyond this point the task could be queued (and executed) by a releasing
|
||||
// task...
|
||||
return npredecessors > 0 ? true : false;
|
||||
}
|
||||
|
||||
void
|
||||
__kmp_release_deps ( kmp_int32 gtid, kmp_taskdata_t *task )
|
||||
{
|
||||
kmp_info_t *thread = __kmp_threads[ gtid ];
|
||||
kmp_depnode_t *node = task->td_depnode;
|
||||
void __kmp_release_deps(kmp_int32 gtid, kmp_taskdata_t *task) {
|
||||
kmp_info_t *thread = __kmp_threads[gtid];
|
||||
kmp_depnode_t *node = task->td_depnode;
|
||||
|
||||
if ( task->td_dephash ) {
|
||||
KA_TRACE(40, ("__kmp_release_deps: T#%d freeing dependencies hash of task %p.\n", gtid, task ) );
|
||||
__kmp_dephash_free(thread,task->td_dephash);
|
||||
task->td_dephash = NULL;
|
||||
if (task->td_dephash) {
|
||||
KA_TRACE(
|
||||
40, ("__kmp_release_deps: T#%d freeing dependencies hash of task %p.\n",
|
||||
gtid, task));
|
||||
__kmp_dephash_free(thread, task->td_dephash);
|
||||
task->td_dephash = NULL;
|
||||
}
|
||||
|
||||
if (!node)
|
||||
return;
|
||||
|
||||
KA_TRACE(20, ("__kmp_release_deps: T#%d notifying successors of task %p.\n",
|
||||
gtid, task));
|
||||
|
||||
KMP_ACQUIRE_DEPNODE(gtid, node);
|
||||
node->dn.task =
|
||||
NULL; // mark this task as finished, so no new dependencies are generated
|
||||
KMP_RELEASE_DEPNODE(gtid, node);
|
||||
|
||||
kmp_depnode_list_t *next;
|
||||
for (kmp_depnode_list_t *p = node->dn.successors; p; p = next) {
|
||||
kmp_depnode_t *successor = p->node;
|
||||
kmp_int32 npredecessors =
|
||||
KMP_TEST_THEN_DEC32(CCAST(kmp_int32 *, &successor->dn.npredecessors)) -
|
||||
1;
|
||||
// successor task can be NULL for wait_depends or because deps are still
|
||||
// being processed
|
||||
if (npredecessors == 0) {
|
||||
KMP_MB();
|
||||
if (successor->dn.task) {
|
||||
KA_TRACE(20, ("__kmp_release_deps: T#%d successor %p of %p scheduled "
|
||||
"for execution.\n",
|
||||
gtid, successor->dn.task, task));
|
||||
__kmp_omp_task(gtid, successor->dn.task, false);
|
||||
}
|
||||
}
|
||||
|
||||
if ( !node ) return;
|
||||
|
||||
KA_TRACE(20, ("__kmp_release_deps: T#%d notifying successors of task %p.\n", gtid, task ) );
|
||||
|
||||
KMP_ACQUIRE_DEPNODE(gtid,node);
|
||||
node->dn.task = NULL; // mark this task as finished, so no new dependencies are generated
|
||||
KMP_RELEASE_DEPNODE(gtid,node);
|
||||
|
||||
kmp_depnode_list_t *next;
|
||||
for ( kmp_depnode_list_t *p = node->dn.successors; p; p = next ) {
|
||||
kmp_depnode_t *successor = p->node;
|
||||
kmp_int32 npredecessors = KMP_TEST_THEN_DEC32(&successor->dn.npredecessors) - 1;
|
||||
|
||||
// successor task can be NULL for wait_depends or because deps are still being processed
|
||||
if ( npredecessors == 0 ) {
|
||||
KMP_MB();
|
||||
if ( successor->dn.task ) {
|
||||
KA_TRACE(20, ("__kmp_release_deps: T#%d successor %p of %p scheduled for execution.\n", gtid, successor->dn.task, task ) );
|
||||
__kmp_omp_task(gtid,successor->dn.task,false);
|
||||
}
|
||||
}
|
||||
|
||||
next = p->next;
|
||||
__kmp_node_deref(thread,p->node);
|
||||
next = p->next;
|
||||
__kmp_node_deref(thread, p->node);
|
||||
#if USE_FAST_MEMORY
|
||||
__kmp_fast_free(thread,p);
|
||||
__kmp_fast_free(thread, p);
|
||||
#else
|
||||
__kmp_thread_free(thread,p);
|
||||
__kmp_thread_free(thread, p);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
__kmp_node_deref(thread,node);
|
||||
__kmp_node_deref(thread, node);
|
||||
|
||||
KA_TRACE(20, ("__kmp_release_deps: T#%d all successors of %p notified of completion\n", gtid, task ) );
|
||||
KA_TRACE(
|
||||
20,
|
||||
("__kmp_release_deps: T#%d all successors of %p notified of completion\n",
|
||||
gtid, task));
|
||||
}
|
||||
|
||||
/*!
|
||||
@ingroup TASKING
|
||||
@param loc_ref location of the original task directive
|
||||
@param gtid Global Thread ID of encountering thread
|
||||
@param new_task task thunk allocated by __kmp_omp_task_alloc() for the ''new task''
|
||||
@param new_task task thunk allocated by __kmp_omp_task_alloc() for the ''new
|
||||
task''
|
||||
@param ndeps Number of depend items with possible aliasing
|
||||
@param dep_list List of depend items with possible aliasing
|
||||
@param ndeps_noalias Number of depend items with no aliasing
|
||||
@param noalias_dep_list List of depend items with no aliasing
|
||||
|
||||
@return Returns either TASK_CURRENT_NOT_QUEUED if the current task was not suspendend and queued, or TASK_CURRENT_QUEUED if it was suspended and queued
|
||||
@return Returns either TASK_CURRENT_NOT_QUEUED if the current task was not
|
||||
suspendend and queued, or TASK_CURRENT_QUEUED if it was suspended and queued
|
||||
|
||||
Schedule a non-thread-switchable task with dependences for execution
|
||||
*/
|
||||
kmp_int32
|
||||
__kmpc_omp_task_with_deps( ident_t *loc_ref, kmp_int32 gtid, kmp_task_t * new_task,
|
||||
kmp_int32 ndeps, kmp_depend_info_t *dep_list,
|
||||
kmp_int32 ndeps_noalias, kmp_depend_info_t *noalias_dep_list )
|
||||
{
|
||||
kmp_int32 __kmpc_omp_task_with_deps(ident_t *loc_ref, kmp_int32 gtid,
|
||||
kmp_task_t *new_task, kmp_int32 ndeps,
|
||||
kmp_depend_info_t *dep_list,
|
||||
kmp_int32 ndeps_noalias,
|
||||
kmp_depend_info_t *noalias_dep_list) {
|
||||
|
||||
kmp_taskdata_t * new_taskdata = KMP_TASK_TO_TASKDATA(new_task);
|
||||
KA_TRACE(10, ("__kmpc_omp_task_with_deps(enter): T#%d loc=%p task=%p\n",
|
||||
gtid, loc_ref, new_taskdata ) );
|
||||
kmp_taskdata_t *new_taskdata = KMP_TASK_TO_TASKDATA(new_task);
|
||||
KA_TRACE(10, ("__kmpc_omp_task_with_deps(enter): T#%d loc=%p task=%p\n", gtid,
|
||||
loc_ref, new_taskdata));
|
||||
|
||||
kmp_info_t *thread = __kmp_threads[ gtid ];
|
||||
kmp_taskdata_t * current_task = thread->th.th_current_task;
|
||||
kmp_info_t *thread = __kmp_threads[gtid];
|
||||
kmp_taskdata_t *current_task = thread->th.th_current_task;
|
||||
|
||||
#if OMPT_SUPPORT && OMPT_TRACE
|
||||
/* OMPT grab all dependences if requested by the tool */
|
||||
if (ompt_enabled && ndeps+ndeps_noalias > 0 &&
|
||||
ompt_callbacks.ompt_callback(ompt_event_task_dependences))
|
||||
{
|
||||
kmp_int32 i;
|
||||
/* OMPT grab all dependences if requested by the tool */
|
||||
if (ompt_enabled && ndeps + ndeps_noalias > 0 &&
|
||||
ompt_callbacks.ompt_callback(ompt_event_task_dependences)) {
|
||||
kmp_int32 i;
|
||||
|
||||
new_taskdata->ompt_task_info.ndeps = ndeps+ndeps_noalias;
|
||||
new_taskdata->ompt_task_info.deps = (ompt_task_dependence_t *)
|
||||
KMP_OMPT_DEPS_ALLOC(thread,
|
||||
(ndeps+ndeps_noalias)*sizeof(ompt_task_dependence_t));
|
||||
new_taskdata->ompt_task_info.ndeps = ndeps + ndeps_noalias;
|
||||
new_taskdata->ompt_task_info.deps =
|
||||
(ompt_task_dependence_t *)KMP_OMPT_DEPS_ALLOC(
|
||||
thread, (ndeps + ndeps_noalias) * sizeof(ompt_task_dependence_t));
|
||||
|
||||
KMP_ASSERT(new_taskdata->ompt_task_info.deps != NULL);
|
||||
KMP_ASSERT(new_taskdata->ompt_task_info.deps != NULL);
|
||||
|
||||
for (i = 0; i < ndeps; i++)
|
||||
{
|
||||
new_taskdata->ompt_task_info.deps[i].variable_addr =
|
||||
(void*) dep_list[i].base_addr;
|
||||
if (dep_list[i].flags.in && dep_list[i].flags.out)
|
||||
new_taskdata->ompt_task_info.deps[i].dependence_flags =
|
||||
ompt_task_dependence_type_inout;
|
||||
else if (dep_list[i].flags.out)
|
||||
new_taskdata->ompt_task_info.deps[i].dependence_flags =
|
||||
ompt_task_dependence_type_out;
|
||||
else if (dep_list[i].flags.in)
|
||||
new_taskdata->ompt_task_info.deps[i].dependence_flags =
|
||||
ompt_task_dependence_type_in;
|
||||
}
|
||||
for (i = 0; i < ndeps_noalias; i++)
|
||||
{
|
||||
new_taskdata->ompt_task_info.deps[ndeps+i].variable_addr =
|
||||
(void*) noalias_dep_list[i].base_addr;
|
||||
if (noalias_dep_list[i].flags.in && noalias_dep_list[i].flags.out)
|
||||
new_taskdata->ompt_task_info.deps[ndeps+i].dependence_flags =
|
||||
ompt_task_dependence_type_inout;
|
||||
else if (noalias_dep_list[i].flags.out)
|
||||
new_taskdata->ompt_task_info.deps[ndeps+i].dependence_flags =
|
||||
ompt_task_dependence_type_out;
|
||||
else if (noalias_dep_list[i].flags.in)
|
||||
new_taskdata->ompt_task_info.deps[ndeps+i].dependence_flags =
|
||||
ompt_task_dependence_type_in;
|
||||
}
|
||||
for (i = 0; i < ndeps; i++) {
|
||||
new_taskdata->ompt_task_info.deps[i].variable_addr =
|
||||
(void *)dep_list[i].base_addr;
|
||||
if (dep_list[i].flags.in && dep_list[i].flags.out)
|
||||
new_taskdata->ompt_task_info.deps[i].dependence_flags =
|
||||
ompt_task_dependence_type_inout;
|
||||
else if (dep_list[i].flags.out)
|
||||
new_taskdata->ompt_task_info.deps[i].dependence_flags =
|
||||
ompt_task_dependence_type_out;
|
||||
else if (dep_list[i].flags.in)
|
||||
new_taskdata->ompt_task_info.deps[i].dependence_flags =
|
||||
ompt_task_dependence_type_in;
|
||||
}
|
||||
for (i = 0; i < ndeps_noalias; i++) {
|
||||
new_taskdata->ompt_task_info.deps[ndeps + i].variable_addr =
|
||||
(void *)noalias_dep_list[i].base_addr;
|
||||
if (noalias_dep_list[i].flags.in && noalias_dep_list[i].flags.out)
|
||||
new_taskdata->ompt_task_info.deps[ndeps + i].dependence_flags =
|
||||
ompt_task_dependence_type_inout;
|
||||
else if (noalias_dep_list[i].flags.out)
|
||||
new_taskdata->ompt_task_info.deps[ndeps + i].dependence_flags =
|
||||
ompt_task_dependence_type_out;
|
||||
else if (noalias_dep_list[i].flags.in)
|
||||
new_taskdata->ompt_task_info.deps[ndeps + i].dependence_flags =
|
||||
ompt_task_dependence_type_in;
|
||||
}
|
||||
}
|
||||
#endif /* OMPT_SUPPORT && OMPT_TRACE */
|
||||
|
||||
bool serial = current_task->td_flags.team_serial || current_task->td_flags.tasking_ser || current_task->td_flags.final;
|
||||
bool serial = current_task->td_flags.team_serial ||
|
||||
current_task->td_flags.tasking_ser ||
|
||||
current_task->td_flags.final;
|
||||
#if OMP_45_ENABLED
|
||||
kmp_task_team_t * task_team = thread->th.th_task_team;
|
||||
serial = serial && !(task_team && task_team->tt.tt_found_proxy_tasks);
|
||||
kmp_task_team_t *task_team = thread->th.th_task_team;
|
||||
serial = serial && !(task_team && task_team->tt.tt_found_proxy_tasks);
|
||||
#endif
|
||||
|
||||
if ( !serial && ( ndeps > 0 || ndeps_noalias > 0 )) {
|
||||
/* if no dependencies have been tracked yet, create the dependence hash */
|
||||
if ( current_task->td_dephash == NULL )
|
||||
current_task->td_dephash = __kmp_dephash_create(thread, current_task);
|
||||
if (!serial && (ndeps > 0 || ndeps_noalias > 0)) {
|
||||
/* if no dependencies have been tracked yet, create the dependence hash */
|
||||
if (current_task->td_dephash == NULL)
|
||||
current_task->td_dephash = __kmp_dephash_create(thread, current_task);
|
||||
|
||||
#if USE_FAST_MEMORY
|
||||
kmp_depnode_t *node = (kmp_depnode_t *) __kmp_fast_allocate(thread,sizeof(kmp_depnode_t));
|
||||
kmp_depnode_t *node =
|
||||
(kmp_depnode_t *)__kmp_fast_allocate(thread, sizeof(kmp_depnode_t));
|
||||
#else
|
||||
kmp_depnode_t *node = (kmp_depnode_t *) __kmp_thread_malloc(thread,sizeof(kmp_depnode_t));
|
||||
kmp_depnode_t *node =
|
||||
(kmp_depnode_t *)__kmp_thread_malloc(thread, sizeof(kmp_depnode_t));
|
||||
#endif
|
||||
|
||||
__kmp_init_node(node);
|
||||
new_taskdata->td_depnode = node;
|
||||
__kmp_init_node(node);
|
||||
new_taskdata->td_depnode = node;
|
||||
|
||||
if ( __kmp_check_deps( gtid, node, new_task, current_task->td_dephash, NO_DEP_BARRIER,
|
||||
ndeps, dep_list, ndeps_noalias,noalias_dep_list ) ) {
|
||||
KA_TRACE(10, ("__kmpc_omp_task_with_deps(exit): T#%d task had blocking dependencies: "
|
||||
"loc=%p task=%p, return: TASK_CURRENT_NOT_QUEUED\n", gtid, loc_ref,
|
||||
new_taskdata ) );
|
||||
return TASK_CURRENT_NOT_QUEUED;
|
||||
}
|
||||
} else {
|
||||
KA_TRACE(10, ("__kmpc_omp_task_with_deps(exit): T#%d ignored dependencies for task (serialized)"
|
||||
"loc=%p task=%p\n", gtid, loc_ref, new_taskdata ) );
|
||||
if (__kmp_check_deps(gtid, node, new_task, current_task->td_dephash,
|
||||
NO_DEP_BARRIER, ndeps, dep_list, ndeps_noalias,
|
||||
noalias_dep_list)) {
|
||||
KA_TRACE(10, ("__kmpc_omp_task_with_deps(exit): T#%d task had blocking "
|
||||
"dependencies: "
|
||||
"loc=%p task=%p, return: TASK_CURRENT_NOT_QUEUED\n",
|
||||
gtid, loc_ref, new_taskdata));
|
||||
return TASK_CURRENT_NOT_QUEUED;
|
||||
}
|
||||
} else {
|
||||
KA_TRACE(10, ("__kmpc_omp_task_with_deps(exit): T#%d ignored dependencies "
|
||||
"for task (serialized)"
|
||||
"loc=%p task=%p\n",
|
||||
gtid, loc_ref, new_taskdata));
|
||||
}
|
||||
|
||||
KA_TRACE(10, ("__kmpc_omp_task_with_deps(exit): T#%d task had no blocking dependencies : "
|
||||
"loc=%p task=%p, transferring to __kmpc_omp_task\n", gtid, loc_ref,
|
||||
new_taskdata ) );
|
||||
KA_TRACE(10, ("__kmpc_omp_task_with_deps(exit): T#%d task had no blocking "
|
||||
"dependencies : "
|
||||
"loc=%p task=%p, transferring to __kmpc_omp_task\n",
|
||||
gtid, loc_ref, new_taskdata));
|
||||
|
||||
return __kmpc_omp_task(loc_ref,gtid,new_task);
|
||||
return __kmpc_omp_task(loc_ref, gtid, new_task);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -539,55 +573,64 @@ __kmpc_omp_task_with_deps( ident_t *loc_ref, kmp_int32 gtid, kmp_task_t * new_ta
|
||||
|
||||
Blocks the current task until all specifies dependencies have been fulfilled.
|
||||
*/
|
||||
void
|
||||
__kmpc_omp_wait_deps ( ident_t *loc_ref, kmp_int32 gtid, kmp_int32 ndeps, kmp_depend_info_t *dep_list,
|
||||
kmp_int32 ndeps_noalias, kmp_depend_info_t *noalias_dep_list )
|
||||
{
|
||||
KA_TRACE(10, ("__kmpc_omp_wait_deps(enter): T#%d loc=%p\n", gtid, loc_ref) );
|
||||
void __kmpc_omp_wait_deps(ident_t *loc_ref, kmp_int32 gtid, kmp_int32 ndeps,
|
||||
kmp_depend_info_t *dep_list, kmp_int32 ndeps_noalias,
|
||||
kmp_depend_info_t *noalias_dep_list) {
|
||||
KA_TRACE(10, ("__kmpc_omp_wait_deps(enter): T#%d loc=%p\n", gtid, loc_ref));
|
||||
|
||||
if ( ndeps == 0 && ndeps_noalias == 0 ) {
|
||||
KA_TRACE(10, ("__kmpc_omp_wait_deps(exit): T#%d has no dependencies to wait upon : loc=%p\n", gtid, loc_ref) );
|
||||
return;
|
||||
}
|
||||
if (ndeps == 0 && ndeps_noalias == 0) {
|
||||
KA_TRACE(10, ("__kmpc_omp_wait_deps(exit): T#%d has no dependencies to "
|
||||
"wait upon : loc=%p\n",
|
||||
gtid, loc_ref));
|
||||
return;
|
||||
}
|
||||
|
||||
kmp_info_t *thread = __kmp_threads[ gtid ];
|
||||
kmp_taskdata_t * current_task = thread->th.th_current_task;
|
||||
kmp_info_t *thread = __kmp_threads[gtid];
|
||||
kmp_taskdata_t *current_task = thread->th.th_current_task;
|
||||
|
||||
// We can return immediately as:
|
||||
// - dependences are not computed in serial teams (except if we have proxy tasks)
|
||||
// - if the dephash is not yet created it means we have nothing to wait for
|
||||
bool ignore = current_task->td_flags.team_serial || current_task->td_flags.tasking_ser || current_task->td_flags.final;
|
||||
// We can return immediately as:
|
||||
// - dependences are not computed in serial teams (except with proxy tasks)
|
||||
// - if the dephash is not yet created it means we have nothing to wait for
|
||||
bool ignore = current_task->td_flags.team_serial ||
|
||||
current_task->td_flags.tasking_ser ||
|
||||
current_task->td_flags.final;
|
||||
#if OMP_45_ENABLED
|
||||
ignore = ignore && thread->th.th_task_team != NULL && thread->th.th_task_team->tt.tt_found_proxy_tasks == FALSE;
|
||||
ignore = ignore && thread->th.th_task_team != NULL &&
|
||||
thread->th.th_task_team->tt.tt_found_proxy_tasks == FALSE;
|
||||
#endif
|
||||
ignore = ignore || current_task->td_dephash == NULL;
|
||||
ignore = ignore || current_task->td_dephash == NULL;
|
||||
|
||||
if ( ignore ) {
|
||||
KA_TRACE(10, ("__kmpc_omp_wait_deps(exit): T#%d has no blocking dependencies : loc=%p\n", gtid, loc_ref) );
|
||||
return;
|
||||
}
|
||||
if (ignore) {
|
||||
KA_TRACE(10, ("__kmpc_omp_wait_deps(exit): T#%d has no blocking "
|
||||
"dependencies : loc=%p\n",
|
||||
gtid, loc_ref));
|
||||
return;
|
||||
}
|
||||
|
||||
kmp_depnode_t node;
|
||||
__kmp_init_node(&node);
|
||||
kmp_depnode_t node;
|
||||
__kmp_init_node(&node);
|
||||
|
||||
if (!__kmp_check_deps( gtid, &node, NULL, current_task->td_dephash, DEP_BARRIER,
|
||||
ndeps, dep_list, ndeps_noalias, noalias_dep_list )) {
|
||||
KA_TRACE(10, ("__kmpc_omp_wait_deps(exit): T#%d has no blocking dependencies : loc=%p\n", gtid, loc_ref) );
|
||||
return;
|
||||
}
|
||||
if (!__kmp_check_deps(gtid, &node, NULL, current_task->td_dephash,
|
||||
DEP_BARRIER, ndeps, dep_list, ndeps_noalias,
|
||||
noalias_dep_list)) {
|
||||
KA_TRACE(10, ("__kmpc_omp_wait_deps(exit): T#%d has no blocking "
|
||||
"dependencies : loc=%p\n",
|
||||
gtid, loc_ref));
|
||||
return;
|
||||
}
|
||||
|
||||
int thread_finished = FALSE;
|
||||
kmp_flag_32 flag((volatile kmp_uint32 *)&(node.dn.npredecessors), 0U);
|
||||
while ( node.dn.npredecessors > 0 ) {
|
||||
flag.execute_tasks(thread, gtid, FALSE, &thread_finished,
|
||||
int thread_finished = FALSE;
|
||||
kmp_flag_32 flag((volatile kmp_uint32 *)&(node.dn.npredecessors), 0U);
|
||||
while (node.dn.npredecessors > 0) {
|
||||
flag.execute_tasks(thread, gtid, FALSE, &thread_finished,
|
||||
#if USE_ITT_BUILD
|
||||
NULL,
|
||||
NULL,
|
||||
#endif
|
||||
__kmp_task_stealing_constraint );
|
||||
}
|
||||
__kmp_task_stealing_constraint);
|
||||
}
|
||||
|
||||
KA_TRACE(10, ("__kmpc_omp_wait_deps(exit): T#%d finished waiting : loc=%p\n", gtid, loc_ref) );
|
||||
KA_TRACE(10, ("__kmpc_omp_wait_deps(exit): T#%d finished waiting : loc=%p\n",
|
||||
gtid, loc_ref));
|
||||
}
|
||||
|
||||
#endif /* OMP_40_ENABLED */
|
||||
|
||||
|
||||
+2801
-2326
File diff suppressed because it is too large
Load Diff
+1683
-1684
File diff suppressed because it is too large
Load Diff
+493
-506
File diff suppressed because it is too large
Load Diff
+300
-320
@@ -14,416 +14,396 @@
|
||||
|
||||
|
||||
#include "kmp.h"
|
||||
#include "kmp_wrapper_getpid.h"
|
||||
#include "kmp_str.h"
|
||||
#include <float.h>
|
||||
#include "kmp_i18n.h"
|
||||
|
||||
/* ------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------ */
|
||||
#include "kmp_str.h"
|
||||
#include "kmp_wrapper_getpid.h"
|
||||
#include <float.h>
|
||||
|
||||
static const char *unknown = "unknown";
|
||||
|
||||
#if KMP_ARCH_X86 || KMP_ARCH_X86_64
|
||||
|
||||
/* NOTE: If called before serial_initialize (i.e. from runtime_initialize), then */
|
||||
/* the debugging package has not been initialized yet, and only "0" will print */
|
||||
/* debugging output since the environment variables have not been read. */
|
||||
/* NOTE: If called before serial_initialize (i.e. from runtime_initialize), then
|
||||
the debugging package has not been initialized yet, and only "0" will print
|
||||
debugging output since the environment variables have not been read. */
|
||||
|
||||
#ifdef KMP_DEBUG
|
||||
static int trace_level = 5;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* LOG_ID_BITS = ( 1 + floor( log_2( max( log_per_phy - 1, 1 ))))
|
||||
/* LOG_ID_BITS = ( 1 + floor( log_2( max( log_per_phy - 1, 1 ))))
|
||||
* APIC_ID = (PHY_ID << LOG_ID_BITS) | LOG_ID
|
||||
* PHY_ID = APIC_ID >> LOG_ID_BITS
|
||||
*/
|
||||
int
|
||||
__kmp_get_physical_id( int log_per_phy, int apic_id )
|
||||
{
|
||||
int index_lsb, index_msb, temp;
|
||||
int __kmp_get_physical_id(int log_per_phy, int apic_id) {
|
||||
int index_lsb, index_msb, temp;
|
||||
|
||||
if (log_per_phy > 1) {
|
||||
index_lsb = 0;
|
||||
index_msb = 31;
|
||||
if (log_per_phy > 1) {
|
||||
index_lsb = 0;
|
||||
index_msb = 31;
|
||||
|
||||
temp = log_per_phy;
|
||||
while ( (temp & 1) == 0 ) {
|
||||
temp >>= 1;
|
||||
index_lsb++;
|
||||
}
|
||||
temp = log_per_phy;
|
||||
while ((temp & 1) == 0) {
|
||||
temp >>= 1;
|
||||
index_lsb++;
|
||||
}
|
||||
|
||||
temp = log_per_phy;
|
||||
while ( (temp & 0x80000000)==0 ) {
|
||||
temp <<= 1;
|
||||
index_msb--;
|
||||
}
|
||||
temp = log_per_phy;
|
||||
while ((temp & 0x80000000) == 0) {
|
||||
temp <<= 1;
|
||||
index_msb--;
|
||||
}
|
||||
|
||||
/* If >1 bits were set in log_per_phy, choose next higher power of 2 */
|
||||
if (index_lsb != index_msb) index_msb++;
|
||||
/* If >1 bits were set in log_per_phy, choose next higher power of 2 */
|
||||
if (index_lsb != index_msb)
|
||||
index_msb++;
|
||||
|
||||
return ( (int) (apic_id >> index_msb) );
|
||||
}
|
||||
return ((int)(apic_id >> index_msb));
|
||||
}
|
||||
|
||||
return apic_id;
|
||||
return apic_id;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* LOG_ID_BITS = ( 1 + floor( log_2( max( log_per_phy - 1, 1 ))))
|
||||
* APIC_ID = (PHY_ID << LOG_ID_BITS) | LOG_ID
|
||||
* LOG_ID = APIC_ID & (( 1 << LOG_ID_BITS ) - 1 )
|
||||
*/
|
||||
int
|
||||
__kmp_get_logical_id( int log_per_phy, int apic_id )
|
||||
{
|
||||
unsigned current_bit;
|
||||
int bits_seen;
|
||||
int __kmp_get_logical_id(int log_per_phy, int apic_id) {
|
||||
unsigned current_bit;
|
||||
int bits_seen;
|
||||
|
||||
if (log_per_phy <= 1) return ( 0 );
|
||||
if (log_per_phy <= 1)
|
||||
return (0);
|
||||
|
||||
bits_seen = 0;
|
||||
bits_seen = 0;
|
||||
|
||||
for (current_bit = 1; log_per_phy != 0; current_bit <<= 1) {
|
||||
if ( log_per_phy & current_bit ) {
|
||||
log_per_phy &= ~current_bit;
|
||||
bits_seen++;
|
||||
}
|
||||
}
|
||||
for (current_bit = 1; log_per_phy != 0; current_bit <<= 1) {
|
||||
if (log_per_phy & current_bit) {
|
||||
log_per_phy &= ~current_bit;
|
||||
bits_seen++;
|
||||
}
|
||||
}
|
||||
|
||||
/* If exactly 1 bit was set in log_per_phy, choose next lower power of 2 */
|
||||
if (bits_seen == 1) {
|
||||
current_bit >>= 1;
|
||||
}
|
||||
/* If exactly 1 bit was set in log_per_phy, choose next lower power of 2 */
|
||||
if (bits_seen == 1) {
|
||||
current_bit >>= 1;
|
||||
}
|
||||
|
||||
return ( (int) ((current_bit - 1) & apic_id) );
|
||||
return ((int)((current_bit - 1) & apic_id));
|
||||
}
|
||||
|
||||
static kmp_uint64 __kmp_parse_frequency( // R: Frequency in Hz.
|
||||
char const *frequency // I: Float number and unit: MHz, GHz, or TGz.
|
||||
) {
|
||||
|
||||
static
|
||||
kmp_uint64
|
||||
__kmp_parse_frequency( // R: Frequency in Hz.
|
||||
char const * frequency // I: Float number and unit: MHz, GHz, or TGz.
|
||||
) {
|
||||
double value = 0.0;
|
||||
char const *unit = NULL;
|
||||
kmp_uint64 result = 0; /* Zero is a better unknown value than all ones. */
|
||||
|
||||
double value = 0.0;
|
||||
char const * unit = NULL;
|
||||
kmp_uint64 result = 0; /* Zero is a better unknown value than all ones. */
|
||||
|
||||
if ( frequency == NULL ) {
|
||||
return result;
|
||||
}; // if
|
||||
value = strtod( frequency, (char * *) & unit ); // strtod() does not like "char const *".
|
||||
if ( 0 < value && value <= DBL_MAX ) { // Good value (not overflow, underflow, etc).
|
||||
if ( strcmp( unit, "MHz" ) == 0 ) {
|
||||
value = value * 1.0E+6;
|
||||
} else if ( strcmp( unit, "GHz" ) == 0 ) {
|
||||
value = value * 1.0E+9;
|
||||
} else if ( strcmp( unit, "THz" ) == 0 ) {
|
||||
value = value * 1.0E+12;
|
||||
} else { // Wrong unit.
|
||||
return result;
|
||||
}; // if
|
||||
result = value;
|
||||
}; // if
|
||||
if (frequency == NULL) {
|
||||
return result;
|
||||
}; // if
|
||||
value = strtod(frequency,
|
||||
CCAST(char **, &unit)); // strtod() does not like "const"
|
||||
if (0 < value &&
|
||||
value <= DBL_MAX) { // Good value (not overflow, underflow, etc).
|
||||
if (strcmp(unit, "MHz") == 0) {
|
||||
value = value * 1.0E+6;
|
||||
} else if (strcmp(unit, "GHz") == 0) {
|
||||
value = value * 1.0E+9;
|
||||
} else if (strcmp(unit, "THz") == 0) {
|
||||
value = value * 1.0E+12;
|
||||
} else { // Wrong unit.
|
||||
return result;
|
||||
}; // if
|
||||
result = value;
|
||||
}; // if
|
||||
return result;
|
||||
|
||||
}; // func __kmp_parse_cpu_frequency
|
||||
|
||||
void
|
||||
__kmp_query_cpuid( kmp_cpuinfo_t *p )
|
||||
{
|
||||
struct kmp_cpuid buf;
|
||||
int max_arg;
|
||||
int log_per_phy;
|
||||
void __kmp_query_cpuid(kmp_cpuinfo_t *p) {
|
||||
struct kmp_cpuid buf;
|
||||
int max_arg;
|
||||
int log_per_phy;
|
||||
#ifdef KMP_DEBUG
|
||||
int cflush_size;
|
||||
int cflush_size;
|
||||
#endif
|
||||
|
||||
p->initialized = 1;
|
||||
p->initialized = 1;
|
||||
|
||||
p->sse2 = 1; // Assume SSE2 by default.
|
||||
p->sse2 = 1; // Assume SSE2 by default.
|
||||
|
||||
__kmp_x86_cpuid( 0, 0, &buf );
|
||||
__kmp_x86_cpuid(0, 0, &buf);
|
||||
|
||||
KA_TRACE( trace_level, ("INFO: CPUID %d: EAX=0x%08X EBX=0x%08X ECX=0x%08X EDX=0x%08X\n",
|
||||
0, buf.eax, buf.ebx, buf.ecx, buf.edx ) );
|
||||
KA_TRACE(trace_level,
|
||||
("INFO: CPUID %d: EAX=0x%08X EBX=0x%08X ECX=0x%08X EDX=0x%08X\n", 0,
|
||||
buf.eax, buf.ebx, buf.ecx, buf.edx));
|
||||
|
||||
max_arg = buf.eax;
|
||||
max_arg = buf.eax;
|
||||
|
||||
p->apic_id = -1;
|
||||
p->apic_id = -1;
|
||||
|
||||
if (max_arg >= 1) {
|
||||
int i;
|
||||
kmp_uint32 t, data[ 4 ];
|
||||
if (max_arg >= 1) {
|
||||
int i;
|
||||
kmp_uint32 t, data[4];
|
||||
|
||||
__kmp_x86_cpuid( 1, 0, &buf );
|
||||
KA_TRACE( trace_level, ("INFO: CPUID %d: EAX=0x%08X EBX=0x%08X ECX=0x%08X EDX=0x%08X\n",
|
||||
1, buf.eax, buf.ebx, buf.ecx, buf.edx ) );
|
||||
__kmp_x86_cpuid(1, 0, &buf);
|
||||
KA_TRACE(trace_level,
|
||||
("INFO: CPUID %d: EAX=0x%08X EBX=0x%08X ECX=0x%08X EDX=0x%08X\n",
|
||||
1, buf.eax, buf.ebx, buf.ecx, buf.edx));
|
||||
|
||||
{
|
||||
#define get_value(reg,lo,mask) ( ( ( reg ) >> ( lo ) ) & ( mask ) )
|
||||
{
|
||||
#define get_value(reg, lo, mask) (((reg) >> (lo)) & (mask))
|
||||
|
||||
p->signature = buf.eax;
|
||||
p->family = get_value( buf.eax, 20, 0xff ) + get_value( buf.eax, 8, 0x0f );
|
||||
p->model = ( get_value( buf.eax, 16, 0x0f ) << 4 ) + get_value( buf.eax, 4, 0x0f );
|
||||
p->stepping = get_value( buf.eax, 0, 0x0f );
|
||||
p->signature = buf.eax;
|
||||
p->family = get_value(buf.eax, 20, 0xff) + get_value(buf.eax, 8, 0x0f);
|
||||
p->model =
|
||||
(get_value(buf.eax, 16, 0x0f) << 4) + get_value(buf.eax, 4, 0x0f);
|
||||
p->stepping = get_value(buf.eax, 0, 0x0f);
|
||||
|
||||
#undef get_value
|
||||
|
||||
KA_TRACE( trace_level, (" family = %d, model = %d, stepping = %d\n", p->family, p->model, p->stepping ) );
|
||||
}
|
||||
KA_TRACE(trace_level, (" family = %d, model = %d, stepping = %d\n",
|
||||
p->family, p->model, p->stepping));
|
||||
}
|
||||
|
||||
for ( t = buf.ebx, i = 0; i < 4; t >>= 8, ++i ) {
|
||||
data[ i ] = (t & 0xff);
|
||||
}; // for
|
||||
for (t = buf.ebx, i = 0; i < 4; t >>= 8, ++i) {
|
||||
data[i] = (t & 0xff);
|
||||
}; // for
|
||||
|
||||
p->sse2 = ( buf.edx >> 26 ) & 1;
|
||||
p->sse2 = (buf.edx >> 26) & 1;
|
||||
|
||||
#ifdef KMP_DEBUG
|
||||
|
||||
if ( (buf.edx >> 4) & 1 ) {
|
||||
/* TSC - Timestamp Counter Available */
|
||||
KA_TRACE( trace_level, (" TSC" ) );
|
||||
}
|
||||
if ( (buf.edx >> 8) & 1 ) {
|
||||
/* CX8 - CMPXCHG8B Instruction Available */
|
||||
KA_TRACE( trace_level, (" CX8" ) );
|
||||
}
|
||||
if ( (buf.edx >> 9) & 1 ) {
|
||||
/* APIC - Local APIC Present (multi-processor operation support */
|
||||
KA_TRACE( trace_level, (" APIC" ) );
|
||||
}
|
||||
if ( (buf.edx >> 15) & 1 ) {
|
||||
/* CMOV - Conditional MOVe Instruction Available */
|
||||
KA_TRACE( trace_level, (" CMOV" ) );
|
||||
}
|
||||
if ( (buf.edx >> 18) & 1 ) {
|
||||
/* PSN - Processor Serial Number Available */
|
||||
KA_TRACE( trace_level, (" PSN" ) );
|
||||
}
|
||||
if ( (buf.edx >> 19) & 1 ) {
|
||||
/* CLFULSH - Cache Flush Instruction Available */
|
||||
cflush_size = data[ 1 ] * 8; /* Bits 15-08: CLFLUSH line size = 8 (64 bytes) */
|
||||
KA_TRACE( trace_level, (" CLFLUSH(%db)", cflush_size ) );
|
||||
|
||||
}
|
||||
if ( (buf.edx >> 21) & 1 ) {
|
||||
/* DTES - Debug Trace & EMON Store */
|
||||
KA_TRACE( trace_level, (" DTES" ) );
|
||||
}
|
||||
if ( (buf.edx >> 22) & 1 ) {
|
||||
/* ACPI - ACPI Support Available */
|
||||
KA_TRACE( trace_level, (" ACPI" ) );
|
||||
}
|
||||
if ( (buf.edx >> 23) & 1 ) {
|
||||
/* MMX - Multimedia Extensions */
|
||||
KA_TRACE( trace_level, (" MMX" ) );
|
||||
}
|
||||
if ( (buf.edx >> 25) & 1 ) {
|
||||
/* SSE - SSE Instructions */
|
||||
KA_TRACE( trace_level, (" SSE" ) );
|
||||
}
|
||||
if ( (buf.edx >> 26) & 1 ) {
|
||||
/* SSE2 - SSE2 Instructions */
|
||||
KA_TRACE( trace_level, (" SSE2" ) );
|
||||
}
|
||||
if ( (buf.edx >> 27) & 1 ) {
|
||||
/* SLFSNP - Self-Snooping Cache */
|
||||
KA_TRACE( trace_level, (" SLFSNP" ) );
|
||||
}
|
||||
if ((buf.edx >> 4) & 1) {
|
||||
/* TSC - Timestamp Counter Available */
|
||||
KA_TRACE(trace_level, (" TSC"));
|
||||
}
|
||||
if ((buf.edx >> 8) & 1) {
|
||||
/* CX8 - CMPXCHG8B Instruction Available */
|
||||
KA_TRACE(trace_level, (" CX8"));
|
||||
}
|
||||
if ((buf.edx >> 9) & 1) {
|
||||
/* APIC - Local APIC Present (multi-processor operation support */
|
||||
KA_TRACE(trace_level, (" APIC"));
|
||||
}
|
||||
if ((buf.edx >> 15) & 1) {
|
||||
/* CMOV - Conditional MOVe Instruction Available */
|
||||
KA_TRACE(trace_level, (" CMOV"));
|
||||
}
|
||||
if ((buf.edx >> 18) & 1) {
|
||||
/* PSN - Processor Serial Number Available */
|
||||
KA_TRACE(trace_level, (" PSN"));
|
||||
}
|
||||
if ((buf.edx >> 19) & 1) {
|
||||
/* CLFULSH - Cache Flush Instruction Available */
|
||||
cflush_size =
|
||||
data[1] * 8; /* Bits 15-08: CLFLUSH line size = 8 (64 bytes) */
|
||||
KA_TRACE(trace_level, (" CLFLUSH(%db)", cflush_size));
|
||||
}
|
||||
if ((buf.edx >> 21) & 1) {
|
||||
/* DTES - Debug Trace & EMON Store */
|
||||
KA_TRACE(trace_level, (" DTES"));
|
||||
}
|
||||
if ((buf.edx >> 22) & 1) {
|
||||
/* ACPI - ACPI Support Available */
|
||||
KA_TRACE(trace_level, (" ACPI"));
|
||||
}
|
||||
if ((buf.edx >> 23) & 1) {
|
||||
/* MMX - Multimedia Extensions */
|
||||
KA_TRACE(trace_level, (" MMX"));
|
||||
}
|
||||
if ((buf.edx >> 25) & 1) {
|
||||
/* SSE - SSE Instructions */
|
||||
KA_TRACE(trace_level, (" SSE"));
|
||||
}
|
||||
if ((buf.edx >> 26) & 1) {
|
||||
/* SSE2 - SSE2 Instructions */
|
||||
KA_TRACE(trace_level, (" SSE2"));
|
||||
}
|
||||
if ((buf.edx >> 27) & 1) {
|
||||
/* SLFSNP - Self-Snooping Cache */
|
||||
KA_TRACE(trace_level, (" SLFSNP"));
|
||||
}
|
||||
#endif /* KMP_DEBUG */
|
||||
|
||||
if ( (buf.edx >> 28) & 1 ) {
|
||||
/* Bits 23-16: Logical Processors per Physical Processor (1 for P4) */
|
||||
log_per_phy = data[ 2 ];
|
||||
p->apic_id = data[ 3 ]; /* Bits 31-24: Processor Initial APIC ID (X) */
|
||||
KA_TRACE( trace_level, (" HT(%d TPUs)", log_per_phy ) );
|
||||
if ((buf.edx >> 28) & 1) {
|
||||
/* Bits 23-16: Logical Processors per Physical Processor (1 for P4) */
|
||||
log_per_phy = data[2];
|
||||
p->apic_id = data[3]; /* Bits 31-24: Processor Initial APIC ID (X) */
|
||||
KA_TRACE(trace_level, (" HT(%d TPUs)", log_per_phy));
|
||||
|
||||
if( log_per_phy > 1 ) {
|
||||
/* default to 1k FOR JT-enabled processors (4k on OS X*) */
|
||||
if (log_per_phy > 1) {
|
||||
/* default to 1k FOR JT-enabled processors (4k on OS X*) */
|
||||
#if KMP_OS_DARWIN
|
||||
p->cpu_stackoffset = 4 * 1024;
|
||||
p->cpu_stackoffset = 4 * 1024;
|
||||
#else
|
||||
p->cpu_stackoffset = 1 * 1024;
|
||||
p->cpu_stackoffset = 1 * 1024;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
p->physical_id = __kmp_get_physical_id( log_per_phy, p->apic_id );
|
||||
p->logical_id = __kmp_get_logical_id( log_per_phy, p->apic_id );
|
||||
}
|
||||
p->physical_id = __kmp_get_physical_id(log_per_phy, p->apic_id);
|
||||
p->logical_id = __kmp_get_logical_id(log_per_phy, p->apic_id);
|
||||
}
|
||||
#ifdef KMP_DEBUG
|
||||
if ( (buf.edx >> 29) & 1 ) {
|
||||
/* ATHROTL - Automatic Throttle Control */
|
||||
KA_TRACE( trace_level, (" ATHROTL" ) );
|
||||
}
|
||||
KA_TRACE( trace_level, (" ]\n" ) );
|
||||
if ((buf.edx >> 29) & 1) {
|
||||
/* ATHROTL - Automatic Throttle Control */
|
||||
KA_TRACE(trace_level, (" ATHROTL"));
|
||||
}
|
||||
KA_TRACE(trace_level, (" ]\n"));
|
||||
|
||||
for (i = 2; i <= max_arg; ++i) {
|
||||
__kmp_x86_cpuid( i, 0, &buf );
|
||||
KA_TRACE( trace_level,
|
||||
( "INFO: CPUID %d: EAX=0x%08X EBX=0x%08X ECX=0x%08X EDX=0x%08X\n",
|
||||
i, buf.eax, buf.ebx, buf.ecx, buf.edx ) );
|
||||
}
|
||||
for (i = 2; i <= max_arg; ++i) {
|
||||
__kmp_x86_cpuid(i, 0, &buf);
|
||||
KA_TRACE(trace_level,
|
||||
("INFO: CPUID %d: EAX=0x%08X EBX=0x%08X ECX=0x%08X EDX=0x%08X\n",
|
||||
i, buf.eax, buf.ebx, buf.ecx, buf.edx));
|
||||
}
|
||||
#endif
|
||||
#if KMP_USE_ADAPTIVE_LOCKS
|
||||
p->rtm = 0;
|
||||
if (max_arg > 7)
|
||||
{
|
||||
/* RTM bit CPUID.07:EBX, bit 11 */
|
||||
__kmp_x86_cpuid(7, 0, &buf);
|
||||
p->rtm = (buf.ebx >> 11) & 1;
|
||||
KA_TRACE( trace_level, (" RTM" ) );
|
||||
}
|
||||
#endif
|
||||
}; // if
|
||||
|
||||
{ // Parse CPU brand string for frequency, saving the string for later.
|
||||
int i;
|
||||
kmp_cpuid_t * base = (kmp_cpuid_t *)&p->name[0];
|
||||
|
||||
// Get CPU brand string.
|
||||
for ( i = 0; i < 3; ++ i ) {
|
||||
__kmp_x86_cpuid( 0x80000002 + i, 0, base+i );
|
||||
}; // for
|
||||
p->name[ sizeof(p->name) - 1 ] = 0; // Just in case. ;-)
|
||||
KA_TRACE( trace_level, ( "cpu brand string: \"%s\"\n", &p->name[0] ) );
|
||||
|
||||
// Parse frequency.
|
||||
p->frequency = __kmp_parse_frequency( strrchr( &p->name[0], ' ' ) );
|
||||
KA_TRACE( trace_level, ( "cpu frequency from brand string: %" KMP_UINT64_SPEC "\n", p->frequency ) );
|
||||
p->rtm = 0;
|
||||
if (max_arg > 7) {
|
||||
/* RTM bit CPUID.07:EBX, bit 11 */
|
||||
__kmp_x86_cpuid(7, 0, &buf);
|
||||
p->rtm = (buf.ebx >> 11) & 1;
|
||||
KA_TRACE(trace_level, (" RTM"));
|
||||
}
|
||||
#endif
|
||||
}; // if
|
||||
|
||||
{ // Parse CPU brand string for frequency, saving the string for later.
|
||||
int i;
|
||||
kmp_cpuid_t *base = (kmp_cpuid_t *)&p->name[0];
|
||||
|
||||
// Get CPU brand string.
|
||||
for (i = 0; i < 3; ++i) {
|
||||
__kmp_x86_cpuid(0x80000002 + i, 0, base + i);
|
||||
}; // for
|
||||
p->name[sizeof(p->name) - 1] = 0; // Just in case. ;-)
|
||||
KA_TRACE(trace_level, ("cpu brand string: \"%s\"\n", &p->name[0]));
|
||||
|
||||
// Parse frequency.
|
||||
p->frequency = __kmp_parse_frequency(strrchr(&p->name[0], ' '));
|
||||
KA_TRACE(trace_level,
|
||||
("cpu frequency from brand string: %" KMP_UINT64_SPEC "\n",
|
||||
p->frequency));
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
|
||||
|
||||
/* ------------------------------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------------------------------ */
|
||||
|
||||
void
|
||||
__kmp_expand_host_name( char *buffer, size_t size )
|
||||
{
|
||||
KMP_DEBUG_ASSERT(size >= sizeof(unknown));
|
||||
void __kmp_expand_host_name(char *buffer, size_t size) {
|
||||
KMP_DEBUG_ASSERT(size >= sizeof(unknown));
|
||||
#if KMP_OS_WINDOWS
|
||||
{
|
||||
DWORD s = size;
|
||||
{
|
||||
DWORD s = size;
|
||||
|
||||
if (! GetComputerNameA( buffer, & s ))
|
||||
KMP_STRCPY_S( buffer, size, unknown );
|
||||
}
|
||||
if (!GetComputerNameA(buffer, &s))
|
||||
KMP_STRCPY_S(buffer, size, unknown);
|
||||
}
|
||||
#else
|
||||
buffer[size - 2] = 0;
|
||||
if (gethostname( buffer, size ) || buffer[size - 2] != 0)
|
||||
KMP_STRCPY_S( buffer, size, unknown );
|
||||
buffer[size - 2] = 0;
|
||||
if (gethostname(buffer, size) || buffer[size - 2] != 0)
|
||||
KMP_STRCPY_S(buffer, size, unknown);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Expand the meta characters in the filename:
|
||||
*
|
||||
* Currently defined characters are:
|
||||
*
|
||||
* %H the hostname
|
||||
* %P the number of threads used.
|
||||
* %I the unique identifier for this run.
|
||||
*/
|
||||
|
||||
void
|
||||
__kmp_expand_file_name( char *result, size_t rlen, char *pattern )
|
||||
{
|
||||
char *pos = result, *end = result + rlen - 1;
|
||||
char buffer[256];
|
||||
int default_cpu_width = 1;
|
||||
int snp_result;
|
||||
void __kmp_expand_file_name(char *result, size_t rlen, char *pattern) {
|
||||
char *pos = result, *end = result + rlen - 1;
|
||||
char buffer[256];
|
||||
int default_cpu_width = 1;
|
||||
int snp_result;
|
||||
|
||||
KMP_DEBUG_ASSERT(rlen > 0);
|
||||
*end = 0;
|
||||
{
|
||||
int i;
|
||||
for(i = __kmp_xproc; i >= 10; i /= 10, ++default_cpu_width);
|
||||
KMP_DEBUG_ASSERT(rlen > 0);
|
||||
*end = 0;
|
||||
{
|
||||
int i;
|
||||
for (i = __kmp_xproc; i >= 10; i /= 10, ++default_cpu_width)
|
||||
;
|
||||
}
|
||||
|
||||
if (pattern != NULL) {
|
||||
while (*pattern != '\0' && pos < end) {
|
||||
if (*pattern != '%') {
|
||||
*pos++ = *pattern++;
|
||||
} else {
|
||||
char *old_pattern = pattern;
|
||||
int width = 1;
|
||||
int cpu_width = default_cpu_width;
|
||||
|
||||
++pattern;
|
||||
|
||||
if (*pattern >= '0' && *pattern <= '9') {
|
||||
width = 0;
|
||||
do {
|
||||
width = (width * 10) + *pattern++ - '0';
|
||||
} while (*pattern >= '0' && *pattern <= '9');
|
||||
if (width < 0 || width > 1024)
|
||||
width = 1;
|
||||
|
||||
cpu_width = width;
|
||||
}
|
||||
|
||||
switch (*pattern) {
|
||||
case 'H':
|
||||
case 'h': {
|
||||
__kmp_expand_host_name(buffer, sizeof(buffer));
|
||||
KMP_STRNCPY(pos, buffer, end - pos + 1);
|
||||
if (*end == 0) {
|
||||
while (*pos)
|
||||
++pos;
|
||||
++pattern;
|
||||
} else
|
||||
pos = end;
|
||||
} break;
|
||||
case 'P':
|
||||
case 'p': {
|
||||
snp_result = KMP_SNPRINTF(pos, end - pos + 1, "%0*d", cpu_width,
|
||||
__kmp_dflt_team_nth);
|
||||
if (snp_result >= 0 && snp_result <= end - pos) {
|
||||
while (*pos)
|
||||
++pos;
|
||||
++pattern;
|
||||
} else
|
||||
pos = end;
|
||||
} break;
|
||||
case 'I':
|
||||
case 'i': {
|
||||
pid_t id = getpid();
|
||||
snp_result = KMP_SNPRINTF(pos, end - pos + 1, "%0*d", width, id);
|
||||
if (snp_result >= 0 && snp_result <= end - pos) {
|
||||
while (*pos)
|
||||
++pos;
|
||||
++pattern;
|
||||
} else
|
||||
pos = end;
|
||||
break;
|
||||
}
|
||||
case '%': {
|
||||
*pos++ = '%';
|
||||
++pattern;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
*pos++ = '%';
|
||||
pattern = old_pattern + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* TODO: How do we get rid of this? */
|
||||
if (*pattern != '\0')
|
||||
KMP_FATAL(FileNameTooLong);
|
||||
}
|
||||
|
||||
if (pattern != NULL) {
|
||||
while (*pattern != '\0' && pos < end) {
|
||||
if (*pattern != '%') {
|
||||
*pos++ = *pattern++;
|
||||
} else {
|
||||
char *old_pattern = pattern;
|
||||
int width = 1;
|
||||
int cpu_width = default_cpu_width;
|
||||
|
||||
++pattern;
|
||||
|
||||
if (*pattern >= '0' && *pattern <= '9') {
|
||||
width = 0;
|
||||
do {
|
||||
width = (width * 10) + *pattern++ - '0';
|
||||
} while (*pattern >= '0' && *pattern <= '9');
|
||||
if (width < 0 || width > 1024)
|
||||
width = 1;
|
||||
|
||||
cpu_width = width;
|
||||
}
|
||||
|
||||
switch (*pattern) {
|
||||
case 'H':
|
||||
case 'h':
|
||||
{
|
||||
__kmp_expand_host_name( buffer, sizeof( buffer ) );
|
||||
KMP_STRNCPY( pos, buffer, end - pos + 1);
|
||||
if(*end == 0) {
|
||||
while ( *pos )
|
||||
++pos;
|
||||
++pattern;
|
||||
} else
|
||||
pos = end;
|
||||
}
|
||||
break;
|
||||
case 'P':
|
||||
case 'p':
|
||||
{
|
||||
snp_result = KMP_SNPRINTF( pos, end - pos + 1, "%0*d", cpu_width, __kmp_dflt_team_nth );
|
||||
if(snp_result >= 0 && snp_result <= end - pos) {
|
||||
while ( *pos )
|
||||
++pos;
|
||||
++pattern;
|
||||
} else
|
||||
pos = end;
|
||||
}
|
||||
break;
|
||||
case 'I':
|
||||
case 'i':
|
||||
{
|
||||
pid_t id = getpid();
|
||||
snp_result = KMP_SNPRINTF( pos, end - pos + 1, "%0*d", width, id );
|
||||
if(snp_result >= 0 && snp_result <= end - pos) {
|
||||
while ( *pos )
|
||||
++pos;
|
||||
++pattern;
|
||||
} else
|
||||
pos = end;
|
||||
break;
|
||||
}
|
||||
case '%':
|
||||
{
|
||||
*pos++ = '%';
|
||||
++pattern;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
*pos++ = '%';
|
||||
pattern = old_pattern + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* TODO: How do we get rid of this? */
|
||||
if(*pattern != '\0')
|
||||
KMP_FATAL( FileNameTooLong );
|
||||
}
|
||||
|
||||
*pos = '\0';
|
||||
*pos = '\0';
|
||||
}
|
||||
|
||||
|
||||
+145
-151
@@ -18,197 +18,191 @@
|
||||
#include "kmp_version.h"
|
||||
|
||||
// Replace with snapshot date YYYYMMDD for promotion build.
|
||||
#define KMP_VERSION_BUILD 20140926
|
||||
#define KMP_VERSION_BUILD 20140926
|
||||
|
||||
// Helper macros to convert value of macro to string literal.
|
||||
#define _stringer( x ) #x
|
||||
#define stringer( x ) _stringer( x )
|
||||
#define _stringer(x) #x
|
||||
#define stringer(x) _stringer(x)
|
||||
|
||||
// Detect compiler.
|
||||
#if KMP_COMPILER_ICC
|
||||
#if __INTEL_COMPILER == 1010
|
||||
#define KMP_COMPILER "Intel C++ Compiler 10.1"
|
||||
#elif __INTEL_COMPILER == 1100
|
||||
#define KMP_COMPILER "Intel C++ Compiler 11.0"
|
||||
#elif __INTEL_COMPILER == 1110
|
||||
#define KMP_COMPILER "Intel C++ Compiler 11.1"
|
||||
#elif __INTEL_COMPILER == 1200
|
||||
#define KMP_COMPILER "Intel C++ Compiler 12.0"
|
||||
#elif __INTEL_COMPILER == 1210
|
||||
#define KMP_COMPILER "Intel C++ Compiler 12.1"
|
||||
#elif __INTEL_COMPILER == 1300
|
||||
#define KMP_COMPILER "Intel C++ Compiler 13.0"
|
||||
#elif __INTEL_COMPILER == 1310
|
||||
#define KMP_COMPILER "Intel C++ Compiler 13.1"
|
||||
#elif __INTEL_COMPILER == 1400
|
||||
#define KMP_COMPILER "Intel C++ Compiler 14.0"
|
||||
#elif __INTEL_COMPILER == 1410
|
||||
#define KMP_COMPILER "Intel C++ Compiler 14.1"
|
||||
#elif __INTEL_COMPILER == 1500
|
||||
#define KMP_COMPILER "Intel C++ Compiler 15.0"
|
||||
#elif __INTEL_COMPILER == 1600
|
||||
#define KMP_COMPILER "Intel C++ Compiler 16.0"
|
||||
#elif __INTEL_COMPILER == 1700
|
||||
#define KMP_COMPILER "Intel C++ Compiler 17.0"
|
||||
#elif __INTEL_COMPILER == 9998
|
||||
#define KMP_COMPILER "Intel C++ Compiler mainline"
|
||||
#elif __INTEL_COMPILER == 9999
|
||||
#define KMP_COMPILER "Intel C++ Compiler mainline"
|
||||
#endif
|
||||
#if __INTEL_COMPILER == 1010
|
||||
#define KMP_COMPILER "Intel C++ Compiler 10.1"
|
||||
#elif __INTEL_COMPILER == 1100
|
||||
#define KMP_COMPILER "Intel C++ Compiler 11.0"
|
||||
#elif __INTEL_COMPILER == 1110
|
||||
#define KMP_COMPILER "Intel C++ Compiler 11.1"
|
||||
#elif __INTEL_COMPILER == 1200
|
||||
#define KMP_COMPILER "Intel C++ Compiler 12.0"
|
||||
#elif __INTEL_COMPILER == 1210
|
||||
#define KMP_COMPILER "Intel C++ Compiler 12.1"
|
||||
#elif __INTEL_COMPILER == 1300
|
||||
#define KMP_COMPILER "Intel C++ Compiler 13.0"
|
||||
#elif __INTEL_COMPILER == 1310
|
||||
#define KMP_COMPILER "Intel C++ Compiler 13.1"
|
||||
#elif __INTEL_COMPILER == 1400
|
||||
#define KMP_COMPILER "Intel C++ Compiler 14.0"
|
||||
#elif __INTEL_COMPILER == 1410
|
||||
#define KMP_COMPILER "Intel C++ Compiler 14.1"
|
||||
#elif __INTEL_COMPILER == 1500
|
||||
#define KMP_COMPILER "Intel C++ Compiler 15.0"
|
||||
#elif __INTEL_COMPILER == 1600
|
||||
#define KMP_COMPILER "Intel C++ Compiler 16.0"
|
||||
#elif __INTEL_COMPILER == 1700
|
||||
#define KMP_COMPILER "Intel C++ Compiler 17.0"
|
||||
#elif __INTEL_COMPILER == 9998
|
||||
#define KMP_COMPILER "Intel C++ Compiler mainline"
|
||||
#elif __INTEL_COMPILER == 9999
|
||||
#define KMP_COMPILER "Intel C++ Compiler mainline"
|
||||
#endif
|
||||
#elif KMP_COMPILER_CLANG
|
||||
#define KMP_COMPILER "Clang " stringer( __clang_major__ ) "." stringer( __clang_minor__ )
|
||||
#define KMP_COMPILER \
|
||||
"Clang " stringer(__clang_major__) "." stringer(__clang_minor__)
|
||||
#elif KMP_COMPILER_GCC
|
||||
#define KMP_COMPILER "GCC " stringer( __GNUC__ ) "." stringer( __GNUC_MINOR__ )
|
||||
#define KMP_COMPILER "GCC " stringer(__GNUC__) "." stringer(__GNUC_MINOR__)
|
||||
#elif KMP_COMPILER_MSVC
|
||||
#define KMP_COMPILER "MSVC " stringer( _MSC_FULL_VER )
|
||||
#define KMP_COMPILER "MSVC " stringer(_MSC_FULL_VER)
|
||||
#endif
|
||||
#ifndef KMP_COMPILER
|
||||
#warning "Unknown compiler"
|
||||
#define KMP_COMPILER "unknown compiler"
|
||||
#warning "Unknown compiler"
|
||||
#define KMP_COMPILER "unknown compiler"
|
||||
#endif
|
||||
|
||||
// Detect librray type (perf, stub).
|
||||
#ifdef KMP_STUB
|
||||
#define KMP_LIB_TYPE "stub"
|
||||
#define KMP_LIB_TYPE "stub"
|
||||
#else
|
||||
#define KMP_LIB_TYPE "performance"
|
||||
#define KMP_LIB_TYPE "performance"
|
||||
#endif // KMP_LIB_TYPE
|
||||
|
||||
// Detect link type (static, dynamic).
|
||||
#ifdef KMP_DYNAMIC_LIB
|
||||
#define KMP_LINK_TYPE "dynamic"
|
||||
#define KMP_LINK_TYPE "dynamic"
|
||||
#else
|
||||
#define KMP_LINK_TYPE "static"
|
||||
#define KMP_LINK_TYPE "static"
|
||||
#endif // KMP_LINK_TYPE
|
||||
|
||||
// Finally, define strings.
|
||||
#define KMP_LIBRARY KMP_LIB_TYPE " library (" KMP_LINK_TYPE ")"
|
||||
#define KMP_LIBRARY KMP_LIB_TYPE " library (" KMP_LINK_TYPE ")"
|
||||
#define KMP_COPYRIGHT ""
|
||||
|
||||
int const __kmp_version_major = KMP_VERSION_MAJOR;
|
||||
int const __kmp_version_minor = KMP_VERSION_MINOR;
|
||||
int const __kmp_version_build = KMP_VERSION_BUILD;
|
||||
int const __kmp_openmp_version =
|
||||
#if OMP_45_ENABLED
|
||||
201511;
|
||||
#elif OMP_40_ENABLED
|
||||
201307;
|
||||
#else
|
||||
201107;
|
||||
#endif
|
||||
|
||||
/* Do NOT change the format of this string! Intel(R) Thread Profiler checks for a
|
||||
specific format some changes in the recognition routine there need to
|
||||
be made before this is changed.
|
||||
*/
|
||||
char const __kmp_copyright[] =
|
||||
KMP_VERSION_PREFIX KMP_LIBRARY
|
||||
" ver. " stringer( KMP_VERSION_MAJOR ) "." stringer( KMP_VERSION_MINOR )
|
||||
"." stringer( KMP_VERSION_BUILD ) " "
|
||||
KMP_COPYRIGHT;
|
||||
|
||||
char const __kmp_version_copyright[] = KMP_VERSION_PREFIX KMP_COPYRIGHT;
|
||||
char const __kmp_version_lib_ver[] = KMP_VERSION_PREFIX "version: " stringer( KMP_VERSION_MAJOR ) "." stringer( KMP_VERSION_MINOR ) "." stringer( KMP_VERSION_BUILD );
|
||||
char const __kmp_version_lib_type[] = KMP_VERSION_PREFIX "library type: " KMP_LIB_TYPE;
|
||||
char const __kmp_version_link_type[] = KMP_VERSION_PREFIX "link type: " KMP_LINK_TYPE;
|
||||
char const __kmp_version_build_time[] = KMP_VERSION_PREFIX "build time: " "no_timestamp";
|
||||
#if KMP_MIC2
|
||||
char const __kmp_version_target_env[] = KMP_VERSION_PREFIX "target environment: MIC2";
|
||||
#if OMP_50_ENABLED
|
||||
201611;
|
||||
#elif OMP_45_ENABLED
|
||||
201511;
|
||||
#elif OMP_40_ENABLED
|
||||
201307;
|
||||
#else
|
||||
201107;
|
||||
#endif
|
||||
char const __kmp_version_build_compiler[] = KMP_VERSION_PREFIX "build compiler: " KMP_COMPILER;
|
||||
|
||||
//
|
||||
/* Do NOT change the format of this string! Intel(R) Thread Profiler checks for
|
||||
a specific format some changes in the recognition routine there need to be
|
||||
made before this is changed. */
|
||||
char const __kmp_copyright[] = KMP_VERSION_PREFIX KMP_LIBRARY
|
||||
" ver. " stringer(KMP_VERSION_MAJOR) "." stringer(
|
||||
KMP_VERSION_MINOR) "." stringer(KMP_VERSION_BUILD) " " KMP_COPYRIGHT;
|
||||
|
||||
char const __kmp_version_copyright[] = KMP_VERSION_PREFIX KMP_COPYRIGHT;
|
||||
char const __kmp_version_lib_ver[] =
|
||||
KMP_VERSION_PREFIX "version: " stringer(KMP_VERSION_MAJOR) "." stringer(
|
||||
KMP_VERSION_MINOR) "." stringer(KMP_VERSION_BUILD);
|
||||
char const __kmp_version_lib_type[] =
|
||||
KMP_VERSION_PREFIX "library type: " KMP_LIB_TYPE;
|
||||
char const __kmp_version_link_type[] =
|
||||
KMP_VERSION_PREFIX "link type: " KMP_LINK_TYPE;
|
||||
char const __kmp_version_build_time[] = KMP_VERSION_PREFIX "build time: "
|
||||
"no_timestamp";
|
||||
#if KMP_MIC2
|
||||
char const __kmp_version_target_env[] =
|
||||
KMP_VERSION_PREFIX "target environment: MIC2";
|
||||
#endif
|
||||
char const __kmp_version_build_compiler[] =
|
||||
KMP_VERSION_PREFIX "build compiler: " KMP_COMPILER;
|
||||
|
||||
// Called at serial initialization time.
|
||||
//
|
||||
static int __kmp_version_1_printed = FALSE;
|
||||
|
||||
void
|
||||
__kmp_print_version_1( void )
|
||||
{
|
||||
if ( __kmp_version_1_printed ) {
|
||||
return;
|
||||
}; // if
|
||||
__kmp_version_1_printed = TRUE;
|
||||
void __kmp_print_version_1(void) {
|
||||
if (__kmp_version_1_printed) {
|
||||
return;
|
||||
}; // if
|
||||
__kmp_version_1_printed = TRUE;
|
||||
|
||||
#ifndef KMP_STUB
|
||||
kmp_str_buf_t buffer;
|
||||
__kmp_str_buf_init( & buffer );
|
||||
// Print version strings skipping initial magic.
|
||||
__kmp_str_buf_print( & buffer, "%s\n", & __kmp_version_lib_ver[ KMP_VERSION_MAGIC_LEN ] );
|
||||
__kmp_str_buf_print( & buffer, "%s\n", & __kmp_version_lib_type[ KMP_VERSION_MAGIC_LEN ] );
|
||||
__kmp_str_buf_print( & buffer, "%s\n", & __kmp_version_link_type[ KMP_VERSION_MAGIC_LEN ] );
|
||||
__kmp_str_buf_print( & buffer, "%s\n", & __kmp_version_build_time[ KMP_VERSION_MAGIC_LEN ] );
|
||||
#if KMP_MIC
|
||||
__kmp_str_buf_print( & buffer, "%s\n", & __kmp_version_target_env[ KMP_VERSION_MAGIC_LEN ] );
|
||||
#endif
|
||||
__kmp_str_buf_print( & buffer, "%s\n", & __kmp_version_build_compiler[ KMP_VERSION_MAGIC_LEN ] );
|
||||
#if defined(KMP_GOMP_COMPAT)
|
||||
__kmp_str_buf_print( & buffer, "%s\n", & __kmp_version_alt_comp[ KMP_VERSION_MAGIC_LEN ] );
|
||||
#endif /* defined(KMP_GOMP_COMPAT) */
|
||||
__kmp_str_buf_print( & buffer, "%s\n", & __kmp_version_omp_api[ KMP_VERSION_MAGIC_LEN ] );
|
||||
__kmp_str_buf_print( & buffer, "%sdynamic error checking: %s\n", KMP_VERSION_PREF_STR, ( __kmp_env_consistency_check ? "yes" : "no" ) );
|
||||
#ifdef KMP_DEBUG
|
||||
for ( int i = bs_plain_barrier; i < bs_last_barrier; ++ i ) {
|
||||
__kmp_str_buf_print(
|
||||
& buffer,
|
||||
"%s%s barrier branch bits: gather=%u, release=%u\n",
|
||||
KMP_VERSION_PREF_STR,
|
||||
__kmp_barrier_type_name[ i ],
|
||||
__kmp_barrier_gather_branch_bits[ i ],
|
||||
__kmp_barrier_release_branch_bits[ i ]
|
||||
); // __kmp_str_buf_print
|
||||
}; // for i
|
||||
for ( int i = bs_plain_barrier; i < bs_last_barrier; ++ i ) {
|
||||
__kmp_str_buf_print(
|
||||
& buffer,
|
||||
"%s%s barrier pattern: gather=%s, release=%s\n",
|
||||
KMP_VERSION_PREF_STR,
|
||||
__kmp_barrier_type_name[ i ],
|
||||
__kmp_barrier_pattern_name[ __kmp_barrier_gather_pattern[ i ] ],
|
||||
__kmp_barrier_pattern_name[ __kmp_barrier_release_pattern[ i ] ]
|
||||
); // __kmp_str_buf_print
|
||||
}; // for i
|
||||
__kmp_str_buf_print( & buffer, "%s\n", & __kmp_version_lock[ KMP_VERSION_MAGIC_LEN ] );
|
||||
#endif
|
||||
__kmp_str_buf_print(
|
||||
& buffer,
|
||||
"%sthread affinity support: %s\n",
|
||||
KMP_VERSION_PREF_STR,
|
||||
#if KMP_AFFINITY_SUPPORTED
|
||||
(
|
||||
KMP_AFFINITY_CAPABLE()
|
||||
?
|
||||
(
|
||||
__kmp_affinity_type == affinity_none
|
||||
?
|
||||
"not used"
|
||||
:
|
||||
"yes"
|
||||
)
|
||||
:
|
||||
"no"
|
||||
)
|
||||
#else
|
||||
"no"
|
||||
#endif
|
||||
);
|
||||
__kmp_printf( "%s", buffer.str );
|
||||
__kmp_str_buf_free( & buffer );
|
||||
K_DIAG( 1, ( "KMP_VERSION is true\n" ) );
|
||||
#endif // KMP_STUB
|
||||
#ifndef KMP_STUB
|
||||
kmp_str_buf_t buffer;
|
||||
__kmp_str_buf_init(&buffer);
|
||||
// Print version strings skipping initial magic.
|
||||
__kmp_str_buf_print(&buffer, "%s\n",
|
||||
&__kmp_version_lib_ver[KMP_VERSION_MAGIC_LEN]);
|
||||
__kmp_str_buf_print(&buffer, "%s\n",
|
||||
&__kmp_version_lib_type[KMP_VERSION_MAGIC_LEN]);
|
||||
__kmp_str_buf_print(&buffer, "%s\n",
|
||||
&__kmp_version_link_type[KMP_VERSION_MAGIC_LEN]);
|
||||
__kmp_str_buf_print(&buffer, "%s\n",
|
||||
&__kmp_version_build_time[KMP_VERSION_MAGIC_LEN]);
|
||||
#if KMP_MIC
|
||||
__kmp_str_buf_print(&buffer, "%s\n",
|
||||
&__kmp_version_target_env[KMP_VERSION_MAGIC_LEN]);
|
||||
#endif
|
||||
__kmp_str_buf_print(&buffer, "%s\n",
|
||||
&__kmp_version_build_compiler[KMP_VERSION_MAGIC_LEN]);
|
||||
#if defined(KMP_GOMP_COMPAT)
|
||||
__kmp_str_buf_print(&buffer, "%s\n",
|
||||
&__kmp_version_alt_comp[KMP_VERSION_MAGIC_LEN]);
|
||||
#endif /* defined(KMP_GOMP_COMPAT) */
|
||||
__kmp_str_buf_print(&buffer, "%s\n",
|
||||
&__kmp_version_omp_api[KMP_VERSION_MAGIC_LEN]);
|
||||
__kmp_str_buf_print(&buffer, "%sdynamic error checking: %s\n",
|
||||
KMP_VERSION_PREF_STR,
|
||||
(__kmp_env_consistency_check ? "yes" : "no"));
|
||||
#ifdef KMP_DEBUG
|
||||
for (int i = bs_plain_barrier; i < bs_last_barrier; ++i) {
|
||||
__kmp_str_buf_print(
|
||||
&buffer, "%s%s barrier branch bits: gather=%u, release=%u\n",
|
||||
KMP_VERSION_PREF_STR, __kmp_barrier_type_name[i],
|
||||
__kmp_barrier_gather_branch_bits[i],
|
||||
__kmp_barrier_release_branch_bits[i]); // __kmp_str_buf_print
|
||||
}; // for i
|
||||
for (int i = bs_plain_barrier; i < bs_last_barrier; ++i) {
|
||||
__kmp_str_buf_print(
|
||||
&buffer, "%s%s barrier pattern: gather=%s, release=%s\n",
|
||||
KMP_VERSION_PREF_STR, __kmp_barrier_type_name[i],
|
||||
__kmp_barrier_pattern_name[__kmp_barrier_gather_pattern[i]],
|
||||
__kmp_barrier_pattern_name
|
||||
[__kmp_barrier_release_pattern[i]]); // __kmp_str_buf_print
|
||||
}; // for i
|
||||
__kmp_str_buf_print(&buffer, "%s\n",
|
||||
&__kmp_version_lock[KMP_VERSION_MAGIC_LEN]);
|
||||
#endif
|
||||
__kmp_str_buf_print(
|
||||
&buffer, "%sthread affinity support: %s\n", KMP_VERSION_PREF_STR,
|
||||
#if KMP_AFFINITY_SUPPORTED
|
||||
(KMP_AFFINITY_CAPABLE()
|
||||
? (__kmp_affinity_type == affinity_none ? "not used" : "yes")
|
||||
: "no")
|
||||
#else
|
||||
"no"
|
||||
#endif
|
||||
);
|
||||
__kmp_printf("%s", buffer.str);
|
||||
__kmp_str_buf_free(&buffer);
|
||||
K_DIAG(1, ("KMP_VERSION is true\n"));
|
||||
#endif // KMP_STUB
|
||||
} // __kmp_print_version_1
|
||||
|
||||
//
|
||||
// Called at parallel initialization time.
|
||||
//
|
||||
static int __kmp_version_2_printed = FALSE;
|
||||
|
||||
void
|
||||
__kmp_print_version_2( void ) {
|
||||
if ( __kmp_version_2_printed ) {
|
||||
return;
|
||||
}; // if
|
||||
__kmp_version_2_printed = TRUE;
|
||||
void __kmp_print_version_2(void) {
|
||||
if (__kmp_version_2_printed) {
|
||||
return;
|
||||
}; // if
|
||||
__kmp_version_2_printed = TRUE;
|
||||
} // __kmp_print_version_2
|
||||
|
||||
// end of file //
|
||||
|
||||
+22
-21
@@ -17,31 +17,32 @@
|
||||
#define KMP_VERSION_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
#ifndef KMP_VERSION_MAJOR
|
||||
#error KMP_VERSION_MAJOR macro is not defined.
|
||||
#error KMP_VERSION_MAJOR macro is not defined.
|
||||
#endif
|
||||
#define KMP_VERSION_MINOR 0
|
||||
/*
|
||||
Using "magic" prefix in all the version strings is rather convenient to get static version info
|
||||
from binaries by using standard utilities "strings" and "grep", e. g.:
|
||||
#define KMP_VERSION_MINOR 0
|
||||
/* Using "magic" prefix in all the version strings is rather convenient to get
|
||||
static version info from binaries by using standard utilities "strings" and
|
||||
"grep", e. g.:
|
||||
$ strings libomp.so | grep "@(#)"
|
||||
gives clean list of all version strings in the library. Leading zero helps to keep version
|
||||
string separate from printable characters which may occurs just before version string.
|
||||
*/
|
||||
#define KMP_VERSION_MAGIC_STR "\x00@(#) "
|
||||
#define KMP_VERSION_MAGIC_LEN 6 // Length of KMP_VERSION_MAGIC_STR.
|
||||
#define KMP_VERSION_PREF_STR "Intel(R) OMP "
|
||||
#define KMP_VERSION_PREFIX KMP_VERSION_MAGIC_STR KMP_VERSION_PREF_STR
|
||||
gives clean list of all version strings in the library. Leading zero helps
|
||||
to keep version string separate from printable characters which may occurs
|
||||
just before version string. */
|
||||
#define KMP_VERSION_MAGIC_STR "\x00@(#) "
|
||||
#define KMP_VERSION_MAGIC_LEN 6 // Length of KMP_VERSION_MAGIC_STR.
|
||||
#define KMP_VERSION_PREF_STR "Intel(R) OMP "
|
||||
#define KMP_VERSION_PREFIX KMP_VERSION_MAGIC_STR KMP_VERSION_PREF_STR
|
||||
|
||||
/* declare all the version string constants for KMP_VERSION env. variable */
|
||||
extern int const __kmp_version_major;
|
||||
extern int const __kmp_version_minor;
|
||||
extern int const __kmp_version_build;
|
||||
extern int const __kmp_openmp_version;
|
||||
extern char const __kmp_copyright[]; // Old variable, kept for compatibility with ITC and ITP.
|
||||
extern int const __kmp_version_major;
|
||||
extern int const __kmp_version_minor;
|
||||
extern int const __kmp_version_build;
|
||||
extern int const __kmp_openmp_version;
|
||||
extern char const
|
||||
__kmp_copyright[]; // Old variable, kept for compatibility with ITC and ITP.
|
||||
extern char const __kmp_version_copyright[];
|
||||
extern char const __kmp_version_lib_ver[];
|
||||
extern char const __kmp_version_lib_type[];
|
||||
@@ -58,11 +59,11 @@ extern char const __kmp_version_ftnstdcall[];
|
||||
extern char const __kmp_version_ftncdecl[];
|
||||
extern char const __kmp_version_ftnextra[];
|
||||
|
||||
void __kmp_print_version_1( void );
|
||||
void __kmp_print_version_2( void );
|
||||
void __kmp_print_version_1(void);
|
||||
void __kmp_print_version_2(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif /* KMP_VERSION_H */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user