Compare commits

...
95 Commits
Author SHA1 Message Date
Tom Stellard 29b515e1e6 Merging r318848:
------------------------------------------------------------------------
r318848 | hahnfeld | 2017-11-22 09:15:20 -0800 (Wed, 22 Nov 2017) | 7 lines

Fix for OMP doacross implementation on Power

Power has a weak consistency model so we need memory barriers to
make writes (both from runtime and from user code) available for
all threads.

Differential Revision: https://reviews.llvm.org/D40175
------------------------------------------------------------------------

git-svn-id: https://llvm.org/svn/llvm-project/openmp/branches/release_50@319057 91177308-0d34-0410-b5e6-96231b3b80d8
2017-11-27 17:34:55 +00:00
Tom Stellard 4ef23db17c Merging r318658:
------------------------------------------------------------------------
r318658 | achurbanov | 2017-11-20 08:00:42 -0800 (Mon, 20 Nov 2017) | 4 lines

Fixed OMP doacross implementation on 32-bit platforms.

Differential Revision: https://reviews.llvm.org/D40171

------------------------------------------------------------------------

git-svn-id: https://llvm.org/svn/llvm-project/openmp/branches/release_50@319053 91177308-0d34-0410-b5e6-96231b3b80d8
2017-11-27 17:29:37 +00:00
Tom Stellard 37c72127e9 Merging r317115:
------------------------------------------------------------------------
r317115 | jlpeyton | 2017-11-01 12:44:42 -0700 (Wed, 01 Nov 2017) | 19 lines

[OpenMP] Fix race condition in omp_init_lock

This is a partial fix for bug 34050.

This prevents callers of omp_set_lock (which does not hold __kmp_global_lock)
from ever seeing an uninitialized version of __kmp_i_lock_table.table.

It does not solve a use-after-free race condition if omp_set_lock obtains a
pointer to __kmp_i_lock_table.table before it is updated and then attempts to
dereference afterwards. That race is far less likely and can be handled in a
separate patch.

The unit test usually segfaults on the current trunk revision. It passes with
the patch.

Patch by Adam Azarchs

Differential Revision: https://reviews.llvm.org/D39439

------------------------------------------------------------------------

git-svn-id: https://llvm.org/svn/llvm-project/openmp/branches/release_50@318178 91177308-0d34-0410-b5e6-96231b3b80d8
2017-11-14 19:21:30 +00:00
Tom Stellard 11cf126119 Merging r316452:
------------------------------------------------------------------------
r316452 | jlpeyton | 2017-10-24 09:10:09 -0700 (Tue, 24 Oct 2017) | 9 lines

Disable threadprivate data cleanup if runtime is terminating

The problem is due to the runtime's threadprivate cleanup code which tries to
access data that was already destroyed by one of the root threads.
__kmp_init_gtid is used as a checker here since it is set to false before actual
resource cleanup is done in __kmp_cleanup().

Patch by Hansang Bae

------------------------------------------------------------------------

git-svn-id: https://llvm.org/svn/llvm-project/openmp/branches/release_50@318176 91177308-0d34-0410-b5e6-96231b3b80d8
2017-11-14 19:19:10 +00:00
Tom Stellard 470366641d Merging r311269:
------------------------------------------------------------------------
r311269 | jlpeyton | 2017-08-19 16:53:36 -0700 (Sat, 19 Aug 2017) | 8 lines

Use va_copy instead of __va_copy to fix building libomp against musl libc

Fixes https://bugs.llvm.org/show_bug.cgi?id=34040

Patch by Peter Levine

Differential Revision: https://reviews.llvm.org/D36343

------------------------------------------------------------------------

git-svn-id: https://llvm.org/svn/llvm-project/openmp/branches/release_50@318175 91177308-0d34-0410-b5e6-96231b3b80d8
2017-11-14 19:16:52 +00:00
Tom Stellard 08f2b9ce14 Merging r309875:
------------------------------------------------------------------------
r309875 | jlpeyton | 2017-08-02 13:06:32 -0700 (Wed, 02 Aug 2017) | 11 lines

Move lock acquire/release functions in task deque cleanup code

The original locations can be reached without initializing the lock variable
(td_deque_lock), so it is potentially unsafe.  It is guaranteed that the lock
is initialized if the deque (td_deque) is not NULL, and lock functions can be
safely called.

Patch by Hansang Bae

Differential Revision: https://reviews.llvm.org/D36017

------------------------------------------------------------------------

git-svn-id: https://llvm.org/svn/llvm-project/openmp/branches/release_50@318171 91177308-0d34-0410-b5e6-96231b3b80d8
2017-11-14 19:11:04 +00:00
Tom Stellard 67512bb555 Merging r314513:
------------------------------------------------------------------------
r314513 | hahnfeld | 2017-09-29 06:53:03 -0700 (Fri, 29 Sep 2017) | 3 lines

[test] Fix uninitialized memory in omp_taskloop_grainsize.c

result was never initialized to zero which sometimes failed the test.
------------------------------------------------------------------------

git-svn-id: https://llvm.org/svn/llvm-project/openmp/branches/release_50@315353 91177308-0d34-0410-b5e6-96231b3b80d8
2017-10-10 19:57:45 +00:00
Hans Wennborg 6999fe680a Merging r309115:
------------------------------------------------------------------------
r309115 | hahnfeld | 2017-07-26 06:55:00 -0700 (Wed, 26 Jul 2017) | 15 lines

[CMake] Disable building libomptarget and add CMake switch

Introduce OPENMP_ENABLE_LIBOMPTARGET which defaults to OFF at the moment.

libomptarget is not yet ready for prime time:
 - Offloading to NVIDIA GPUs is not completed yet (compiler, device RTL)
 - The generic ELF plugin for offloading to the host (meant for testing)
   uses a single instance of the OpenMP runtime (libomp). That is why
   omp_is_initial_device() returns 1 which makes the tests fail.
Because of these reasons, we want to disable building (and testing!)
for release 5.0.

See https://bugs.llvm.org/show_bug.cgi?id=33859

Differential Revision: https://reviews.llvm.org/D35719
------------------------------------------------------------------------


git-svn-id: https://llvm.org/svn/llvm-project/openmp/branches/release_50@309126 91177308-0d34-0410-b5e6-96231b3b80d8
2017-07-26 15:47:03 +00:00
Hans Wennborg 1333cd34fa Creating release_50 branch off revision 308441
git-svn-id: https://llvm.org/svn/llvm-project/openmp/branches/release_50@308453 91177308-0d34-0410-b5e6-96231b3b80d8
2017-07-19 12:20:58 +00:00
Andrey Churbanov 8072ba12e0 OpenMP RTL cleanup: two PAUSEs per spin loop iteration replaced with single one
Differential Revision: https://reviews.llvm.org/D35490


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@308423 91177308-0d34-0410-b5e6-96231b3b80d8
2017-07-19 09:26:13 +00:00
Dimitry Andric 4efa4a63cf For KMP_PAGE_SIZE, use getpagesize() on Unix, GetSystemInfo() on Windows
Summary:
The kmp_os.h header is defining the `PAGE_SIZE` macro unconditionally,
even while it is only used directly after its definition, for the
Windows implementation of the `KMP_GET_PAGE_SIZE()` macro.

On at least FreeBSD, but likely all other BSDs too, this macro conflicts
with the one defined in system headers, so remove it, since nothing else
uses it.  Make all Unixes use `getpagesize()` instead, and use
`GetSystemInfo()` for the Windows case.

Reviewers: jlpeyton, jcownie, emaste, AndreyChurbanov

Reviewed By: AndreyChurbanov

Subscribers: AndreyChurbanov, hfinkel, zturner

Differential Revision: https://reviews.llvm.org/D35072


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@308355 91177308-0d34-0410-b5e6-96231b3b80d8
2017-07-18 20:31:19 +00:00
Jonathan Peyton a07d8b0a66 Fix failing taskloop tests by omitting gcc
We do not have GOMP interface support for taskloop yet.


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@308351 91177308-0d34-0410-b5e6-96231b3b80d8
2017-07-18 20:16:25 +00:00
Jonathan Peyton 92f7b797ee Add recursive task scheduling strategy to taskloop implementation
Summary:
Taskloop implementation is extended by using recursive task scheduling.
Envirable KMP_TASKLOOP_MIN_TASKS added as a manual threshold for the user
to switch from recursive to linear tasks scheduling.

Details:
* The calculations for the loop parameters are moved from __kmp_taskloop_linear
  upper level
* Initial calculation is done in the __kmpc_taskloop, further range splitting
  is done in the __kmp_taskloop_recur.
* Added threshold to switch from recursive to linear tasks scheduling;
* One half of split range is scheduled as an internal task which just moves
  sub-range parameters to the stealing thread that continues recursive
  scheduling (if number of tasks still enough), the other half is processed
  recursively;
* Internal task duplication routine fixed to assign parent task, that was not
  needed when all tasks were scheduled by same thread, but is needed now.

Patch by Andrey Churbanov

Differential Revision: https://reviews.llvm.org/D35273


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@308338 91177308-0d34-0410-b5e6-96231b3b80d8
2017-07-18 18:50:13 +00:00
Andrey Churbanov 4c2424f72c Fix sporadic segfaults in tasking tests.
Patch by Terry Wilmarth

Differential Revision: https://reviews.llvm.org/D35535


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@308298 91177308-0d34-0410-b5e6-96231b3b80d8
2017-07-18 11:56:16 +00:00
Andrey Churbanov dd87e37353 OpenMP RTL cleanup: nullify pointer after memory freeing
Differential Revision: https://reviews.llvm.org/D35497


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@308274 91177308-0d34-0410-b5e6-96231b3b80d8
2017-07-18 08:30:03 +00:00
Jonathan Peyton 3b5852c6a1 Removed "duplicates" from verbose affinity output
The internal details of this setting are not meant to be user visible and only create confusion.

Differential Revision: https://reviews.llvm.org/D35269


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@308189 91177308-0d34-0410-b5e6-96231b3b80d8
2017-07-17 17:06:43 +00:00
Andrey Churbanov b88a01f4ef OpenMP RTL cleanup: eliminated warnings with -Wcast-qual, patch 2.
Changes are: got all atomics to accept volatile pointers that allowed
to simplify many type conversions. Windows specific code fixed correspondingly.

Differential Revision: https://reviews.llvm.org/D35417


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@308164 91177308-0d34-0410-b5e6-96231b3b80d8
2017-07-17 09:03:14 +00:00
Jonas Hahnfeld 53e0c92a88 [GOMP] Fix (un)tied tasks with the GCC
The first bit is actually the "untied" flag. That is why the condition was
wrong and has to be inverted to set the flag correctly.

Found and initial patch by Simon Convent!

git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@307899 91177308-0d34-0410-b5e6-96231b3b80d8
2017-07-13 10:38:11 +00:00
Dimitry Andric 4d238bda09 Rename z_Linux_asm.s to z_Linux_asm.S
Summary:
On Unix, a .S file is normally an assembly source which must be
preprocessed with a C preprocessor, while a .s file is "plain" assembly.
The former is handled by the compiler driver (cc), the latter is
directly passed to the assembler binary (as).

Because z_Linux_asm.s is supposed to be preprocessed, rename it to .S,
so it can be automatically picked up correctly by build systems.

Reviewers: AndreyChurbanov, emaste, jlpeyton

Reviewed By: AndreyChurbanov

Subscribers: mgorny, openmp-commits

Differential Revision: https://reviews.llvm.org/D35171

git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@307680 91177308-0d34-0410-b5e6-96231b3b80d8
2017-07-11 18:04:56 +00:00
Dimitry Andric 0a8f95d15f Add a .arcconfig file for openmp.
git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@307474 91177308-0d34-0410-b5e6-96231b3b80d8
2017-07-08 16:09:47 +00:00
Ed Maste 06426cf363 remove deprecated register storage class specifier
While importing libomp into the FreeBSD base system we encountered
Clang warnings that "'register' storage class specifier is deprecated
and incompatible with C++1z [-Wdeprecated-register]".

Differential Revision:	https://reviews.llvm.org/D35124


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@307441 91177308-0d34-0410-b5e6-96231b3b80d8
2017-07-07 21:06:05 +00:00
Ed Maste 597a305494 remove duplicate symbol version script entries
GNU ld ignores duplicates, but lld produces a warning.

Differential Revision:	https://reviews.llvm.org/D35121


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@307399 91177308-0d34-0410-b5e6-96231b3b80d8
2017-07-07 13:45:41 +00:00
Jonathan Peyton 3c37ab915c Fix wrong website in messages
Address user message bug where the messages were sending users to Intel's
website instead of the LLVM OpenMP runtime websites.

Bugzilla: https://bugs.llvm.org/show_bug.cgi?id=32892

Differential Revision: https://reviews.llvm.org/D35018


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@307206 91177308-0d34-0410-b5e6-96231b3b80d8
2017-07-05 22:01:05 +00:00
Andrey Churbanov 1c31fdada0 OpenMP RTL cleanup: eliminated warnings with -Wcast-qual.
Changes are: replaced C-style casts with cons_cast and reinterpret_cast;
type of several counters changed to signed; type of parameters of 32-bit and
64-bit AND and OR intrinsics changes to unsigned; changed files formatted
using clang-format version 3.8.1.

Differential Revision: https://reviews.llvm.org/D34759


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@307020 91177308-0d34-0410-b5e6-96231b3b80d8
2017-07-03 11:24:08 +00:00
Hal Finkel 5e8afb8077 Make test/parallel/omp_nested.c not use so many threads
I've found it very difficult to get test/parallel/omp_nested.c to pass
consistently across my build environments. The problem is that it creates N^2
threads (it is testing nested parallel regions), and that often exceeds the
thread limits on systems with many cores. We do raise the process limits in
lit, and that often helps, but if running lit with a smaller number of threads
or on a system where we're otherwise resource constrained, this particular test
tends to fail (because the runtime cannot create a sufficient number of
threads).

This seems to work: if the maximum number of threads is more than some small
number, then cap the number of threads used for the parallel region. The choice
of 4 here is somewhat arbitrary.

Differential Revision: https://reviews.llvm.org/D32033

git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@306357 91177308-0d34-0410-b5e6-96231b3b80d8
2017-06-27 03:04:25 +00:00
Dimitry Andric 6943fc62c3 Only use libdl when it is available
Summary: On BSDs, there is no `libdl.so`, and functions like `dlopen`
are implemented in the main C library instead.  Use the `CMAKE_DL_LIBS`
variable instead of hardcoding a dependency on the `dl` library.

Reviewers: grokos, joerg, emaste

Reviewed By: emaste

Subscribers: jlpeyton, mgorny, openmp-commits

Differential Revision: https://reviews.llvm.org/D34632


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@306319 91177308-0d34-0410-b5e6-96231b3b80d8
2017-06-26 19:16:49 +00:00
Jonathan Peyton 862483e622 Set affinity to none/false in child processes
Reset affinity to none (false for proc-bind-var) so that threads in the child
processes are not bound tightly, unless the user explicitly sets this in
KMP_AFFINITY/OMP_PROC_BIND, in child processes. This can improve
performance for scripting languages which fork for parallelism like Python's
multiprocessing module.

Differential Revision: https://reviews.llvm.org/D34154


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@305513 91177308-0d34-0410-b5e6-96231b3b80d8
2017-06-15 21:51:07 +00:00
Jonathan Peyton 8924d7386a Replace platform macro with KMP_MIC_SUPPORTED
Differential Revision: https://reviews.llvm.org/D34119


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@305307 91177308-0d34-0410-b5e6-96231b3b80d8
2017-06-13 17:17:26 +00:00
Jonathan Peyton a8b80af9fc Reset initial affinity in children processes
If OpenMP is initialized before fork()-ing occurs and affinity is set to
something like compact, then the master thread will be pinned to a single HW
thread/core after initialization. If the master (or any other thread) then
forks N processes, all N processes will then be pinned to that same single HW
thread/core. To reset the affinity for the new child process, the atfork
handler for the child process can call kmp_set_thread_affinity_mask_initial()
to reset its affinity to the initial affinity of the application before it
re-initializes libomp. The parent process will not be affected and still
keeps its affinity setting.

Differential Revision: https://reviews.llvm.org/D34118


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@305306 91177308-0d34-0410-b5e6-96231b3b80d8
2017-06-13 17:16:12 +00:00
Samuel Antao 4bdc9afa72 [OpenMP] Prevent unused-variable warning in libomptarget when compiling in Release mode.
git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@305090 91177308-0d34-0410-b5e6-96231b3b80d8
2017-06-09 16:46:07 +00:00
Jonathan Peyton 84e84f8bb4 Fix static initializers for locks.
Fix static initializers to use the proper unlocked value for the poll
field of the tas and futex locks.

Patch by Terry Wilmarth

Differential Revision: https://reviews.llvm.org/D33794


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@304828 91177308-0d34-0410-b5e6-96231b3b80d8
2017-06-06 20:24:41 +00:00
Andrey Churbanov 2b5580f57b OpenMP 4.5: implemented support of schedule(simd:guided) and
schedule(simd:runtime) - library part. Compiler generation should use newly
introduced scheduling kinds kmp_sch_guided_simd = 46, kmp_sch_runtime_simd = 47,
as parameters to __kmpc_dispatch_init_* entries.

Differential Revision: https://reviews.llvm.org/D31602


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@304724 91177308-0d34-0410-b5e6-96231b3b80d8
2017-06-05 17:17:33 +00:00
George Rokos d2cb509fa4 [OpenMP] libomptarget: eliminate compiler warnings at build
Thanks to Sergey Dmitriev for submitting the patch.

Differential Revision: https://reviews.llvm.org/D33851



git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@304601 91177308-0d34-0410-b5e6-96231b3b80d8
2017-06-02 22:41:35 +00:00
Andrey Churbanov 20fe9e7270 Re-enable assertion after the problem that caused it to be hit had been fixed
Differential Revision: https://reviews.llvm.org/D31421


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@304443 91177308-0d34-0410-b5e6-96231b3b80d8
2017-06-01 18:10:45 +00:00
Jonathan Peyton fcec73a508 Fix minor formatting issues
Some code was restructured to move it under KMP_DEBUG.  The rest is
formatting changes to fix some things broken by clang-format

Patch by Terry Wilmarth

Differential Revision: https://reviews.llvm.org/D33744


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@304438 91177308-0d34-0410-b5e6-96231b3b80d8
2017-06-01 16:46:36 +00:00
Jonathan Peyton e60f480d75 Fix for KMP_AFFINITY=disabled and KMP_TOPOLOGY_METHOD=hwloc
With these settings, the create_hwloc_map() method was being called causing an
assert(). After some consideration, it was determined that disabling affinity
explicitly should just disable hwloc as well. i.e., KMP_AFFINITY overrides
KMP_TOPOLOGY_METHOD. This lets the user know that the Hwloc mechanism is being
ignored when KMP_AFFINITY=disabled.

Differential Revision: https://reviews.llvm.org/D33208


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@304344 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-31 20:35:22 +00:00
Jonathan Peyton 50a02e790e Address default pinning OpenMP process with multiple processor groups
This change checks if the initial affinity mask is equal to exactly one
Windows processor group's affinity mask. If it is, then the code does not
respect the initial affinity mask and uses the entire machine instead.
The reasoning behind this is that, by default, Windows assigns exactly one
processor group as the initial affinity mask even when there are multiple
Windows processor groups available. User's typically want to use the whole
machine, so we ignore this special case and use the entire machine.

If the initial affinity mask is a proper subset of one group, or spans multiple
groups, then the initial affinity mask is respected since we can assume that the
operating system did not assign this initial affinity mask. This change only
affects machines with multiple processor groups

Differential Revision: https://reviews.llvm.org/D33210


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@304343 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-31 20:33:56 +00:00
Jonathan Peyton e4c0f2b8d3 Fix for KMP_AFFINITY=respect with multiple processor groups
An assert() was being tripped when KMP_AFFINITY=respect + Multiple Processor
Groups. Let __kmp_affinity_create_proc_group_map() function be able to create
address2os object which contains a single group by deleting restriction that
process affinity mask must span multiple groups.


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@303101 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-15 19:05:59 +00:00
Jonathan Peyton c2f4638c23 Remove some outdated comments
git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@303086 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-15 17:39:16 +00:00
Jonathan Peyton ac4f9700a7 Add the .clang-format file which the formatting was based on
git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@303079 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-15 16:39:42 +00:00
Jonathan Peyton e703e783e7 Clang-format and whitespace cleanup of source code
This patch contains the clang-format and cleanup of the entire code base. Some
of clang-formats changes made the code look worse in places. A best effort was
made to resolve the bulk of these problems, but many remain. Most of the
problems were mangling line-breaks and tabbing of comments.

Patch by Terry Wilmarth

Differential Revision: https://reviews.llvm.org/D32659


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@302929 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-12 18:01:32 +00:00
George Rokos 07c5582c3b [OpenMP] Changes in the plugin interface
This patch chagnes the plugin interface so that:
1) future plugins can take advantage of systems with shared CPU/device storage
2) instead of using base addresses, target regions are launched by providing target addresseds and base offsets explicitly.

Differential revision: https://reviews.llvm.org/D33028
 


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@302663 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-10 14:12:36 +00:00
George Rokos 1a189314bd [OpenMP] libomptarget: test correction for use with OpenMP 4.5
Differential Revision: https://reviews.llvm.org/D32562

Thanks to Sergey Dmitriev for submitting the patch.



git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@301577 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-27 18:54:00 +00:00
Jonathan Peyton 81a7c91728 Fix Hwloc API Incompatibility
Older Hwloc libraries (< 1.10.0) don't offer the HWLOC_OBJ_NUMANODE nor
HWLOC_OBJ_PACKAGE types. Instead they are named HWLOC_OBJ_NODE and
HWLOC_OBJ_SOCKET instead. This patch just defines the newer names based on
the older names when using an older Hwloc.

Differential Revision: https://reviews.llvm.org/D32496


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@301349 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-25 19:04:07 +00:00
George Rokos 23f1ee8d87 [OpenMP] Optimized default kernel launch parameters in CUDA plugin
Differential Revision: https://reviews.llvm.org/D32321



git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@301321 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-25 16:34:13 +00:00
George Rokos 079ec52a07 [OpenMP] Add missing parenthesis which triggers a compile error
Differential Revision: https://reviews.llvm.org/D32490



git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@301318 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-25 15:55:39 +00:00
George Rokos 1eb73292d2 [OpenMP] libomptarget: Set ref count for global objects to positive infinity
Differential Revision: https://reviews.llvm.org/D32326



git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@301076 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-22 11:45:03 +00:00
George Rokos 305e440c56 [OpenMP] libomptarget: Remove obsolete negative device IDs -2/-3
Differential Revision: https://reviews.llvm.org/D32325



git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@301075 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-22 11:21:54 +00:00
George Rokos f07924fd3f [OpenMP] Run libomptarget regression tests using all available system threads.
Differential Revision: https://reviews.llvm.org/D32327



git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@301074 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-22 11:20:20 +00:00
Andrey Churbanov ef71bbcce4 Fix crash in invoking microtask on ios arm64.
Patch by Ni Hui.

Differential Revision: https://reviews.llvm.org/D31923


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@300448 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-17 11:58:20 +00:00
Andrey Churbanov 9a49cce023 KMP_HW_SUBSET extended with NUMA support when HWLOC enabled
Differential Revision: https://reviews.llvm.org/D31600


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@300220 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-13 17:15:07 +00:00
Olga Malysheva fa50db79c4 Test cancellation_for_sections.c expectedly fails on GCC
git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@299437 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-04 14:39:52 +00:00
Olga Malysheva b8b75f9476 Reset cancellation status for 'parallel', 'sections' and 'for' constracts.
Without this fix cancellation status for parallel, sections and for persists 
across construct boundaries.

Differential Revision: https://reviews.llvm.org/D31419

git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@299434 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-04 13:56:50 +00:00
Olga Malysheva c75321c16f Test check-in, comment changed
git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@299428 91177308-0d34-0410-b5e6-96231b3b80d8
2017-04-04 12:56:55 +00:00
Andrey Churbanov e3e3d228fe Fix for bug https://llvm.org/bugs/show_bug.cgi?id=32456
ITT Notify disabled for static build of OpenMP RTL.

Differential Revision: https://reviews.llvm.org/D31466


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@299230 91177308-0d34-0410-b5e6-96231b3b80d8
2017-03-31 16:20:07 +00:00
Andrey Churbanov ea09034b77 Fix for bug https://llvm.org/bugs/show_bug.cgi?id=30889
Condition adjusted for Debug assertion.

Differential Revision: https://reviews.llvm.org/D29638


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@298915 91177308-0d34-0410-b5e6-96231b3b80d8
2017-03-28 13:35:42 +00:00
Paul Osmialowski b78659393e GOMP compatibility: add missing OpenMP4.0 task deps handling code
Differential Revision: https://reviews.llvm.org/D31071

git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@298605 91177308-0d34-0410-b5e6-96231b3b80d8
2017-03-23 15:03:17 +00:00
George Rokos 3a5a5198c0 [OpenMP] CUDA plugin: More descriptive error messages
Differential Revision: https://reviews.llvm.org/D31206



git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@298527 91177308-0d34-0410-b5e6-96231b3b80d8
2017-03-22 17:36:22 +00:00
George Rokos c5cb0abc91 [OpenMP] Allow multiple weak symbols to be loaded from the fat binary
For compatibility with Fortran.

Differential Revision: https://reviews.llvm.org/D31205



git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@298516 91177308-0d34-0410-b5e6-96231b3b80d8
2017-03-22 16:43:40 +00:00
George Rokos 1c2799754b [OpenMP] CUDA plugin: add include directory for libelf
Allow the user to manually specify where libelf is installed.

Differential Revision: https://reviews.llvm.org/D31207



git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@298515 91177308-0d34-0410-b5e6-96231b3b80d8
2017-03-22 16:41:46 +00:00
George Rokos c79f0d5955 [OpenMP] libomptarget: Disable on MacOS X
Disable compilation of libomptarget on MacOS X.

Differential Revision: https://reviews.llvm.org/D31055



git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@298411 91177308-0d34-0410-b5e6-96231b3b80d8
2017-03-21 18:19:09 +00:00
Andrey Churbanov e70eb2bba4 Fixed intermittent hang on tests with "target teams if(0)" construct with no parallel inside.
Differential Revision: https://reviews.llvm.org/D29597


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@298373 91177308-0d34-0410-b5e6-96231b3b80d8
2017-03-21 13:48:52 +00:00
Andrey Churbanov 17fe17487c Stride in distribute parallel for loops with no chunk size.
Patch by George Rokos.

Differential Revision: https://reviews.llvm.org/D24486


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@298362 91177308-0d34-0410-b5e6-96231b3b80d8
2017-03-21 12:17:22 +00:00
Jonathan Peyton 6168925936 Minor improvement of KMP_YIELD_NOW() macro.
This change slightly improves performance of KMP_YIELD_NOW() macro, by using
_rdtsc() intrinsic function if possible.

Patch by Hansang Bae

Differential Revision: https://reviews.llvm.org/D31008


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@298314 91177308-0d34-0410-b5e6-96231b3b80d8
2017-03-20 22:11:31 +00:00
Jonathan Peyton d2a2afc3d4 Fix incorrect initial value of __kmp_affinity_type.
Affinity initialization code expects __kmp_affinity_type has the value
affinity_default by default, but the cleanup code does not properly set the
value back to affinity_default.  This may introduce some issues when multiple
roots are trying to initialize/uninitialize the runtime successively.

Patch by Hansang Bae

Differential Revision: https://reviews.llvm.org/D31012


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@298313 91177308-0d34-0410-b5e6-96231b3b80d8
2017-03-20 22:04:02 +00:00
Andrey Churbanov 96b04de80a Create a git ignore file for openmp runtime.
Patch by Guansong Zhang.

Differential Revision: https://reviews.llvm.org/D30784


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@297562 91177308-0d34-0410-b5e6-96231b3b80d8
2017-03-11 13:05:08 +00:00
Jonathan Peyton b61de7c64a Fix assertion failure when 'proclist' is used without 'explicit' in KMP_AFFINITY
This change fixes an assertion failure the in case KMP_AFFINITY is set with
'proclist' specified but without 'explicit'
e.g., KMP_AFFINITY=verbose,proclist=[0-31]

Patch by Olga Malysheva

Differential Revision: https://reviews.llvm.org/D30404


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@297480 91177308-0d34-0410-b5e6-96231b3b80d8
2017-03-10 17:22:47 +00:00
Dan Albert bff1acca47 Fix GNU strerror_r check for Android.
Summary:
Bionic didn't get a GNU style strerror_r until Android M. Until then
we unconditionally exposed the POSIX one. Expand the check to account
for this.

Reviewers: pirama, AndreyChurbanov, jlpeyton

Reviewed By: jlpeyton

Subscribers: openmp-commits, srhines

Differential Revision: https://reviews.llvm.org/D30056

git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@297235 91177308-0d34-0410-b5e6-96231b3b80d8
2017-03-07 22:18:05 +00:00
Jonathan Peyton d3acdf9c86 OpenMP version 5.0 added
Add build option LIBOMP_OMP_VERSION=50, 5.0 headers, and add the year/month
associated with OpenMP 5.0 in relevant source locations. Also, remove the
deprecated LIBOMP_OMP_VERSION=41 option.

Patch by Olga Malysheva

Differential Revision: https://reviews.llvm.org/D30450


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@297083 91177308-0d34-0410-b5e6-96231b3b80d8
2017-03-06 22:07:40 +00:00
Jonathan Peyton 14e93081b9 Mixed type atomic routines added to Windows DLL
Patch by Olga Malysheva

Differential Revision: https://reviews.llvm.org/D30408


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@297082 91177308-0d34-0410-b5e6-96231b3b80d8
2017-03-06 21:46:36 +00:00
Paul Osmialowski fb0f861623 Add AArch64 support.
This adds AArch64 support to recently added part of the runtime responsible for offloading to target. This piece of code allows offloading-to-self on AArch64 machines.

Differential Revision: https://reviews.llvm.org/D30644

git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@297070 91177308-0d34-0410-b5e6-96231b3b80d8
2017-03-06 21:00:07 +00:00
Jonathan Peyton c80d301009 Removing couple unnecessary architecture guards.
This section of code (__kmp_test_then_* functions) is guarded by
(KMP_ARCH_X86 || KMP_ARCH_X86_64) so it does not make sense to have other
architecture guards inside this section.  Non-x86 architectures always
use intrinsics (__sync_*)


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@296525 91177308-0d34-0410-b5e6-96231b3b80d8
2017-02-28 21:43:28 +00:00
Michal Gorny 7bd7063524 [test] Try to link -latomic to provide atomics when available
When using -rtlib=libgcc, the fallback implementation of __atomic_*
builtins is provided via libatomic (included in GCC). However, neither
GCC itself nor clang link libatomic implicitly, and it seems that GCC
upstream expects projects to link it explicitly as necessary.

Since compiler-rt provides __atomic_* builtins directly in the main
library, check if they are provided by the default libraries first.
If they are not, check if -latomic is available to provide them
and add explicit -latomic for tests in this case.

This fixes unresolved __atomic_load() references when running openmp
tests on i386 with libgcc backend.

Differential Revision: https://reviews.llvm.org/D30083

git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@296183 91177308-0d34-0410-b5e6-96231b3b80d8
2017-02-24 22:15:24 +00:00
George Rokos b2806f6cc0 [OpenMP] Missing virtual destructor in KMPAffinity
Added virtual destructor in a class containing virtual functions.

Differential Revision: https://reviews.llvm.org/D30271



git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@295896 91177308-0d34-0410-b5e6-96231b3b80d8
2017-02-22 22:50:28 +00:00
Jonathan Peyton 9c1e6c9bc1 [stats] add stats-gathering for static_steal scheduling method
Add counter to count number of static_steal for loops
Add counter for number of chunks executed per static_steal for loop
Add counter for number of chunks stolen per static_steal for loop


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@295461 91177308-0d34-0410-b5e6-96231b3b80d8
2017-02-17 17:06:16 +00:00
Andrey Churbanov 0f00053d19 Run-time library part of OpenMP 5.0 task reduction implementation.
Added test kmp_task_reduction_nest.cpp which has an example of
possible compiler codegen.

Differential Revision: https://reviews.llvm.org/D29600


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@295343 91177308-0d34-0410-b5e6-96231b3b80d8
2017-02-16 17:49:49 +00:00
Andrey Churbanov 8f2e239462 Added an option to bind initial thread at the start of application
via setting envirable KMP_INITIAL_THREAD_BIND=1.

Differential Revision: https://reviews.llvm.org/D29665


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@295339 91177308-0d34-0410-b5e6-96231b3b80d8
2017-02-16 17:08:40 +00:00
George Rokos c40fa62243 [OpenMP] libomptarget: Protect parent struct from being deallocated
Fixed bug due to which a parent struct was deallocated when one of the struct's pointers was being unmapped.

Differential Revision: https://reviews.llvm.org/D29914



git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@295231 91177308-0d34-0410-b5e6-96231b3b80d8
2017-02-15 20:45:37 +00:00
Jonathan Peyton 1aaa414753 Enable yield cycle on Linux
This change allows the runtime to turn __kmp_yield() on/off repeatedly on Linux.
This feature was removed when disabling monitor thread, but there are
applications that perform better with this feature on.

Patch by Hansang Bae

Differential Revision: https://reviews.llvm.org/D29227


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@295203 91177308-0d34-0410-b5e6-96231b3b80d8
2017-02-15 17:19:21 +00:00
Jonas Hahnfeld 4726583580 [OpenMP] New Tsan annotations to remove false positive on reduction and barriers
Added new ThreadSanitizer annotations to remove false positives with OpenMP reduction.
Cleaned up Tsan annotations header file from unused annotations.

Patch by Simone Atzeni!

Differential Revision: https://reviews.llvm.org/D29202

git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@295158 91177308-0d34-0410-b5e6-96231b3b80d8
2017-02-15 08:14:22 +00:00
Hans Wennborg f26c30f014 libomptarget: Disable on Win32
It's not supported, and currently breaks the weekly LLVM snapshot
builds.

Differential Revision: https://reviews.llvm.org/D29801

git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@294758 91177308-0d34-0410-b5e6-96231b3b80d8
2017-02-10 17:13:28 +00:00
Jonas Hahnfeld cb9c397660 [libomptarget] Align test code with runtime/
This change allows setting LIBOMPTARGET_LLVM_LIT_EXECUTABLE and
LIBOMPTARGET_FILECHECK_EXECUTABLE as full path. It also honors
OPENMP_LLVM_TOOLS_DIR which is meant as a common configuration
for both libomp and libomptarget.

Maybe this should be done in a common CMake module, but I'm no expert here.

Differential Revision: https://reviews.llvm.org/D29172

git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@294284 91177308-0d34-0410-b5e6-96231b3b80d8
2017-02-07 06:58:15 +00:00
Andrey Churbanov 273c4bfef1 Fix a race in shutdown when tasking is used.
Patch by Terry Wilmarth.

Differential Revision: https://reviews.llvm.org/D28377


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@294214 91177308-0d34-0410-b5e6-96231b3b80d8
2017-02-06 18:53:32 +00:00
George Rokos cf09abbf86 [OpenMP] Redefined macro warning in libomptarget
Fixed compilation warning in libomptarget.

Differential Revision: https://reviews.llvm.org/D29353



git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@293747 91177308-0d34-0410-b5e6-96231b3b80d8
2017-02-01 08:33:38 +00:00
George Rokos 6009b4051a [OpenMP] Initial implementation of OpenMP offloading library - libomptarget plugins.
This is the patch upstreaming the plugins part of libomptarget (CUDA, generic-elf-64).

Differential Revision: https://reviews.llvm.org/D14253



git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@293724 91177308-0d34-0410-b5e6-96231b3b80d8
2017-02-01 00:14:41 +00:00
Jonas Hahnfeld b00226fdf5 Correct wrong comment in bug_nested_proxy_task.c
The nested proxy task does not have dependencies.

git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@293472 91177308-0d34-0410-b5e6-96231b3b80d8
2017-01-30 09:51:02 +00:00
Jonas Hahnfeld bd223d612d [libomptarget] Fix Debug build with glibc < 2.18
glibc < 2.18 is C99 compliant and only provides the format macros in C++ if
__STDC_FORMAT_MACROS is defined. This change fixes the debug build for
GCC 4.8, GCC 6.2 and Clang 3.9.1 that were previously broken on my machine.

It shows no regression for libc++ >= 4.0.0 which has a fix since September:
http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20160926/171659.html

git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@293468 91177308-0d34-0410-b5e6-96231b3b80d8
2017-01-30 08:11:20 +00:00
Jonathan Peyton 7ec028b27e Cleanup: put i_maxmin members and ___kmp_size_type into traits_t
Put the duplicated i_maxmin into traits_t by adding new members max_value and
min_value. Put ___kmp_size_type into traits_t by adding member type_size.

Differential Revision: https://reviews.llvm.org/D28847


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@293316 91177308-0d34-0410-b5e6-96231b3b80d8
2017-01-27 18:09:22 +00:00
Jonathan Peyton 78b78d175a Printing OS thread id, when KMP_AFFINITY is set.
Patch by Vishakha Agrawal

Differential Revision: https://reviews.llvm.org/D28873


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@293315 91177308-0d34-0410-b5e6-96231b3b80d8
2017-01-27 18:04:33 +00:00
Jonathan Peyton c0cfee9024 Fix performance issue incurred by removing monitor thread.
When the monitor thread is used, most threads in the team directly go to
sleep if the copy of bt_intervals/bt_set is not available in the cache,
and this happens at least once per thread in the wait function, making the
overall performance slightly better.
This change tries to mimic this behavior by using the bt_intervals cache,
which simply keeps the blocktime interval in terms of the platform-dependent
ticks or nanoseconds.

Patch by Hansang Bae

Differential Revision: https://reviews.llvm.org/D28906


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@293312 91177308-0d34-0410-b5e6-96231b3b80d8
2017-01-27 17:54:31 +00:00
Jonas Hahnfeld 1dc2e70de2 [libomptarget] Fix compilation with libc++
iterator is only guaranteed to be default-constructible, without any argument.

Differential Revision: https://reviews.llvm.org/D29171

git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@293277 91177308-0d34-0410-b5e6-96231b3b80d8
2017-01-27 11:03:33 +00:00
George Rokos 7680cbb63a [OpenMP] Initial implementation of OpenMP offloading library - libomptarget.
This is the patch upstreaming the device-agnostic part of libomptarget.

Differential Revision: https://reviews.llvm.org/D14031



git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@293094 91177308-0d34-0410-b5e6-96231b3b80d8
2017-01-25 21:27:24 +00:00
Jonathan Peyton 3585ec7dbc Use C++11 static_assert() for build asserts.
git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@292350 91177308-0d34-0410-b5e6-96231b3b80d8
2017-01-18 07:49:30 +00:00
Jonathan Peyton fa45385094 Fix memory error in case of reinit using kmp_set_defaults() for lock code.
The lock tables were being reallocated if kmp_set_defaults() was called.
In the env_init code it says that the user should be able to switch between
different KMP_CONSISTENCY_CHECK values which is what this change enables.


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@292349 91177308-0d34-0410-b5e6-96231b3b80d8
2017-01-18 07:02:21 +00:00
Jonathan Peyton 0e5d1992ca Fix small memory leak regarding __kmp_nested_proc_bind
There is no corresponding free() for this expandable array.  The logic is
added in __kmp_cleanup() next to the freeing of __kmp_nested_nth.


git-svn-id: https://llvm.org/svn/llvm-project/openmp/trunk@292348 91177308-0d34-0410-b5e6-96231b3b80d8
2017-01-18 06:40:19 +00:00
137 changed files with 63459 additions and 53676 deletions
+4
View File
@@ -0,0 +1,4 @@
{
"project_id" : "openmp",
"conduit_uri" : "https://reviews.llvm.org/"
}
+42
View File
@@ -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
+18
View File
@@ -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()
+142
View File
@@ -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.
+119
View File
@@ -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)
+74
View File
@@ -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)
+28
View File
@@ -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:
*;
};
+72
View File
@@ -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()
+73
View File
@@ -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;
}
+50
View File
@@ -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)
+694
View File
@@ -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
+15
View File
@@ -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
+18
View File
@@ -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
+237
View File
@@ -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_
+92
View File
@@ -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_
+92
View File
@@ -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)
+116
View File
@@ -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))
+20
View File
@@ -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;
}
+91
View File
@@ -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
...
+2 -2
View File
@@ -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
View File
@@ -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?")
+3
View File
@@ -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()
+1 -1
View File
@@ -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
View File
@@ -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
-3
View File
@@ -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
View File
@@ -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;
}
+10 -6
View File
@@ -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, "
+198
View File
@@ -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 */
+855
View File
@@ -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
+524
View File
@@ -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
+644
View File
@@ -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
+515
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+4528 -4409
View File
File diff suppressed because it is too large Load Diff
+760 -697
View File
File diff suppressed because it is too large Load Diff
+1405 -1580
View File
File diff suppressed because it is too large Load Diff
+2300 -1786
View File
File diff suppressed because it is too large Load Diff
+1498 -878
View File
File diff suppressed because it is too large Load Diff
+1723 -1512
View File
File diff suppressed because it is too large Load Diff
+194 -194
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+86 -94
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+381 -464
View File
@@ -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 //
+29 -30
View 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
View File
@@ -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
View File
@@ -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
+11 -10
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+9 -8
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+7 -7
View File
@@ -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
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+674 -803
View File
File diff suppressed because it is too large Load Diff
+110 -119
View File
@@ -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
+7 -13
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+2997 -3390
View File
File diff suppressed because it is too large Load Diff
+717 -741
View File
File diff suppressed because it is too large Load Diff
+173 -165
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+110 -101
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+22 -23
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+4362 -4612
View File
File diff suppressed because it is too large Load Diff
+35 -18
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+580 -507
View File
File diff suppressed because it is too large Load Diff
+84 -96
View File
@@ -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();
}
+62 -56
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+71 -63
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+1683 -1684
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+300 -320
View File
@@ -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
View File
@@ -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
View File
@@ -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