Creating release candidate final for 3.5.1
git-svn-id: https://llvm.org/svn/llvm-project/openmp/tags/RELEASE_351@225679 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
This file is a partial list of people who have contributed to the LLVM/openmp
|
||||
project. If you have contributed a patch or made some other contribution to
|
||||
LLVM/openmp, please submit a patch to this file to add yourself, and it will be
|
||||
done!
|
||||
|
||||
The list is sorted by surname and formatted to allow easy grepping and
|
||||
beautification by scripts. The fields are: name (N), email (E), web-address
|
||||
(W), PGP key ID and fingerprint (P), description (D), and snail-mail address
|
||||
(S).
|
||||
|
||||
N: Carlo Bertolli
|
||||
D: IBM contributor to PowerPC support in CMake files and elsewhere.
|
||||
|
||||
N: Sunita Chandrasekaran
|
||||
D: Contributor to testsuite from OpenUH
|
||||
|
||||
N: Barbara Chapman
|
||||
D: Contributor to testsuite from OpenUH
|
||||
|
||||
N: University of Houston
|
||||
W: http://web.cs.uh.edu/~openuh/download/
|
||||
D: OpenUH test suite
|
||||
|
||||
N: Intel Corporation OpenMP runtime team
|
||||
W: http://openmprtl.org
|
||||
D: Created the runtime.
|
||||
|
||||
N: Matthias Muller
|
||||
D: Contributor to testsuite from OpenUH
|
||||
|
||||
N: Pavel Neytchev
|
||||
D: Contributor to testsuite from OpenUH
|
||||
|
||||
N: Steven Noonan
|
||||
E: steven@uplinklabs.net
|
||||
D: Patches for the ARM architecture and removal of several inconsistencies.
|
||||
|
||||
N: Alp Toker
|
||||
E: alp@nuanti.com
|
||||
D: Making build work for FreeBSD.
|
||||
|
||||
N: Cheng Wang
|
||||
D: Contributor to testsuite from OpenUH
|
||||
@@ -0,0 +1,124 @@
|
||||
==============================================================================
|
||||
|
||||
The software contained in this directory tree is dual licensed under both the
|
||||
University of Illinois "BSD-Like" license and the MIT license. As a user of
|
||||
this code you may choose to use it under either license. As a contributor,
|
||||
you agree to allow your code to be used under both. The full text of the
|
||||
relevant licenses is included below.
|
||||
|
||||
In addition, a license agreement from the copyright/patent holders of the
|
||||
software contained in this directory tree is included below.
|
||||
|
||||
==============================================================================
|
||||
|
||||
University of Illinois/NCSA
|
||||
Open Source License
|
||||
|
||||
Copyright (c) 1997-2013 Intel Corporation
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Developed by:
|
||||
OpenMP Runtime Team
|
||||
Intel Corporation
|
||||
http://www.openmprtl.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal with
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimers.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimers in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the names of Intel Corporation OpenMP Runtime Team nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this Software without specific prior written permission.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
|
||||
SOFTWARE.
|
||||
|
||||
==============================================================================
|
||||
|
||||
Copyright (c) 1997-2013 Intel Corporation
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
==============================================================================
|
||||
|
||||
Intel Corporation
|
||||
|
||||
Software Grant License Agreement ("Agreement")
|
||||
|
||||
Except for the license granted herein to you, Intel Corporation ("Intel") reserves
|
||||
all right, title, and interest in and to the Software (defined below).
|
||||
|
||||
Definition
|
||||
|
||||
"Software" means the code and documentation as well as any original work of
|
||||
authorship, including any modifications or additions to an existing work, that
|
||||
is intentionally submitted by Intel to llvm.org (http://llvm.org) ("LLVM") for
|
||||
inclusion in, or documentation of, any of the products owned or managed by LLVM
|
||||
(the "Work"). For the purposes of this definition, "submitted" means any form of
|
||||
electronic, verbal, or written communication sent to LLVM or its
|
||||
representatives, including but not limited to communication on electronic
|
||||
mailing lists, source code control systems, and issue tracking systems that are
|
||||
managed by, or on behalf of, LLVM for the purpose of discussing and improving
|
||||
the Work, but excluding communication that is conspicuously marked otherwise.
|
||||
|
||||
1. Grant of Copyright License. Subject to the terms and conditions of this
|
||||
Agreement, Intel hereby grants to you and to recipients of the Software
|
||||
distributed by LLVM a perpetual, worldwide, non-exclusive, no-charge,
|
||||
royalty-free, irrevocable copyright license to reproduce, prepare derivative
|
||||
works of, publicly display, publicly perform, sublicense, and distribute the
|
||||
Software and such derivative works.
|
||||
|
||||
2. Grant of Patent License. Subject to the terms and conditions of this
|
||||
Agreement, Intel hereby grants you and to recipients of the Software
|
||||
distributed by LLVM a perpetual, worldwide, non-exclusive, no-charge,
|
||||
royalty-free, irrevocable (except as stated in this section) patent license
|
||||
to make, have made, use, offer to sell, sell, import, and otherwise transfer
|
||||
the Work, where such license applies only to those patent claims licensable
|
||||
by Intel that are necessarily infringed by Intel's Software alone or by
|
||||
combination of the Software with the Work to which such Software was
|
||||
submitted. If any entity institutes patent litigation against Intel or any
|
||||
other entity (including a cross-claim or counterclaim in a lawsuit) alleging
|
||||
that Intel's Software, or the Work to which Intel has contributed constitutes
|
||||
direct or contributory patent infringement, then any patent licenses granted
|
||||
to that entity under this Agreement for the Software or Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
Unless required by applicable law or agreed to in writing, the software is
|
||||
provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
either express or implied, including, without limitation, any warranties or
|
||||
conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE.
|
||||
|
||||
==============================================================================
|
||||
Executable
+208
@@ -0,0 +1,208 @@
|
||||
#
|
||||
##//===----------------------------------------------------------------------===//
|
||||
#//
|
||||
#// 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.
|
||||
#//
|
||||
#//===----------------------------------------------------------------------===//
|
||||
#
|
||||
|
||||
# MAKEFILE PARAMETERS
|
||||
#
|
||||
# root_dir - path to root directory of liboffload
|
||||
# build_dir - path to build directory
|
||||
# mpss_dir - path to root directory of mpss
|
||||
# libiomp_host_dir - path to host libiomp directory (unnecessary if compiler_host is icc)
|
||||
# libiomp_target_dir - path to target libiomp directory (unnecesarry if compiler_target is icc)
|
||||
# omp_header_dir - path to omp.h (unnecessary if compiler_host and compiler_target are icc)
|
||||
# os_host - host operating system
|
||||
# os_target - target operating system
|
||||
# compiler_host - host compiler
|
||||
# compiler_target - target compiler
|
||||
# options_host - additional options for host compiler
|
||||
# options_target - additional options for target compiler
|
||||
#
|
||||
|
||||
# Directories
|
||||
root_dir?=.
|
||||
build_dir?=$(root_dir)/build
|
||||
build_host_dir=$(build_dir)/host
|
||||
build_target_dir=$(build_dir)/target
|
||||
obj_host_dir=$(build_dir)/obj_host
|
||||
obj_target_dir=$(build_dir)/obj_target
|
||||
source_dir=$(root_dir)/src
|
||||
imported_dir=$(source_dir)/imported
|
||||
|
||||
# OS
|
||||
os_host?=linux
|
||||
os_target?=linux
|
||||
ifneq ($(os_host)_$(os_target), linux_linux)
|
||||
$(error "Only linux is supported")
|
||||
endif
|
||||
|
||||
# Compilers
|
||||
compiler_host?=gcc
|
||||
compiler_target?=gcc
|
||||
|
||||
# MPSS
|
||||
mpss_dir?=/
|
||||
mpss_present=$(shell if test -d $(mpss_dir); then echo OK; else echo KO; fi)
|
||||
ifneq ($(mpss_present), OK)
|
||||
$(error "Cannot find MPSS directory $(mpss_dir)")
|
||||
endif
|
||||
|
||||
coi_dir=$(mpss_dir)/opt/intel/mic/coi
|
||||
myo_dir=$(mpss_dir)/opt/intel/mic/myo
|
||||
|
||||
# Sources
|
||||
src_liboffload_common=dv_util.cpp liboffload_error.c liboffload_msg.c offload_common.cpp offload_table.cpp offload_trace.cpp offload_util.cpp
|
||||
|
||||
src_liboffload_host=$(src_liboffload_common) cean_util.cpp coi/coi_client.cpp compiler_if_host.cpp offload_engine.cpp offload_env.cpp offload_host.cpp offload_omp_host.cpp offload_timer_host.cpp offload_orsl.cpp orsl-lite/lib/orsl-lite.c offload_myo_host.cpp
|
||||
src_liboffload_host:=$(foreach file,$(src_liboffload_host),$(source_dir)/$(file))
|
||||
|
||||
src_liboffload_target=$(src_liboffload_common) coi/coi_server.cpp compiler_if_target.cpp offload_omp_target.cpp offload_target.cpp offload_timer_target.cpp offload_myo_target.cpp
|
||||
src_liboffload_target:=$(foreach file,$(src_liboffload_target),$(source_dir)/$(file))
|
||||
|
||||
src_ofld=ofldbegin.cpp ofldend.cpp
|
||||
src_ofld:=$(foreach file,$(src_ofld),$(source_dir)/$(file))
|
||||
|
||||
headers=$(wildcard $(source_dir)/*.h) $(wildcard $(source_dir)/coi/*.h) $(wildcard $(source_dir)/orsl-lite/include/*.h)
|
||||
ifneq ($(omp_header_dir), )
|
||||
headers+=$(imported_dir)/omp.h
|
||||
endif
|
||||
|
||||
# Objects
|
||||
obj_liboffload_host=$(notdir $(src_liboffload_host))
|
||||
obj_liboffload_host:=$(obj_liboffload_host:.cpp=.o)
|
||||
obj_liboffload_host:=$(obj_liboffload_host:.c=.o)
|
||||
obj_liboffload_host:=$(foreach file,$(obj_liboffload_host),$(obj_host_dir)/$(file))
|
||||
|
||||
obj_liboffload_target=$(notdir $(src_liboffload_target))
|
||||
obj_liboffload_target:=$(obj_liboffload_target:.cpp=.o)
|
||||
obj_liboffload_target:=$(obj_liboffload_target:.c=.o)
|
||||
obj_liboffload_target:=$(foreach file,$(obj_liboffload_target),$(obj_target_dir)/$(file))
|
||||
|
||||
obj_ofld=$(notdir $(src_ofld))
|
||||
obj_ofld:=$(obj_ofld:.cpp=.o)
|
||||
obj_ofld_host=$(foreach file,$(obj_ofld),$(build_host_dir)/$(file))
|
||||
obj_ofld_target=$(foreach file,$(obj_ofld),$(build_target_dir)/$(file))
|
||||
|
||||
# Options
|
||||
opts_common=-O2 -w -fpic -c -DCOI_LIBRARY_VERSION=2 -DMYO_SUPPORT -DOFFLOAD_DEBUG=1 -DSEP_SUPPORT -DTIMING_SUPPORT -I$(coi_dir)/include -I$(myo_dir)/include -I$(source_dir)
|
||||
ifneq ($(omp_header_dir), )
|
||||
opts_common+=-I$(imported_dir)
|
||||
endif
|
||||
|
||||
opts_liboffload=-shared -Wl,-soname,liboffload.so.5 -ldl -lstdc++ -liomp5
|
||||
|
||||
opts_liboffload_host=$(opts_liboffload) -L$(coi_dir)/host-linux-release/lib -lcoi_host -L$(myo_dir)/lib -lmyo-client
|
||||
ifneq ($(libiomp_host_dir), )
|
||||
opts_liboffload_host+=-L$(libiomp_host_dir)
|
||||
endif
|
||||
|
||||
opts_liboffload_target=$(opts_liboffload) -L$(coi_dir)/device-linux-release/lib -lcoi_device -L$(myo_dir)/lib -lmyo-service
|
||||
ifneq ($(libiomp_target_dir), )
|
||||
opts_liboffload_target+=-L$(libiomp_target_dir)
|
||||
endif
|
||||
|
||||
options_host?=
|
||||
opts_host=$(options_host) -DHOST_LIBRARY=1
|
||||
ifeq ($(os_host), linux)
|
||||
opts_host+=-DLINUX
|
||||
endif
|
||||
|
||||
options_target?=
|
||||
opts_target=$(options_target) -DHOST_LIBRARY=0
|
||||
ifeq ($(os_target), linux)
|
||||
opts_target+=-DLINUX
|
||||
endif
|
||||
|
||||
# Make targets
|
||||
.PHONY: all clean info
|
||||
|
||||
all: info $(build_host_dir)/liboffload.so $(build_target_dir)/liboffload.so $(obj_ofld_host) $(obj_ofld_target)
|
||||
|
||||
|
||||
$(build_host_dir)/liboffload.so: $(build_host_dir)/liboffload.so.5 | $(build_host_dir)
|
||||
ln -f $< $@
|
||||
|
||||
$(build_host_dir)/liboffload.so.5: $(obj_liboffload_host) | $(build_host_dir)
|
||||
$(compiler_host) $(opts_liboffload_host) $(opts_host) $^ -o $@
|
||||
|
||||
$(obj_host_dir)/%.o: $(source_dir)/%.c $(headers) | $(obj_host_dir)
|
||||
$(compiler_host) $(opts_common) $(opts_host) $< -o $@
|
||||
|
||||
$(obj_host_dir)/%.o: $(source_dir)/%.cpp $(headers) | $(obj_host_dir)
|
||||
$(compiler_host) $(opts_common) $(opts_host) $< -o $@
|
||||
|
||||
$(obj_host_dir)/%.o: $(source_dir)/coi/%.cpp $(headers) | $(obj_host_dir)
|
||||
$(compiler_host) $(opts_common) $(opts_host) $< -o $@
|
||||
|
||||
$(obj_host_dir)/%.o: $(source_dir)/orsl-lite/lib/%.c $(headers) | $(obj_host_dir)
|
||||
$(compiler_host) $(opts_common) $(opts_host) $< -o $@
|
||||
|
||||
|
||||
$(build_target_dir)/liboffload.so: $(build_target_dir)/liboffload.so.5 | $(build_target_dir)
|
||||
ln -f $< $@
|
||||
|
||||
$(build_target_dir)/liboffload.so.5: $(obj_liboffload_target) | $(build_target_dir)
|
||||
$(compiler_target) $(opts_liboffload_target) $(opts_target) $^ -o $@
|
||||
|
||||
$(obj_target_dir)/%.o: $(source_dir)/%.c $(headers) | $(obj_target_dir)
|
||||
$(compiler_target) $(opts_common) $(opts_target) $< -o $@
|
||||
|
||||
$(obj_target_dir)/%.o: $(source_dir)/%.cpp $(headers) | $(obj_target_dir)
|
||||
$(compiler_target) $(opts_common) $(opts_target) $< -o $@
|
||||
|
||||
$(obj_target_dir)/%.o: $(source_dir)/coi/%.cpp $(headers) | $(obj_target_dir)
|
||||
$(compiler_target) $(opts_common) $(opts_target) $< -o $@
|
||||
|
||||
$(obj_target_dir)/%.o: $(source_dir)/orsl-lite/lib/%.c $(headers) | $(obj_target_dir)
|
||||
$(compiler_target) $(opts_common) $(opts_target) $< -o $@
|
||||
|
||||
|
||||
$(build_host_dir)/%.o: $(source_dir)/%.cpp $(headers) | $(build_host_dir)
|
||||
$(compiler_host) $(opts_common) $(opts_host) $< -o $@
|
||||
|
||||
$(build_target_dir)/%.o: $(source_dir)/%.cpp $(headers) | $(build_target_dir)
|
||||
$(compiler_target) $(opts_common) $(opts_target) $< -o $@
|
||||
|
||||
|
||||
$(imported_dir)/omp.h: $(omp_header_dir)/omp.h | $(imported_dir)
|
||||
cp $< $@
|
||||
|
||||
|
||||
$(build_host_dir) $(build_target_dir) $(obj_host_dir) $(obj_target_dir): | $(build_dir)
|
||||
$(shell mkdir -p $@ >/dev/null 2>/dev/null)
|
||||
@echo "Created $@ directory"
|
||||
|
||||
$(build_dir):
|
||||
$(shell mkdir -p $@ >/dev/null 2>/dev/null)
|
||||
@echo "Created $@ directory"
|
||||
|
||||
$(imported_dir):
|
||||
$(shell mkdir -p $@ >/dev/null 2>/dev/null)
|
||||
@echo "Created $@ directory"
|
||||
|
||||
|
||||
clean:
|
||||
$(shell rm -rf $(build_dir))
|
||||
@echo "Remove $(build_dir) directory"
|
||||
|
||||
|
||||
info:
|
||||
@echo "root_dir = $(root_dir)"
|
||||
@echo "build_dir = $(build_dir)"
|
||||
@echo "mpss_dir = $(mpss_dir)"
|
||||
@echo "libiomp_host_dir = $(libiomp_host_dir)"
|
||||
@echo "libiomp_target_dir = $(libiomp_target_dir)"
|
||||
@echo "omp_header_dir = $(omp_header_dir)"
|
||||
@echo "os_host = $(os_host)"
|
||||
@echo "os_target = $(os_target)"
|
||||
@echo "compiler_host = $(compiler_host)"
|
||||
@echo "compiler_target = $(compiler_target)"
|
||||
@echo "options_host = $(options_host)"
|
||||
@echo "options_target = $(options_target)"
|
||||
|
||||
Executable
+129
@@ -0,0 +1,129 @@
|
||||
|
||||
README for Intel(R) Offload Runtime Library
|
||||
===========================================
|
||||
|
||||
How to Build Documentation
|
||||
==========================
|
||||
|
||||
The main documentation is in Doxygen* format, and this distribution
|
||||
should come with pre-built PDF documentation in doc/Reference.pdf.
|
||||
However, an HTML version can be built by executing:
|
||||
|
||||
% doxygen doc/doxygen/config
|
||||
|
||||
in this directory.
|
||||
|
||||
That will produce HTML documentation in the doc/doxygen/generated
|
||||
directory, which can be accessed by pointing a web browser at the
|
||||
index.html file there.
|
||||
|
||||
If you don't have Doxygen installed, you can download it from
|
||||
www.doxygen.org.
|
||||
|
||||
|
||||
Software Requirements
|
||||
=====================
|
||||
|
||||
Intel(R) Offload Runtime Library requires additional software:
|
||||
|
||||
1) Intel(R) OpenMP* Runtime Library. You can either download the source
|
||||
code for that (from openmprtl.org or openmp.llvm.org) or simply use the
|
||||
compiled version distributed with the Intel compilers.
|
||||
2) Intel(R) COI Runtime Library and Intel(R) MYO Runtime Library. These
|
||||
libraries are part of Intel(R) Manycore Platform Software Stack (MPSS). You
|
||||
can download MPSS source code or binaries from
|
||||
software.intel.com/en-us/articles/intel-manycore-platform-software-stack-mpss.
|
||||
Binaries include host libraries for Intel(R) 64 Architecture and target
|
||||
libraries for Intel(R) Many Integrated Core Architecture.
|
||||
|
||||
Also you will require all of the libraries that enable the target code to run
|
||||
on device. If you target the Intel(R) Xeon Phi (TM) coprocessor, these
|
||||
libraries can be taken from MPSS too.
|
||||
|
||||
|
||||
How to Build the Intel(R) Offload Runtime Library
|
||||
=================================================
|
||||
|
||||
The Makefile at the top-level will attempt to detect what it needs to
|
||||
build the Intel(R) Offload Runtime Library. To see the default settings,
|
||||
type:
|
||||
|
||||
make info
|
||||
|
||||
You can change the Makefile's behavior with the following options:
|
||||
|
||||
root_dir: The path to the top-level directory containing the
|
||||
top-level Makefile. By default, this will take on the
|
||||
value of the current working directory.
|
||||
|
||||
build_dir: The path to the build directory. By default, this will
|
||||
take on value [root_dir]/build.
|
||||
|
||||
mpss_dir: The path to the Intel(R) Manycore Platform Software
|
||||
Stack install directory. By default, this will take on
|
||||
the value of operating system's root directory.
|
||||
|
||||
libiomp_host_dir: The path to the host Intel(R) OpenMP* Runtime Library.
|
||||
This option is required when the host compiler is other
|
||||
than icc.
|
||||
|
||||
libiomp_target_dir: The path to the target Intel(R) OpenMP* Runtime
|
||||
Library. This option is required when the target
|
||||
compiler is other than icc.
|
||||
|
||||
omp_header_dir: The path to the header file <omp.h> of Intel(R) OpenMP*
|
||||
Runtime Library. This option is required if either host
|
||||
or target compiler is other than icc.
|
||||
|
||||
os_host: Operating system on host. Currently supports only
|
||||
"linux" which is set by default.
|
||||
|
||||
os_target: Operating system on target device. Currently supports
|
||||
only "linux" which is set by default.
|
||||
|
||||
compiler_host: Which compiler to use for the build of the host part.
|
||||
Defaults to "gcc"*. Also supports "icc" and "clang"*.
|
||||
You should provide the full path to the compiler or it
|
||||
should be in the user's path.
|
||||
|
||||
compiler_host: Which compiler to use for the build of the target part.
|
||||
Defaults to "gcc"*. Also supports "icc" and "clang"*.
|
||||
You should provide the full path to the compiler or it
|
||||
should be in the user's path.
|
||||
|
||||
options_host: Additional options for the host compiler.
|
||||
|
||||
options_target: Additional options for the target compiler.
|
||||
|
||||
To use any of the options above, simple add <option_name>=<value>. For
|
||||
example, if you want to build with icc instead of gcc, type:
|
||||
|
||||
make compiler_host=icc compiler_target=icc
|
||||
|
||||
|
||||
Supported RTL Build Configurations
|
||||
==================================
|
||||
|
||||
Supported Architectures: Intel(R) 64, and Intel(R) Many Integrated
|
||||
Core Architecture
|
||||
|
||||
---------------------------------------------
|
||||
| icc/icl | gcc | clang |
|
||||
--------------|---------------|---------------------------|
|
||||
| Linux* OS | Yes | Yes(1) | Yes(1) |
|
||||
| OS X* | No | No | No |
|
||||
| Windows* OS | No | No | No |
|
||||
-----------------------------------------------------------
|
||||
|
||||
(1) Liboffload requires _rdtsc intrinsic, which may be unsupported by some
|
||||
versions of compiler. In this case you need to include src/rdtsc.h
|
||||
manually by using Makefile options options_host and options_target:
|
||||
|
||||
make options_host="-include src/rdtsc.h" options_target="-include src/rdtsc.h"
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
Notices
|
||||
=======
|
||||
|
||||
*Other names and brands may be claimed as the property of others.
|
||||
File diff suppressed because it is too large
Load Diff
Executable
+2328
File diff suppressed because it is too large
Load Diff
Executable
+90
@@ -0,0 +1,90 @@
|
||||
% Latex header for doxygen 1.8.3.1
|
||||
\documentclass{book}
|
||||
\usepackage[a4paper,top=2.5cm,bottom=2.5cm,left=2.5cm,right=2.5cm]{geometry}
|
||||
\usepackage{makeidx}
|
||||
\usepackage{natbib}
|
||||
\usepackage{graphicx}
|
||||
\usepackage{multicol}
|
||||
\usepackage{float}
|
||||
\usepackage{listings}
|
||||
\usepackage{color}
|
||||
\usepackage{ifthen}
|
||||
\usepackage[table]{xcolor}
|
||||
\usepackage{textcomp}
|
||||
\usepackage{alltt}
|
||||
\usepackage{ifpdf}
|
||||
\ifpdf
|
||||
\usepackage[pdftex,
|
||||
pagebackref=true,
|
||||
colorlinks=true,
|
||||
linkcolor=blue,
|
||||
unicode
|
||||
]{hyperref}
|
||||
\else
|
||||
\usepackage[ps2pdf,
|
||||
pagebackref=true,
|
||||
colorlinks=true,
|
||||
linkcolor=blue,
|
||||
unicode
|
||||
]{hyperref}
|
||||
\usepackage{pspicture}
|
||||
\fi
|
||||
\usepackage[utf8]{inputenc}
|
||||
\usepackage{mathptmx}
|
||||
\usepackage[scaled=.90]{helvet}
|
||||
\usepackage{courier}
|
||||
\usepackage{sectsty}
|
||||
\usepackage{amssymb}
|
||||
\usepackage[titles]{tocloft}
|
||||
\usepackage{doxygen}
|
||||
\usepackage{fancyhdr}
|
||||
\pagestyle{fancy}
|
||||
\lstset{language=C++,inputencoding=utf8,basicstyle=\footnotesize,breaklines=true,breakatwhitespace=true,tabsize=4,numbers=left }
|
||||
\makeindex
|
||||
\setcounter{tocdepth}{3}
|
||||
\renewcommand{\footrulewidth}{0.4pt}
|
||||
\renewcommand{\familydefault}{\sfdefault}
|
||||
\hfuzz=15pt
|
||||
\setlength{\emergencystretch}{15pt}
|
||||
\hbadness=750
|
||||
\tolerance=750
|
||||
\begin{document}
|
||||
\hypersetup{pageanchor=false,citecolor=blue}
|
||||
\begin{titlepage}
|
||||
\vspace*{7cm}
|
||||
\begin{center}
|
||||
{\Large Intel\textsuperscript{\textregistered} Offload Runtime Library }\\
|
||||
\vspace*{1cm}
|
||||
{\large Generated by Doxygen $doxygenversion }\\
|
||||
\vspace*{0.5cm}
|
||||
{\small $datetime }\\
|
||||
\end{center}
|
||||
\end{titlepage}
|
||||
|
||||
{\bf FTC Optimization Notice}
|
||||
|
||||
Intel's compilers may or may not optimize to the same degree for non-Intel microprocessors for
|
||||
optimizations that are not unique to Intel microprocessors. These optimizations include SSE2,
|
||||
SSE3, and SSSE3 instruction sets and other optimizations. Intel does not guarantee the
|
||||
availability, functionality, or effectiveness of any optimization on microprocessors not
|
||||
manufactured by Intel.
|
||||
|
||||
Microprocessor-dependent optimizations in this product are intended for use with Intel
|
||||
microprocessors. Certain optimizations not specific to Intel microarchitecture are reserved for
|
||||
Intel microprocessors. Please refer to the applicable product User and Reference Guides for
|
||||
more information regarding the specific instruction sets covered by this notice.
|
||||
|
||||
Notice revision \#20110804
|
||||
|
||||
\vspace*{0.5cm}
|
||||
|
||||
{\bf Trademarks}
|
||||
|
||||
Intel, Xeon, and Intel Xeon Phi are trademarks of Intel Corporation in the U.S. and/or other countries.
|
||||
|
||||
This document is Copyright \textcopyright 2014, Intel Corporation. All rights reserved.
|
||||
|
||||
\pagenumbering{roman}
|
||||
\tableofcontents
|
||||
\pagenumbering{arabic}
|
||||
\hypersetup{pageanchor=true,citecolor=blue}
|
||||
@@ -0,0 +1,344 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 "cean_util.h"
|
||||
#include "offload_common.h"
|
||||
|
||||
// 1. allocate element of CeanReadRanges type
|
||||
// 2. initialized it for reading consequently contiguous ranges
|
||||
// described by "ap" argument
|
||||
CeanReadRanges * init_read_ranges_arr_desc(const arr_desc *ap)
|
||||
{
|
||||
CeanReadRanges * res;
|
||||
|
||||
// find the max contiguous range
|
||||
int64_t rank = ap->rank - 1;
|
||||
int64_t length = ap->dim[rank].size;
|
||||
for (; rank >= 0; rank--) {
|
||||
if (ap->dim[rank].stride == 1) {
|
||||
length *= (ap->dim[rank].upper - ap->dim[rank].lower + 1);
|
||||
if (rank > 0 && length != ap->dim[rank - 1].size) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
res =(CeanReadRanges *)malloc(sizeof(CeanReadRanges) +
|
||||
(ap->rank - rank) * sizeof(CeanReadDim));
|
||||
res->current_number = 0;
|
||||
res->range_size = length;
|
||||
res->last_noncont_ind = rank;
|
||||
|
||||
// calculate number of contiguous ranges inside noncontiguous dimensions
|
||||
int count = 1;
|
||||
bool prev_is_cont = true;
|
||||
int64_t offset = 0;
|
||||
|
||||
for (; rank >= 0; rank--) {
|
||||
res->Dim[rank].count = count;
|
||||
res->Dim[rank].size = ap->dim[rank].stride * ap->dim[rank].size;
|
||||
count *= (prev_is_cont && ap->dim[rank].stride == 1? 1 :
|
||||
(ap->dim[rank].upper - ap->dim[rank].lower +
|
||||
ap->dim[rank].stride) / ap->dim[rank].stride);
|
||||
prev_is_cont = false;
|
||||
offset +=(ap->dim[rank].lower - ap->dim[rank].lindex) *
|
||||
ap->dim[rank].size;
|
||||
}
|
||||
res->range_max_number = count;
|
||||
res -> ptr = (void*)ap->base;
|
||||
res -> init_offset = offset;
|
||||
return res;
|
||||
}
|
||||
|
||||
// check if ranges described by 1 argument could be transferred into ranges
|
||||
// described by 2-nd one
|
||||
bool cean_ranges_match(
|
||||
CeanReadRanges * read_rng1,
|
||||
CeanReadRanges * read_rng2
|
||||
)
|
||||
{
|
||||
return ( read_rng1 == NULL || read_rng2 == NULL ||
|
||||
(read_rng1->range_size % read_rng2->range_size == 0 ||
|
||||
read_rng2->range_size % read_rng1->range_size == 0));
|
||||
}
|
||||
|
||||
// Set next offset and length and returns true for next range.
|
||||
// Returns false if the ranges are over.
|
||||
bool get_next_range(
|
||||
CeanReadRanges * read_rng,
|
||||
int64_t *offset
|
||||
)
|
||||
{
|
||||
if (++read_rng->current_number > read_rng->range_max_number) {
|
||||
read_rng->current_number = 0;
|
||||
return false;
|
||||
}
|
||||
int rank = 0;
|
||||
int num = read_rng->current_number - 1;
|
||||
int64_t cur_offset = 0;
|
||||
int num_loc;
|
||||
for (; rank <= read_rng->last_noncont_ind; rank++) {
|
||||
num_loc = num / read_rng->Dim[rank].count;
|
||||
cur_offset += num_loc * read_rng->Dim[rank].size;
|
||||
num = num % read_rng->Dim[rank].count;
|
||||
}
|
||||
*offset = cur_offset + read_rng->init_offset;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool is_arr_desc_contiguous(const arr_desc *ap)
|
||||
{
|
||||
int64_t rank = ap->rank - 1;
|
||||
int64_t length = ap->dim[rank].size;
|
||||
for (; rank >= 0; rank--) {
|
||||
if (ap->dim[rank].stride > 1 &&
|
||||
ap->dim[rank].upper - ap->dim[rank].lower != 0) {
|
||||
return false;
|
||||
}
|
||||
else if (length != ap->dim[rank].size) {
|
||||
for (; rank >= 0; rank--) {
|
||||
if (ap->dim[rank].upper - ap->dim[rank].lower != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
length *= (ap->dim[rank].upper - ap->dim[rank].lower + 1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int64_t cean_get_transf_size(CeanReadRanges * read_rng)
|
||||
{
|
||||
return(read_rng->range_max_number * read_rng->range_size);
|
||||
}
|
||||
|
||||
static uint64_t last_left, last_right;
|
||||
typedef void (*fpp)(const char *spaces, uint64_t low, uint64_t high, int esize);
|
||||
|
||||
static void generate_one_range(
|
||||
const char *spaces,
|
||||
uint64_t lrange,
|
||||
uint64_t rrange,
|
||||
fpp fp,
|
||||
int esize
|
||||
)
|
||||
{
|
||||
OFFLOAD_TRACE(3,
|
||||
"%s generate_one_range(lrange=%p, rrange=%p, esize=%d)\n",
|
||||
spaces, (void*)lrange, (void*)rrange, esize);
|
||||
if (last_left == -1) {
|
||||
// First range
|
||||
last_left = lrange;
|
||||
}
|
||||
else {
|
||||
if (lrange == last_right+1) {
|
||||
// Extend previous range, don't print
|
||||
}
|
||||
else {
|
||||
(*fp)(spaces, last_left, last_right, esize);
|
||||
last_left = lrange;
|
||||
}
|
||||
}
|
||||
last_right = rrange;
|
||||
}
|
||||
|
||||
static void generate_mem_ranges_one_rank(
|
||||
const char *spaces,
|
||||
uint64_t base,
|
||||
uint64_t rank,
|
||||
const struct dim_desc *ddp,
|
||||
fpp fp,
|
||||
int esize
|
||||
)
|
||||
{
|
||||
uint64_t lindex = ddp->lindex;
|
||||
uint64_t lower = ddp->lower;
|
||||
uint64_t upper = ddp->upper;
|
||||
uint64_t stride = ddp->stride;
|
||||
uint64_t size = ddp->size;
|
||||
OFFLOAD_TRACE(3,
|
||||
"%s "
|
||||
"generate_mem_ranges_one_rank(base=%p, rank=%lld, lindex=%lld, "
|
||||
"lower=%lld, upper=%lld, stride=%lld, size=%lld, esize=%d)\n",
|
||||
spaces, (void*)base, rank, lindex, lower, upper, stride, size, esize);
|
||||
if (rank == 1) {
|
||||
uint64_t lrange, rrange;
|
||||
if (stride == 1) {
|
||||
lrange = base + (lower-lindex)*size;
|
||||
rrange = lrange + (upper-lower+1)*size - 1;
|
||||
generate_one_range(spaces, lrange, rrange, fp, esize);
|
||||
}
|
||||
else {
|
||||
for (int i=lower-lindex; i<=upper-lindex; i+=stride) {
|
||||
lrange = base + i*size;
|
||||
rrange = lrange + size - 1;
|
||||
generate_one_range(spaces, lrange, rrange, fp, esize);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int i=lower-lindex; i<=upper-lindex; i+=stride) {
|
||||
generate_mem_ranges_one_rank(
|
||||
spaces, base+i*size, rank-1, ddp+1, fp, esize);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void generate_mem_ranges(
|
||||
const char *spaces,
|
||||
const arr_desc *adp,
|
||||
bool deref,
|
||||
fpp fp
|
||||
)
|
||||
{
|
||||
uint64_t esize;
|
||||
|
||||
OFFLOAD_TRACE(3,
|
||||
"%s "
|
||||
"generate_mem_ranges(adp=%p, deref=%d, fp)\n",
|
||||
spaces, adp, deref);
|
||||
last_left = -1;
|
||||
last_right = -2;
|
||||
|
||||
// Element size is derived from last dimension
|
||||
esize = adp->dim[adp->rank-1].size;
|
||||
|
||||
generate_mem_ranges_one_rank(
|
||||
// For c_cean_var the base addr is the address of the data
|
||||
// For c_cean_var_ptr the base addr is dereferenced to get to the data
|
||||
spaces, deref ? *((uint64_t*)(adp->base)) : adp->base,
|
||||
adp->rank, &adp->dim[0], fp, esize);
|
||||
(*fp)(spaces, last_left, last_right, esize);
|
||||
}
|
||||
|
||||
// returns offset and length of the data to be transferred
|
||||
void __arr_data_offset_and_length(
|
||||
const arr_desc *adp,
|
||||
int64_t &offset,
|
||||
int64_t &length
|
||||
)
|
||||
{
|
||||
int64_t rank = adp->rank - 1;
|
||||
int64_t size = adp->dim[rank].size;
|
||||
int64_t r_off = 0; // offset from right boundary
|
||||
|
||||
// find the rightmost dimension which takes just part of its
|
||||
// range. We define it if the size of left rank is not equal
|
||||
// the range's length between upper and lower boungaries
|
||||
while (rank > 0) {
|
||||
size *= (adp->dim[rank].upper - adp->dim[rank].lower + 1);
|
||||
if (size != adp->dim[rank - 1].size) {
|
||||
break;
|
||||
}
|
||||
rank--;
|
||||
}
|
||||
|
||||
offset = (adp->dim[rank].lower - adp->dim[rank].lindex) *
|
||||
adp->dim[rank].size;
|
||||
|
||||
// find gaps both from the left - offset and from the right - r_off
|
||||
for (rank--; rank >= 0; rank--) {
|
||||
offset += (adp->dim[rank].lower - adp->dim[rank].lindex) *
|
||||
adp->dim[rank].size;
|
||||
r_off += adp->dim[rank].size -
|
||||
(adp->dim[rank + 1].upper - adp->dim[rank + 1].lindex + 1) *
|
||||
adp->dim[rank + 1].size;
|
||||
}
|
||||
length = (adp->dim[0].upper - adp->dim[0].lindex + 1) *
|
||||
adp->dim[0].size - offset - r_off;
|
||||
}
|
||||
|
||||
#if OFFLOAD_DEBUG > 0
|
||||
|
||||
void print_range(
|
||||
const char *spaces,
|
||||
uint64_t low,
|
||||
uint64_t high,
|
||||
int esize
|
||||
)
|
||||
{
|
||||
char buffer[1024];
|
||||
char number[32];
|
||||
|
||||
OFFLOAD_TRACE(3, "%s print_range(low=%p, high=%p, esize=%d)\n",
|
||||
spaces, (void*)low, (void*)high, esize);
|
||||
|
||||
if (console_enabled < 4) {
|
||||
return;
|
||||
}
|
||||
OFFLOAD_TRACE(4, "%s values:\n", spaces);
|
||||
int count = 0;
|
||||
buffer[0] = '\0';
|
||||
while (low <= high)
|
||||
{
|
||||
switch (esize)
|
||||
{
|
||||
case 1:
|
||||
sprintf(number, "%d ", *((char *)low));
|
||||
low += 1;
|
||||
break;
|
||||
case 2:
|
||||
sprintf(number, "%d ", *((short *)low));
|
||||
low += 2;
|
||||
break;
|
||||
case 4:
|
||||
sprintf(number, "%d ", *((int *)low));
|
||||
low += 4;
|
||||
break;
|
||||
default:
|
||||
sprintf(number, "0x%016x ", *((uint64_t *)low));
|
||||
low += 8;
|
||||
break;
|
||||
}
|
||||
strcat(buffer, number);
|
||||
count++;
|
||||
if (count == 10) {
|
||||
OFFLOAD_TRACE(4, "%s %s\n", spaces, buffer);
|
||||
count = 0;
|
||||
buffer[0] = '\0';
|
||||
}
|
||||
}
|
||||
if (count != 0) {
|
||||
OFFLOAD_TRACE(4, "%s %s\n", spaces, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void __arr_desc_dump(
|
||||
const char *spaces,
|
||||
const char *name,
|
||||
const arr_desc *adp,
|
||||
bool deref
|
||||
)
|
||||
{
|
||||
OFFLOAD_TRACE(2, "%s%s CEAN expression %p\n", spaces, name, adp);
|
||||
|
||||
if (adp != 0) {
|
||||
OFFLOAD_TRACE(2, "%s base=%llx, rank=%lld\n",
|
||||
spaces, adp->base, adp->rank);
|
||||
|
||||
for (int i = 0; i < adp->rank; i++) {
|
||||
OFFLOAD_TRACE(2,
|
||||
"%s dimension %d: size=%lld, lindex=%lld, "
|
||||
"lower=%lld, upper=%lld, stride=%lld\n",
|
||||
spaces, i, adp->dim[i].size, adp->dim[i].lindex,
|
||||
adp->dim[i].lower, adp->dim[i].upper,
|
||||
adp->dim[i].stride);
|
||||
}
|
||||
// For c_cean_var the base addr is the address of the data
|
||||
// For c_cean_var_ptr the base addr is dereferenced to get to the data
|
||||
generate_mem_ranges(spaces, adp, deref, &print_range);
|
||||
}
|
||||
}
|
||||
#endif // OFFLOAD_DEBUG
|
||||
@@ -0,0 +1,96 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 CEAN_UTIL_H_INCLUDED
|
||||
#define CEAN_UTIL_H_INCLUDED
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// CEAN expression representation
|
||||
struct dim_desc {
|
||||
int64_t size; // Length of data type
|
||||
int64_t lindex; // Lower index
|
||||
int64_t lower; // Lower section bound
|
||||
int64_t upper; // Upper section bound
|
||||
int64_t stride; // Stride
|
||||
};
|
||||
|
||||
struct arr_desc {
|
||||
int64_t base; // Base address
|
||||
int64_t rank; // Rank of array
|
||||
dim_desc dim[1];
|
||||
};
|
||||
|
||||
struct CeanReadDim {
|
||||
int64_t count; // The number of elements in this dimension
|
||||
int64_t size; // The number of bytes between successive
|
||||
// elements in this dimension.
|
||||
};
|
||||
|
||||
struct CeanReadRanges {
|
||||
void * ptr;
|
||||
int64_t current_number; // the number of ranges read
|
||||
int64_t range_max_number; // number of contiguous ranges
|
||||
int64_t range_size; // size of max contiguous range
|
||||
int last_noncont_ind; // size of Dim array
|
||||
int64_t init_offset; // offset of 1-st element from array left bound
|
||||
CeanReadDim Dim[1];
|
||||
};
|
||||
|
||||
// array descriptor length
|
||||
#define __arr_desc_length(rank) \
|
||||
(sizeof(int64_t) + sizeof(dim_desc) * (rank))
|
||||
|
||||
// returns offset and length of the data to be transferred
|
||||
void __arr_data_offset_and_length(const arr_desc *adp,
|
||||
int64_t &offset,
|
||||
int64_t &length);
|
||||
|
||||
// define if data array described by argument is contiguous one
|
||||
bool is_arr_desc_contiguous(const arr_desc *ap);
|
||||
|
||||
// allocate element of CeanReadRanges type initialized
|
||||
// to read consequently contiguous ranges described by "ap" argument
|
||||
CeanReadRanges * init_read_ranges_arr_desc(const arr_desc *ap);
|
||||
|
||||
// check if ranges described by 1 argument could be transferred into ranges
|
||||
// described by 2-nd one
|
||||
bool cean_ranges_match(
|
||||
CeanReadRanges * read_rng1,
|
||||
CeanReadRanges * read_rng2
|
||||
);
|
||||
|
||||
// first argument - returned value by call to init_read_ranges_arr_desc.
|
||||
// returns true if offset and length of next range is set successfuly.
|
||||
// returns false if the ranges is over.
|
||||
bool get_next_range(
|
||||
CeanReadRanges * read_rng,
|
||||
int64_t *offset
|
||||
);
|
||||
|
||||
// returns number of transferred bytes
|
||||
int64_t cean_get_transf_size(CeanReadRanges * read_rng);
|
||||
|
||||
#if OFFLOAD_DEBUG > 0
|
||||
// prints array descriptor contents to stderr
|
||||
void __arr_desc_dump(
|
||||
const char *spaces,
|
||||
const char *name,
|
||||
const arr_desc *adp,
|
||||
bool dereference);
|
||||
#else
|
||||
#define __arr_desc_dump(
|
||||
spaces,
|
||||
name,
|
||||
adp,
|
||||
dereference)
|
||||
#endif // OFFLOAD_DEBUG
|
||||
|
||||
#endif // CEAN_UTIL_H_INCLUDED
|
||||
@@ -0,0 +1,350 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
// The COI host interface
|
||||
|
||||
#include "coi_client.h"
|
||||
#include "../offload_common.h"
|
||||
|
||||
namespace COI {
|
||||
|
||||
#define COI_VERSION1 "COI_1.0"
|
||||
#define COI_VERSION2 "COI_2.0"
|
||||
|
||||
bool is_available;
|
||||
static void* lib_handle;
|
||||
|
||||
// pointers to functions from COI library
|
||||
COIRESULT (*EngineGetCount)(COI_ISA_TYPE, uint32_t*);
|
||||
COIRESULT (*EngineGetHandle)(COI_ISA_TYPE, uint32_t, COIENGINE*);
|
||||
|
||||
COIRESULT (*ProcessCreateFromMemory)(COIENGINE, const char*, const void*,
|
||||
uint64_t, int, const char**, uint8_t,
|
||||
const char**, uint8_t, const char*,
|
||||
uint64_t, const char*, const char*,
|
||||
uint64_t, COIPROCESS*);
|
||||
COIRESULT (*ProcessDestroy)(COIPROCESS, int32_t, uint8_t, int8_t*, uint32_t*);
|
||||
COIRESULT (*ProcessGetFunctionHandles)(COIPROCESS, uint32_t, const char**,
|
||||
COIFUNCTION*);
|
||||
COIRESULT (*ProcessLoadLibraryFromMemory)(COIPROCESS, const void*, uint64_t,
|
||||
const char*, const char*,
|
||||
const char*, uint64_t, uint32_t,
|
||||
COILIBRARY*);
|
||||
COIRESULT (*ProcessRegisterLibraries)(uint32_t, const void**, const uint64_t*,
|
||||
const char**, const uint64_t*);
|
||||
|
||||
COIRESULT (*PipelineCreate)(COIPROCESS, COI_CPU_MASK, uint32_t, COIPIPELINE*);
|
||||
COIRESULT (*PipelineDestroy)(COIPIPELINE);
|
||||
COIRESULT (*PipelineRunFunction)(COIPIPELINE, COIFUNCTION, uint32_t,
|
||||
const COIBUFFER*, const COI_ACCESS_FLAGS*,
|
||||
uint32_t, const COIEVENT*, const void*,
|
||||
uint16_t, void*, uint16_t, COIEVENT*);
|
||||
|
||||
COIRESULT (*BufferCreate)(uint64_t, COI_BUFFER_TYPE, uint32_t, const void*,
|
||||
uint32_t, const COIPROCESS*, COIBUFFER*);
|
||||
COIRESULT (*BufferCreateFromMemory)(uint64_t, COI_BUFFER_TYPE, uint32_t,
|
||||
void*, uint32_t, const COIPROCESS*,
|
||||
COIBUFFER*);
|
||||
COIRESULT (*BufferDestroy)(COIBUFFER);
|
||||
COIRESULT (*BufferMap)(COIBUFFER, uint64_t, uint64_t, COI_MAP_TYPE, uint32_t,
|
||||
const COIEVENT*, COIEVENT*, COIMAPINSTANCE*, void**);
|
||||
COIRESULT (*BufferUnmap)(COIMAPINSTANCE, uint32_t, const COIEVENT*, COIEVENT*);
|
||||
COIRESULT (*BufferWrite)(COIBUFFER, uint64_t, const void*, uint64_t,
|
||||
COI_COPY_TYPE, uint32_t, const COIEVENT*, COIEVENT*);
|
||||
COIRESULT (*BufferRead)(COIBUFFER, uint64_t, void*, uint64_t, COI_COPY_TYPE,
|
||||
uint32_t, const COIEVENT*, COIEVENT*);
|
||||
COIRESULT (*BufferCopy)(COIBUFFER, COIBUFFER, uint64_t, uint64_t, uint64_t,
|
||||
COI_COPY_TYPE, uint32_t, const COIEVENT*, COIEVENT*);
|
||||
COIRESULT (*BufferGetSinkAddress)(COIBUFFER, uint64_t*);
|
||||
COIRESULT (*BufferSetState)(COIBUFFER, COIPROCESS, COI_BUFFER_STATE,
|
||||
COI_BUFFER_MOVE_FLAG, uint32_t,
|
||||
const COIEVENT*, COIEVENT*);
|
||||
|
||||
COIRESULT (*EventWait)(uint16_t, const COIEVENT*, int32_t, uint8_t, uint32_t*,
|
||||
uint32_t*);
|
||||
|
||||
uint64_t (*PerfGetCycleFrequency)(void);
|
||||
|
||||
bool init(void)
|
||||
{
|
||||
#ifndef TARGET_WINNT
|
||||
const char *lib_name = "libcoi_host.so.0";
|
||||
#else // TARGET_WINNT
|
||||
const char *lib_name = "coi_host.dll";
|
||||
#endif // TARGET_WINNT
|
||||
|
||||
OFFLOAD_DEBUG_TRACE(2, "Loading COI library %s ...\n", lib_name);
|
||||
lib_handle = DL_open(lib_name);
|
||||
if (lib_handle == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "Failed to load the library\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
EngineGetCount =
|
||||
(COIRESULT (*)(COI_ISA_TYPE, uint32_t*))
|
||||
DL_sym(lib_handle, "COIEngineGetCount", COI_VERSION1);
|
||||
if (EngineGetCount == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
|
||||
"COIEngineGetCount");
|
||||
fini();
|
||||
return false;
|
||||
}
|
||||
|
||||
EngineGetHandle =
|
||||
(COIRESULT (*)(COI_ISA_TYPE, uint32_t, COIENGINE*))
|
||||
DL_sym(lib_handle, "COIEngineGetHandle", COI_VERSION1);
|
||||
if (EngineGetHandle == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
|
||||
"COIEngineGetHandle");
|
||||
fini();
|
||||
return false;
|
||||
}
|
||||
|
||||
ProcessCreateFromMemory =
|
||||
(COIRESULT (*)(COIENGINE, const char*, const void*, uint64_t, int,
|
||||
const char**, uint8_t, const char**, uint8_t,
|
||||
const char*, uint64_t, const char*, const char*,
|
||||
uint64_t, COIPROCESS*))
|
||||
DL_sym(lib_handle, "COIProcessCreateFromMemory", COI_VERSION1);
|
||||
if (ProcessCreateFromMemory == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
|
||||
"COIProcessCreateFromMemory");
|
||||
fini();
|
||||
return false;
|
||||
}
|
||||
|
||||
ProcessDestroy =
|
||||
(COIRESULT (*)(COIPROCESS, int32_t, uint8_t, int8_t*,
|
||||
uint32_t*))
|
||||
DL_sym(lib_handle, "COIProcessDestroy", COI_VERSION1);
|
||||
if (ProcessDestroy == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
|
||||
"COIProcessDestroy");
|
||||
fini();
|
||||
return false;
|
||||
}
|
||||
|
||||
ProcessGetFunctionHandles =
|
||||
(COIRESULT (*)(COIPROCESS, uint32_t, const char**, COIFUNCTION*))
|
||||
DL_sym(lib_handle, "COIProcessGetFunctionHandles", COI_VERSION1);
|
||||
if (ProcessGetFunctionHandles == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
|
||||
"COIProcessGetFunctionHandles");
|
||||
fini();
|
||||
return false;
|
||||
}
|
||||
|
||||
ProcessLoadLibraryFromMemory =
|
||||
(COIRESULT (*)(COIPROCESS, const void*, uint64_t, const char*,
|
||||
const char*, const char*, uint64_t, uint32_t,
|
||||
COILIBRARY*))
|
||||
DL_sym(lib_handle, "COIProcessLoadLibraryFromMemory", COI_VERSION2);
|
||||
if (ProcessLoadLibraryFromMemory == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
|
||||
"COIProcessLoadLibraryFromMemory");
|
||||
fini();
|
||||
return false;
|
||||
}
|
||||
|
||||
ProcessRegisterLibraries =
|
||||
(COIRESULT (*)(uint32_t, const void**, const uint64_t*, const char**,
|
||||
const uint64_t*))
|
||||
DL_sym(lib_handle, "COIProcessRegisterLibraries", COI_VERSION1);
|
||||
if (ProcessRegisterLibraries == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
|
||||
"COIProcessRegisterLibraries");
|
||||
fini();
|
||||
return false;
|
||||
}
|
||||
|
||||
PipelineCreate =
|
||||
(COIRESULT (*)(COIPROCESS, COI_CPU_MASK, uint32_t, COIPIPELINE*))
|
||||
DL_sym(lib_handle, "COIPipelineCreate", COI_VERSION1);
|
||||
if (PipelineCreate == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
|
||||
"COIPipelineCreate");
|
||||
fini();
|
||||
return false;
|
||||
}
|
||||
|
||||
PipelineDestroy =
|
||||
(COIRESULT (*)(COIPIPELINE))
|
||||
DL_sym(lib_handle, "COIPipelineDestroy", COI_VERSION1);
|
||||
if (PipelineDestroy == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
|
||||
"COIPipelineDestroy");
|
||||
fini();
|
||||
return false;
|
||||
}
|
||||
|
||||
PipelineRunFunction =
|
||||
(COIRESULT (*)(COIPIPELINE, COIFUNCTION, uint32_t, const COIBUFFER*,
|
||||
const COI_ACCESS_FLAGS*, uint32_t, const COIEVENT*,
|
||||
const void*, uint16_t, void*, uint16_t, COIEVENT*))
|
||||
DL_sym(lib_handle, "COIPipelineRunFunction", COI_VERSION1);
|
||||
if (PipelineRunFunction == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
|
||||
"COIPipelineRunFunction");
|
||||
fini();
|
||||
return false;
|
||||
}
|
||||
|
||||
BufferCreate =
|
||||
(COIRESULT (*)(uint64_t, COI_BUFFER_TYPE, uint32_t, const void*,
|
||||
uint32_t, const COIPROCESS*, COIBUFFER*))
|
||||
DL_sym(lib_handle, "COIBufferCreate", COI_VERSION1);
|
||||
if (BufferCreate == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
|
||||
"COIBufferCreate");
|
||||
fini();
|
||||
return false;
|
||||
}
|
||||
|
||||
BufferCreateFromMemory =
|
||||
(COIRESULT (*)(uint64_t, COI_BUFFER_TYPE, uint32_t, void*,
|
||||
uint32_t, const COIPROCESS*, COIBUFFER*))
|
||||
DL_sym(lib_handle, "COIBufferCreateFromMemory", COI_VERSION1);
|
||||
if (BufferCreateFromMemory == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
|
||||
"COIBufferCreateFromMemory");
|
||||
fini();
|
||||
return false;
|
||||
}
|
||||
|
||||
BufferDestroy =
|
||||
(COIRESULT (*)(COIBUFFER))
|
||||
DL_sym(lib_handle, "COIBufferDestroy", COI_VERSION1);
|
||||
if (BufferDestroy == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
|
||||
"COIBufferDestroy");
|
||||
fini();
|
||||
return false;
|
||||
}
|
||||
|
||||
BufferMap =
|
||||
(COIRESULT (*)(COIBUFFER, uint64_t, uint64_t, COI_MAP_TYPE, uint32_t,
|
||||
const COIEVENT*, COIEVENT*, COIMAPINSTANCE*,
|
||||
void**))
|
||||
DL_sym(lib_handle, "COIBufferMap", COI_VERSION1);
|
||||
if (BufferMap == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
|
||||
"COIBufferMap");
|
||||
fini();
|
||||
return false;
|
||||
}
|
||||
|
||||
BufferUnmap =
|
||||
(COIRESULT (*)(COIMAPINSTANCE, uint32_t, const COIEVENT*,
|
||||
COIEVENT*))
|
||||
DL_sym(lib_handle, "COIBufferUnmap", COI_VERSION1);
|
||||
if (BufferUnmap == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
|
||||
"COIBufferUnmap");
|
||||
fini();
|
||||
return false;
|
||||
}
|
||||
|
||||
BufferWrite =
|
||||
(COIRESULT (*)(COIBUFFER, uint64_t, const void*, uint64_t,
|
||||
COI_COPY_TYPE, uint32_t, const COIEVENT*,
|
||||
COIEVENT*))
|
||||
DL_sym(lib_handle, "COIBufferWrite", COI_VERSION1);
|
||||
if (BufferWrite == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
|
||||
"COIBufferWrite");
|
||||
fini();
|
||||
return false;
|
||||
}
|
||||
|
||||
BufferRead =
|
||||
(COIRESULT (*)(COIBUFFER, uint64_t, void*, uint64_t,
|
||||
COI_COPY_TYPE, uint32_t,
|
||||
const COIEVENT*, COIEVENT*))
|
||||
DL_sym(lib_handle, "COIBufferRead", COI_VERSION1);
|
||||
if (BufferRead == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
|
||||
"COIBufferRead");
|
||||
fini();
|
||||
return false;
|
||||
}
|
||||
|
||||
BufferCopy =
|
||||
(COIRESULT (*)(COIBUFFER, COIBUFFER, uint64_t, uint64_t, uint64_t,
|
||||
COI_COPY_TYPE, uint32_t, const COIEVENT*,
|
||||
COIEVENT*))
|
||||
DL_sym(lib_handle, "COIBufferCopy", COI_VERSION1);
|
||||
if (BufferCopy == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
|
||||
"COIBufferCopy");
|
||||
fini();
|
||||
return false;
|
||||
}
|
||||
|
||||
BufferGetSinkAddress =
|
||||
(COIRESULT (*)(COIBUFFER, uint64_t*))
|
||||
DL_sym(lib_handle, "COIBufferGetSinkAddress", COI_VERSION1);
|
||||
if (BufferGetSinkAddress == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
|
||||
"COIBufferGetSinkAddress");
|
||||
fini();
|
||||
return false;
|
||||
}
|
||||
|
||||
BufferSetState =
|
||||
(COIRESULT(*)(COIBUFFER, COIPROCESS, COI_BUFFER_STATE,
|
||||
COI_BUFFER_MOVE_FLAG, uint32_t, const COIEVENT*,
|
||||
COIEVENT*))
|
||||
DL_sym(lib_handle, "COIBufferSetState", COI_VERSION1);
|
||||
if (BufferSetState == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
|
||||
"COIBufferSetState");
|
||||
fini();
|
||||
return false;
|
||||
}
|
||||
|
||||
EventWait =
|
||||
(COIRESULT (*)(uint16_t, const COIEVENT*, int32_t, uint8_t,
|
||||
uint32_t*, uint32_t*))
|
||||
DL_sym(lib_handle, "COIEventWait", COI_VERSION1);
|
||||
if (EventWait == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
|
||||
"COIEventWait");
|
||||
fini();
|
||||
return false;
|
||||
}
|
||||
|
||||
PerfGetCycleFrequency =
|
||||
(uint64_t (*)(void))
|
||||
DL_sym(lib_handle, "COIPerfGetCycleFrequency", COI_VERSION1);
|
||||
if (PerfGetCycleFrequency == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in COI library\n",
|
||||
"COIPerfGetCycleFrequency");
|
||||
fini();
|
||||
return false;
|
||||
}
|
||||
|
||||
is_available = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void fini(void)
|
||||
{
|
||||
is_available = false;
|
||||
|
||||
if (lib_handle != 0) {
|
||||
#ifndef TARGET_WINNT
|
||||
DL_close(lib_handle);
|
||||
#endif // TARGET_WINNT
|
||||
lib_handle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace COI
|
||||
@@ -0,0 +1,118 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
// The interface between offload library and the COI API on the host
|
||||
|
||||
#ifndef COI_CLIENT_H_INCLUDED
|
||||
#define COI_CLIENT_H_INCLUDED
|
||||
|
||||
#include <common/COIPerf_common.h>
|
||||
#include <source/COIEngine_source.h>
|
||||
#include <source/COIProcess_source.h>
|
||||
#include <source/COIPipeline_source.h>
|
||||
#include <source/COIBuffer_source.h>
|
||||
#include <source/COIEvent_source.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "../liboffload_error_codes.h"
|
||||
#include "../offload_util.h"
|
||||
|
||||
#define MIC_ENGINES_MAX 128
|
||||
|
||||
#if MIC_ENGINES_MAX < COI_MAX_ISA_MIC_DEVICES
|
||||
#error MIC_ENGINES_MAX need to be increased
|
||||
#endif
|
||||
|
||||
// COI library interface
|
||||
namespace COI {
|
||||
|
||||
extern bool init(void);
|
||||
extern void fini(void);
|
||||
|
||||
extern bool is_available;
|
||||
|
||||
// pointers to functions from COI library
|
||||
extern COIRESULT (*EngineGetCount)(COI_ISA_TYPE, uint32_t*);
|
||||
extern COIRESULT (*EngineGetHandle)(COI_ISA_TYPE, uint32_t, COIENGINE*);
|
||||
|
||||
extern COIRESULT (*ProcessCreateFromMemory)(COIENGINE, const char*,
|
||||
const void*, uint64_t, int,
|
||||
const char**, uint8_t,
|
||||
const char**, uint8_t,
|
||||
const char*, uint64_t,
|
||||
const char*,
|
||||
const char*, uint64_t,
|
||||
COIPROCESS*);
|
||||
extern COIRESULT (*ProcessDestroy)(COIPROCESS, int32_t, uint8_t,
|
||||
int8_t*, uint32_t*);
|
||||
extern COIRESULT (*ProcessGetFunctionHandles)(COIPROCESS, uint32_t,
|
||||
const char**,
|
||||
COIFUNCTION*);
|
||||
extern COIRESULT (*ProcessLoadLibraryFromMemory)(COIPROCESS,
|
||||
const void*,
|
||||
uint64_t,
|
||||
const char*,
|
||||
const char*,
|
||||
const char*,
|
||||
uint64_t,
|
||||
uint32_t,
|
||||
COILIBRARY*);
|
||||
extern COIRESULT (*ProcessRegisterLibraries)(uint32_t,
|
||||
const void**,
|
||||
const uint64_t*,
|
||||
const char**,
|
||||
const uint64_t*);
|
||||
|
||||
extern COIRESULT (*PipelineCreate)(COIPROCESS, COI_CPU_MASK, uint32_t,
|
||||
COIPIPELINE*);
|
||||
extern COIRESULT (*PipelineDestroy)(COIPIPELINE);
|
||||
extern COIRESULT (*PipelineRunFunction)(COIPIPELINE, COIFUNCTION,
|
||||
uint32_t, const COIBUFFER*,
|
||||
const COI_ACCESS_FLAGS*,
|
||||
uint32_t, const COIEVENT*,
|
||||
const void*, uint16_t, void*,
|
||||
uint16_t, COIEVENT*);
|
||||
|
||||
extern COIRESULT (*BufferCreate)(uint64_t, COI_BUFFER_TYPE, uint32_t,
|
||||
const void*, uint32_t,
|
||||
const COIPROCESS*, COIBUFFER*);
|
||||
extern COIRESULT (*BufferCreateFromMemory)(uint64_t, COI_BUFFER_TYPE,
|
||||
uint32_t, void*,
|
||||
uint32_t, const COIPROCESS*,
|
||||
COIBUFFER*);
|
||||
extern COIRESULT (*BufferDestroy)(COIBUFFER);
|
||||
extern COIRESULT (*BufferMap)(COIBUFFER, uint64_t, uint64_t,
|
||||
COI_MAP_TYPE, uint32_t, const COIEVENT*,
|
||||
COIEVENT*, COIMAPINSTANCE*, void**);
|
||||
extern COIRESULT (*BufferUnmap)(COIMAPINSTANCE, uint32_t,
|
||||
const COIEVENT*, COIEVENT*);
|
||||
extern COIRESULT (*BufferWrite)(COIBUFFER, uint64_t, const void*,
|
||||
uint64_t, COI_COPY_TYPE, uint32_t,
|
||||
const COIEVENT*, COIEVENT*);
|
||||
extern COIRESULT (*BufferRead)(COIBUFFER, uint64_t, void*, uint64_t,
|
||||
COI_COPY_TYPE, uint32_t,
|
||||
const COIEVENT*, COIEVENT*);
|
||||
extern COIRESULT (*BufferCopy)(COIBUFFER, COIBUFFER, uint64_t, uint64_t,
|
||||
uint64_t, COI_COPY_TYPE, uint32_t,
|
||||
const COIEVENT*, COIEVENT*);
|
||||
extern COIRESULT (*BufferGetSinkAddress)(COIBUFFER, uint64_t*);
|
||||
extern COIRESULT (*BufferSetState)(COIBUFFER, COIPROCESS, COI_BUFFER_STATE,
|
||||
COI_BUFFER_MOVE_FLAG, uint32_t,
|
||||
const COIEVENT*, COIEVENT*);
|
||||
|
||||
extern COIRESULT (*EventWait)(uint16_t, const COIEVENT*, int32_t,
|
||||
uint8_t, uint32_t*, uint32_t*);
|
||||
|
||||
extern uint64_t (*PerfGetCycleFrequency)(void);
|
||||
|
||||
} // namespace COI
|
||||
|
||||
#endif // COI_CLIENT_H_INCLUDED
|
||||
@@ -0,0 +1,130 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
// The COI interface on the target
|
||||
|
||||
#include "coi_server.h"
|
||||
|
||||
#include "../offload_target.h"
|
||||
#include "../offload_timer.h"
|
||||
#ifdef MYO_SUPPORT
|
||||
#include "../offload_myo_target.h" // for __offload_myoLibInit/Fini
|
||||
#endif // MYO_SUPPORT
|
||||
|
||||
COINATIVELIBEXPORT
|
||||
void server_compute(
|
||||
uint32_t buffer_count,
|
||||
void** buffers,
|
||||
uint64_t* buffers_len,
|
||||
void* misc_data,
|
||||
uint16_t misc_data_len,
|
||||
void* return_data,
|
||||
uint16_t return_data_len
|
||||
)
|
||||
{
|
||||
OffloadDescriptor::offload(buffer_count, buffers,
|
||||
misc_data, misc_data_len,
|
||||
return_data, return_data_len);
|
||||
}
|
||||
|
||||
COINATIVELIBEXPORT
|
||||
void server_init(
|
||||
uint32_t buffer_count,
|
||||
void** buffers,
|
||||
uint64_t* buffers_len,
|
||||
void* misc_data,
|
||||
uint16_t misc_data_len,
|
||||
void* return_data,
|
||||
uint16_t return_data_len
|
||||
)
|
||||
{
|
||||
struct init_data {
|
||||
int device_index;
|
||||
int devices_total;
|
||||
int console_level;
|
||||
int offload_report_level;
|
||||
} *data = (struct init_data*) misc_data;
|
||||
|
||||
// set device index and number of total devices
|
||||
mic_index = data->device_index;
|
||||
mic_engines_total = data->devices_total;
|
||||
|
||||
// initialize trace level
|
||||
console_enabled = data->console_level;
|
||||
offload_report_level = data->offload_report_level;
|
||||
|
||||
// return back the process id
|
||||
*((pid_t*) return_data) = getpid();
|
||||
}
|
||||
|
||||
COINATIVELIBEXPORT
|
||||
void server_var_table_size(
|
||||
uint32_t buffer_count,
|
||||
void** buffers,
|
||||
uint64_t* buffers_len,
|
||||
void* misc_data,
|
||||
uint16_t misc_data_len,
|
||||
void* return_data,
|
||||
uint16_t return_data_len
|
||||
)
|
||||
{
|
||||
struct Params {
|
||||
int64_t nelems;
|
||||
int64_t length;
|
||||
} *params;
|
||||
|
||||
params = static_cast<Params*>(return_data);
|
||||
params->length = __offload_vars.table_size(params->nelems);
|
||||
}
|
||||
|
||||
COINATIVELIBEXPORT
|
||||
void server_var_table_copy(
|
||||
uint32_t buffer_count,
|
||||
void** buffers,
|
||||
uint64_t* buffers_len,
|
||||
void* misc_data,
|
||||
uint16_t misc_data_len,
|
||||
void* return_data,
|
||||
uint16_t return_data_len
|
||||
)
|
||||
{
|
||||
__offload_vars.table_copy(buffers[0], *static_cast<int64_t*>(misc_data));
|
||||
}
|
||||
|
||||
#ifdef MYO_SUPPORT
|
||||
// temporary workaround for blocking behavior of myoiLibInit/Fini calls
|
||||
COINATIVELIBEXPORT
|
||||
void server_myoinit(
|
||||
uint32_t buffer_count,
|
||||
void** buffers,
|
||||
uint64_t* buffers_len,
|
||||
void* misc_data,
|
||||
uint16_t misc_data_len,
|
||||
void* return_data,
|
||||
uint16_t return_data_len
|
||||
)
|
||||
{
|
||||
__offload_myoLibInit();
|
||||
}
|
||||
|
||||
COINATIVELIBEXPORT
|
||||
void server_myofini(
|
||||
uint32_t buffer_count,
|
||||
void** buffers,
|
||||
uint64_t* buffers_len,
|
||||
void* misc_data,
|
||||
uint16_t misc_data_len,
|
||||
void* return_data,
|
||||
uint16_t return_data_len
|
||||
)
|
||||
{
|
||||
__offload_myoLibFini();
|
||||
}
|
||||
#endif // MYO_SUPPORT
|
||||
@@ -0,0 +1,74 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
//The interface between offload library and the COI API on the target.
|
||||
|
||||
#ifndef COI_SERVER_H_INCLUDED
|
||||
#define COI_SERVER_H_INCLUDED
|
||||
|
||||
#include <common/COIEngine_common.h>
|
||||
#include <common/COIPerf_common.h>
|
||||
#include <sink/COIProcess_sink.h>
|
||||
#include <sink/COIPipeline_sink.h>
|
||||
#include <sink/COIBuffer_sink.h>
|
||||
#include <list>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include "../liboffload_error_codes.h"
|
||||
|
||||
// wrappers for COI API
|
||||
#define PipelineStartExecutingRunFunctions() \
|
||||
{ \
|
||||
COIRESULT res = COIPipelineStartExecutingRunFunctions(); \
|
||||
if (res != COI_SUCCESS) { \
|
||||
LIBOFFLOAD_ERROR(c_pipeline_start_run_funcs, mic_index, res); \
|
||||
exit(1); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define ProcessWaitForShutdown() \
|
||||
{ \
|
||||
COIRESULT res = COIProcessWaitForShutdown(); \
|
||||
if (res != COI_SUCCESS) { \
|
||||
LIBOFFLOAD_ERROR(c_process_wait_shutdown, mic_index, res); \
|
||||
exit(1); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define BufferAddRef(buf) \
|
||||
{ \
|
||||
COIRESULT res = COIBufferAddRef(buf); \
|
||||
if (res != COI_SUCCESS) { \
|
||||
LIBOFFLOAD_ERROR(c_buf_add_ref, mic_index, res); \
|
||||
exit(1); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define BufferReleaseRef(buf) \
|
||||
{ \
|
||||
COIRESULT res = COIBufferReleaseRef(buf); \
|
||||
if (res != COI_SUCCESS) { \
|
||||
LIBOFFLOAD_ERROR(c_buf_release_ref, mic_index, res); \
|
||||
exit(1); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define EngineGetIndex(index) \
|
||||
{ \
|
||||
COI_ISA_TYPE isa_type; \
|
||||
COIRESULT res = COIEngineGetIndex(&isa_type, index); \
|
||||
if (res != COI_SUCCESS) { \
|
||||
LIBOFFLOAD_ERROR(c_get_engine_index, mic_index, res); \
|
||||
exit(1); \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif // COI_SERVER_H_INCLUDED
|
||||
@@ -0,0 +1,323 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 "compiler_if_host.h"
|
||||
|
||||
#include <malloc.h>
|
||||
#ifndef TARGET_WINNT
|
||||
#include <alloca.h>
|
||||
#endif // TARGET_WINNT
|
||||
|
||||
// Global counter on host.
|
||||
// This variable is used if P2OPT_offload_do_data_persistence == 2.
|
||||
// The variable used to identify offload constructs contained in one procedure.
|
||||
// Increment of OFFLOAD_CALL_COUNT is inserted at entries of HOST routines with
|
||||
// offload constructs.
|
||||
static int offload_call_count = 0;
|
||||
|
||||
extern "C" OFFLOAD OFFLOAD_TARGET_ACQUIRE(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
int is_optional,
|
||||
_Offload_status* status,
|
||||
const char* file,
|
||||
uint64_t line
|
||||
)
|
||||
{
|
||||
bool retval;
|
||||
OFFLOAD ofld;
|
||||
|
||||
// initialize status
|
||||
if (status != 0) {
|
||||
status->result = OFFLOAD_UNAVAILABLE;
|
||||
status->device_number = -1;
|
||||
status->data_sent = 0;
|
||||
status->data_received = 0;
|
||||
}
|
||||
|
||||
// make sure libray is initialized
|
||||
retval = __offload_init_library();
|
||||
|
||||
// OFFLOAD_TIMER_INIT must follow call to __offload_init_library
|
||||
OffloadHostTimerData * timer_data = OFFLOAD_TIMER_INIT(file, line);
|
||||
|
||||
OFFLOAD_TIMER_START(timer_data, c_offload_host_total_offload);
|
||||
|
||||
OFFLOAD_TIMER_START(timer_data, c_offload_host_initialize);
|
||||
|
||||
// initialize all devices is init_type is on_offload_all
|
||||
if (retval && __offload_init_type == c_init_on_offload_all) {
|
||||
for (int i = 0; i < mic_engines_total; i++) {
|
||||
mic_engines[i].init();
|
||||
}
|
||||
}
|
||||
OFFLOAD_TIMER_STOP(timer_data, c_offload_host_initialize);
|
||||
|
||||
OFFLOAD_TIMER_START(timer_data, c_offload_host_target_acquire);
|
||||
|
||||
if (target_type == TARGET_HOST) {
|
||||
// Host always available
|
||||
retval = true;
|
||||
}
|
||||
else if (target_type == TARGET_MIC) {
|
||||
if (target_number >= -1) {
|
||||
if (retval) {
|
||||
if (target_number >= 0) {
|
||||
// User provided the device number
|
||||
target_number = target_number % mic_engines_total;
|
||||
}
|
||||
else {
|
||||
// use device 0
|
||||
target_number = 0;
|
||||
}
|
||||
|
||||
// reserve device in ORSL
|
||||
if (is_optional) {
|
||||
if (!ORSL::try_reserve(target_number)) {
|
||||
target_number = -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!ORSL::reserve(target_number)) {
|
||||
target_number = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// initialize device
|
||||
if (target_number >= 0 &&
|
||||
__offload_init_type == c_init_on_offload) {
|
||||
OFFLOAD_TIMER_START(timer_data, c_offload_host_initialize);
|
||||
mic_engines[target_number].init();
|
||||
OFFLOAD_TIMER_STOP(timer_data, c_offload_host_initialize);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// fallback to CPU
|
||||
target_number = -1;
|
||||
}
|
||||
|
||||
if (target_number < 0 || !retval) {
|
||||
if (!is_optional && status == 0) {
|
||||
LIBOFFLOAD_ERROR(c_device_is_not_available);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
retval = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
LIBOFFLOAD_ERROR(c_invalid_device_number);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (retval) {
|
||||
ofld = new OffloadDescriptor(target_number, status,
|
||||
!is_optional, false, timer_data);
|
||||
OFFLOAD_TIMER_HOST_MIC_NUM(timer_data, target_number);
|
||||
Offload_Report_Prolog(timer_data);
|
||||
OFFLOAD_DEBUG_TRACE_1(2, timer_data->offload_number, c_offload_start,
|
||||
"Starting offload: target_type = %d, "
|
||||
"number = %d, is_optional = %d\n",
|
||||
target_type, target_number, is_optional);
|
||||
|
||||
OFFLOAD_TIMER_STOP(timer_data, c_offload_host_target_acquire);
|
||||
}
|
||||
else {
|
||||
ofld = NULL;
|
||||
|
||||
OFFLOAD_TIMER_STOP(timer_data, c_offload_host_target_acquire);
|
||||
OFFLOAD_TIMER_STOP(timer_data, c_offload_host_total_offload);
|
||||
offload_report_free_data(timer_data);
|
||||
}
|
||||
|
||||
return ofld;
|
||||
}
|
||||
|
||||
extern "C" OFFLOAD OFFLOAD_TARGET_ACQUIRE1(
|
||||
const int* device_num,
|
||||
const char* file,
|
||||
uint64_t line
|
||||
)
|
||||
{
|
||||
int target_number;
|
||||
|
||||
// make sure libray is initialized and at least one device is available
|
||||
if (!__offload_init_library()) {
|
||||
LIBOFFLOAD_ERROR(c_device_is_not_available);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// OFFLOAD_TIMER_INIT must follow call to __offload_init_library
|
||||
|
||||
OffloadHostTimerData * timer_data = OFFLOAD_TIMER_INIT(file, line);
|
||||
|
||||
OFFLOAD_TIMER_START(timer_data, c_offload_host_total_offload);
|
||||
|
||||
OFFLOAD_TIMER_START(timer_data, c_offload_host_initialize);
|
||||
|
||||
if (__offload_init_type == c_init_on_offload_all) {
|
||||
for (int i = 0; i < mic_engines_total; i++) {
|
||||
mic_engines[i].init();
|
||||
}
|
||||
}
|
||||
|
||||
OFFLOAD_TIMER_STOP(timer_data, c_offload_host_initialize);
|
||||
|
||||
OFFLOAD_TIMER_START(timer_data, c_offload_host_target_acquire);
|
||||
|
||||
// use default device number if it is not provided
|
||||
if (device_num != 0) {
|
||||
target_number = *device_num;
|
||||
}
|
||||
else {
|
||||
target_number = __omp_device_num;
|
||||
}
|
||||
|
||||
// device number should be a non-negative integer value
|
||||
if (target_number < 0) {
|
||||
LIBOFFLOAD_ERROR(c_omp_invalid_device_num);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// should we do this for OpenMP?
|
||||
target_number %= mic_engines_total;
|
||||
|
||||
// reserve device in ORSL
|
||||
if (!ORSL::reserve(target_number)) {
|
||||
LIBOFFLOAD_ERROR(c_device_is_not_available);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// initialize device(s)
|
||||
OFFLOAD_TIMER_START(timer_data, c_offload_host_initialize);
|
||||
|
||||
if (__offload_init_type == c_init_on_offload) {
|
||||
mic_engines[target_number].init();
|
||||
}
|
||||
|
||||
OFFLOAD_TIMER_STOP(timer_data, c_offload_host_initialize);
|
||||
|
||||
OFFLOAD ofld =
|
||||
new OffloadDescriptor(target_number, 0, true, true, timer_data);
|
||||
|
||||
OFFLOAD_TIMER_HOST_MIC_NUM(timer_data, target_number);
|
||||
|
||||
Offload_Report_Prolog(timer_data);
|
||||
|
||||
OFFLOAD_DEBUG_TRACE_1(2, timer_data->offload_number, c_offload_start,
|
||||
"Starting OpenMP offload, device = %d\n",
|
||||
target_number);
|
||||
|
||||
OFFLOAD_TIMER_STOP(timer_data, c_offload_host_target_acquire);
|
||||
|
||||
return ofld;
|
||||
}
|
||||
|
||||
int offload_offload_wrap(
|
||||
OFFLOAD ofld,
|
||||
const char *name,
|
||||
int is_empty,
|
||||
int num_vars,
|
||||
VarDesc *vars,
|
||||
VarDesc2 *vars2,
|
||||
int num_waits,
|
||||
const void **waits,
|
||||
const void **signal,
|
||||
int entry_id,
|
||||
const void *stack_addr
|
||||
)
|
||||
{
|
||||
bool ret = ofld->offload(name, is_empty, vars, vars2, num_vars,
|
||||
waits, num_waits, signal, entry_id, stack_addr);
|
||||
if (!ret || signal == 0) {
|
||||
delete ofld;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" int OFFLOAD_OFFLOAD1(
|
||||
OFFLOAD ofld,
|
||||
const char *name,
|
||||
int is_empty,
|
||||
int num_vars,
|
||||
VarDesc *vars,
|
||||
VarDesc2 *vars2,
|
||||
int num_waits,
|
||||
const void **waits,
|
||||
const void **signal
|
||||
)
|
||||
{
|
||||
return offload_offload_wrap(ofld, name, is_empty,
|
||||
num_vars, vars, vars2,
|
||||
num_waits, waits,
|
||||
signal, NULL, NULL);
|
||||
}
|
||||
|
||||
extern "C" int OFFLOAD_OFFLOAD2(
|
||||
OFFLOAD ofld,
|
||||
const char *name,
|
||||
int is_empty,
|
||||
int num_vars,
|
||||
VarDesc *vars,
|
||||
VarDesc2 *vars2,
|
||||
int num_waits,
|
||||
const void** waits,
|
||||
const void** signal,
|
||||
int entry_id,
|
||||
const void *stack_addr
|
||||
)
|
||||
{
|
||||
return offload_offload_wrap(ofld, name, is_empty,
|
||||
num_vars, vars, vars2,
|
||||
num_waits, waits,
|
||||
signal, entry_id, stack_addr);
|
||||
}
|
||||
|
||||
extern "C" int OFFLOAD_OFFLOAD(
|
||||
OFFLOAD ofld,
|
||||
const char *name,
|
||||
int is_empty,
|
||||
int num_vars,
|
||||
VarDesc *vars,
|
||||
VarDesc2 *vars2,
|
||||
int num_waits,
|
||||
const void **waits,
|
||||
const void *signal,
|
||||
int entry_id,
|
||||
const void *stack_addr
|
||||
)
|
||||
{
|
||||
// signal is passed by reference now
|
||||
const void **signal_new = (signal != 0) ? &signal : 0;
|
||||
const void **waits_new = 0;
|
||||
int num_waits_new = 0;
|
||||
|
||||
// remove NULL values from the list of signals to wait for
|
||||
if (num_waits > 0) {
|
||||
waits_new = (const void**) alloca(sizeof(void*) * num_waits);
|
||||
for (int i = 0; i < num_waits; i++) {
|
||||
if (waits[i] != 0) {
|
||||
waits_new[num_waits_new++] = waits[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return OFFLOAD_OFFLOAD1(ofld, name, is_empty,
|
||||
num_vars, vars, vars2,
|
||||
num_waits_new, waits_new,
|
||||
signal_new);
|
||||
}
|
||||
|
||||
extern "C" int OFFLOAD_CALL_COUNT()
|
||||
{
|
||||
offload_call_count++;
|
||||
return offload_call_count;
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
/*! \file
|
||||
\brief The interface between compiler-generated host code and runtime library
|
||||
*/
|
||||
|
||||
#ifndef COMPILER_IF_HOST_H_INCLUDED
|
||||
#define COMPILER_IF_HOST_H_INCLUDED
|
||||
|
||||
#include "offload_host.h"
|
||||
|
||||
#define OFFLOAD_TARGET_ACQUIRE OFFLOAD_PREFIX(target_acquire)
|
||||
#define OFFLOAD_TARGET_ACQUIRE1 OFFLOAD_PREFIX(target_acquire1)
|
||||
#define OFFLOAD_OFFLOAD OFFLOAD_PREFIX(offload)
|
||||
#define OFFLOAD_OFFLOAD1 OFFLOAD_PREFIX(offload1)
|
||||
#define OFFLOAD_OFFLOAD2 OFFLOAD_PREFIX(offload2)
|
||||
#define OFFLOAD_CALL_COUNT OFFLOAD_PREFIX(offload_call_count)
|
||||
|
||||
|
||||
/*! \fn OFFLOAD_TARGET_ACQUIRE
|
||||
\brief Attempt to acquire the target.
|
||||
\param target_type The type of target.
|
||||
\param target_number The device number.
|
||||
\param is_optional Whether CPU fall-back is allowed.
|
||||
\param status Address of variable to hold offload status.
|
||||
\param file Filename in which this offload occurred.
|
||||
\param line Line number in the file where this offload occurred.
|
||||
*/
|
||||
extern "C" OFFLOAD OFFLOAD_TARGET_ACQUIRE(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
int is_optional,
|
||||
_Offload_status* status,
|
||||
const char* file,
|
||||
uint64_t line
|
||||
);
|
||||
|
||||
/*! \fn OFFLOAD_TARGET_ACQUIRE1
|
||||
\brief Acquire the target for offload (OpenMP).
|
||||
\param device_number Device number or null if not specified.
|
||||
\param file Filename in which this offload occurred
|
||||
\param line Line number in the file where this offload occurred.
|
||||
*/
|
||||
extern "C" OFFLOAD OFFLOAD_TARGET_ACQUIRE1(
|
||||
const int* device_number,
|
||||
const char* file,
|
||||
uint64_t line
|
||||
);
|
||||
|
||||
/*! \fn OFFLOAD_OFFLOAD1
|
||||
\brief Run function on target using interface for old data persistence.
|
||||
\param o Offload descriptor created by OFFLOAD_TARGET_ACQUIRE.
|
||||
\param name Name of offload entry point.
|
||||
\param is_empty If no code to execute (e.g. offload_transfer)
|
||||
\param num_vars Number of variable descriptors.
|
||||
\param vars Pointer to VarDesc array.
|
||||
\param vars2 Pointer to VarDesc2 array.
|
||||
\param num_waits Number of "wait" values.
|
||||
\param waits Pointer to array of wait values.
|
||||
\param signal Pointer to signal value or NULL.
|
||||
*/
|
||||
extern "C" int OFFLOAD_OFFLOAD1(
|
||||
OFFLOAD o,
|
||||
const char *name,
|
||||
int is_empty,
|
||||
int num_vars,
|
||||
VarDesc *vars,
|
||||
VarDesc2 *vars2,
|
||||
int num_waits,
|
||||
const void** waits,
|
||||
const void** signal
|
||||
);
|
||||
|
||||
/*! \fn OFFLOAD_OFFLOAD2
|
||||
\brief Run function on target using interface for new data persistence.
|
||||
\param o Offload descriptor created by OFFLOAD_TARGET_ACQUIRE.
|
||||
\param name Name of offload entry point.
|
||||
\param is_empty If no code to execute (e.g. offload_transfer)
|
||||
\param num_vars Number of variable descriptors.
|
||||
\param vars Pointer to VarDesc array.
|
||||
\param vars2 Pointer to VarDesc2 array.
|
||||
\param num_waits Number of "wait" values.
|
||||
\param waits Pointer to array of wait values.
|
||||
\param signal Pointer to signal value or NULL.
|
||||
\param entry_id A signature for the function doing the offload.
|
||||
\param stack_addr The stack frame address of the function doing offload.
|
||||
*/
|
||||
extern "C" int OFFLOAD_OFFLOAD2(
|
||||
OFFLOAD o,
|
||||
const char *name,
|
||||
int is_empty,
|
||||
int num_vars,
|
||||
VarDesc *vars,
|
||||
VarDesc2 *vars2,
|
||||
int num_waits,
|
||||
const void** waits,
|
||||
const void** signal,
|
||||
int entry_id,
|
||||
const void *stack_addr
|
||||
);
|
||||
|
||||
// Run function on target (obsolete).
|
||||
// @param o OFFLOAD object
|
||||
// @param name function name
|
||||
extern "C" int OFFLOAD_OFFLOAD(
|
||||
OFFLOAD o,
|
||||
const char *name,
|
||||
int is_empty,
|
||||
int num_vars,
|
||||
VarDesc *vars,
|
||||
VarDesc2 *vars2,
|
||||
int num_waits,
|
||||
const void** waits,
|
||||
const void* signal,
|
||||
int entry_id = 0,
|
||||
const void *stack_addr = NULL
|
||||
);
|
||||
|
||||
// Global counter on host.
|
||||
// This variable is used if P2OPT_offload_do_data_persistence == 2.
|
||||
// The variable used to identify offload constructs contained in one procedure.
|
||||
// Call to OFFLOAD_CALL_COUNT() is inserted at HOST on entry of the routine.
|
||||
extern "C" int OFFLOAD_CALL_COUNT();
|
||||
|
||||
#endif // COMPILER_IF_HOST_H_INCLUDED
|
||||
@@ -0,0 +1,44 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 "compiler_if_target.h"
|
||||
|
||||
extern "C" void OFFLOAD_TARGET_ENTER(
|
||||
OFFLOAD ofld,
|
||||
int vars_total,
|
||||
VarDesc *vars,
|
||||
VarDesc2 *vars2
|
||||
)
|
||||
{
|
||||
OFFLOAD_DEBUG_TRACE(3, "%s(%p, %d, %p, %p)\n", __func__, ofld,
|
||||
vars_total, vars, vars2);
|
||||
ofld->merge_var_descs(vars, vars2, vars_total);
|
||||
ofld->scatter_copyin_data();
|
||||
}
|
||||
|
||||
extern "C" void OFFLOAD_TARGET_LEAVE(
|
||||
OFFLOAD ofld
|
||||
)
|
||||
{
|
||||
OFFLOAD_DEBUG_TRACE(3, "%s(%p)\n", __func__, ofld);
|
||||
ofld->gather_copyout_data();
|
||||
}
|
||||
|
||||
extern "C" void OFFLOAD_TARGET_MAIN(void)
|
||||
{
|
||||
// initialize target part
|
||||
__offload_target_init();
|
||||
|
||||
// pass control to COI
|
||||
PipelineStartExecutingRunFunctions();
|
||||
ProcessWaitForShutdown();
|
||||
|
||||
OFFLOAD_DEBUG_TRACE(2, "Exiting main...\n");
|
||||
}
|
||||
@@ -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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
/*! \file
|
||||
\brief The interface between compiler-generated target code and runtime library
|
||||
*/
|
||||
|
||||
#ifndef COMPILER_IF_TARGET_H_INCLUDED
|
||||
#define COMPILER_IF_TARGET_H_INCLUDED
|
||||
|
||||
#include "offload_target.h"
|
||||
|
||||
#define OFFLOAD_TARGET_ENTER OFFLOAD_PREFIX(target_enter)
|
||||
#define OFFLOAD_TARGET_LEAVE OFFLOAD_PREFIX(target_leave)
|
||||
#define OFFLOAD_TARGET_MAIN OFFLOAD_PREFIX(target_main)
|
||||
|
||||
/*! \fn OFFLOAD_TARGET_ENTER
|
||||
\brief Fill in variable addresses using VarDesc array.
|
||||
\brief Then call back the runtime library to fetch data.
|
||||
\param ofld Offload descriptor created by runtime.
|
||||
\param var_desc_num Number of variable descriptors.
|
||||
\param var_desc Pointer to VarDesc array.
|
||||
\param var_desc2 Pointer to VarDesc2 array.
|
||||
*/
|
||||
extern "C" void OFFLOAD_TARGET_ENTER(
|
||||
OFFLOAD ofld,
|
||||
int var_desc_num,
|
||||
VarDesc *var_desc,
|
||||
VarDesc2 *var_desc2
|
||||
);
|
||||
|
||||
/*! \fn OFFLOAD_TARGET_LEAVE
|
||||
\brief Call back the runtime library to gather outputs using VarDesc array.
|
||||
\param ofld Offload descriptor created by OFFLOAD_TARGET_ACQUIRE.
|
||||
*/
|
||||
extern "C" void OFFLOAD_TARGET_LEAVE(
|
||||
OFFLOAD ofld
|
||||
);
|
||||
|
||||
// Entry point for the target application.
|
||||
extern "C" void OFFLOAD_TARGET_MAIN(void);
|
||||
|
||||
#endif // COMPILER_IF_TARGET_H_INCLUDED
|
||||
@@ -0,0 +1,131 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 "offload_common.h"
|
||||
|
||||
bool __dv_is_contiguous(const ArrDesc *dvp)
|
||||
{
|
||||
if (dvp->Flags & ArrDescFlagsContiguous) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (dvp->Rank != 0) {
|
||||
if (dvp->Dim[0].Mult != dvp->Len) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 1; i < dvp->Rank; i++) {
|
||||
if (dvp->Dim[i].Mult !=
|
||||
dvp->Dim[i-1].Extent * dvp->Dim[i-1].Mult) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool __dv_is_allocated(const ArrDesc *dvp)
|
||||
{
|
||||
return (dvp->Flags & ArrDescFlagsDefined);
|
||||
}
|
||||
|
||||
uint64_t __dv_data_length(const ArrDesc *dvp)
|
||||
{
|
||||
uint64_t size;
|
||||
|
||||
if (dvp->Rank == 0) {
|
||||
size = dvp->Len;
|
||||
return size;
|
||||
}
|
||||
|
||||
size = dvp->Len;
|
||||
for (int i = 0; i < dvp->Rank; ++i) {
|
||||
size += (dvp->Dim[i].Extent-1) * dvp->Dim[i].Mult;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
uint64_t __dv_data_length(const ArrDesc *dvp, int64_t count)
|
||||
{
|
||||
if (dvp->Rank == 0) {
|
||||
return count;
|
||||
}
|
||||
|
||||
return count * dvp->Dim[0].Mult;
|
||||
}
|
||||
|
||||
// Create CeanReadRanges data for reading contiguous ranges of
|
||||
// noncontiguous array defined by the argument
|
||||
CeanReadRanges * init_read_ranges_dv(const ArrDesc *dvp)
|
||||
{
|
||||
int64_t len;
|
||||
int count;
|
||||
int rank = dvp->Rank;
|
||||
CeanReadRanges *res = NULL;
|
||||
|
||||
if (rank != 0) {
|
||||
int i = 0;
|
||||
len = dvp->Len;
|
||||
if (dvp->Dim[0].Mult == len) {
|
||||
for (i = 1; i < rank; i++) {
|
||||
len *= dvp->Dim[i-1].Extent;
|
||||
if (dvp->Dim[i].Mult != len) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
res = (CeanReadRanges *)malloc(
|
||||
sizeof(CeanReadRanges) + (rank - i) * sizeof(CeanReadDim));
|
||||
res -> last_noncont_ind = rank - i - 1;
|
||||
count = 1;
|
||||
for (; i < rank; i++) {
|
||||
res->Dim[rank - i - 1].count = count;
|
||||
res->Dim[rank - i - 1].size = dvp->Dim[i].Mult;
|
||||
count *= dvp->Dim[i].Extent;
|
||||
}
|
||||
res -> range_max_number = count;
|
||||
res -> range_size = len;
|
||||
res -> ptr = (void*)dvp->Base;
|
||||
res -> current_number = 0;
|
||||
res -> init_offset = 0;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
#if OFFLOAD_DEBUG > 0
|
||||
void __dv_desc_dump(const char *name, const ArrDesc *dvp)
|
||||
{
|
||||
OFFLOAD_TRACE(3, "%s DV %p\n", name, dvp);
|
||||
|
||||
if (dvp != 0) {
|
||||
OFFLOAD_TRACE(3,
|
||||
" dv->Base = 0x%lx\n"
|
||||
" dv->Len = 0x%lx\n"
|
||||
" dv->Offset = 0x%lx\n"
|
||||
" dv->Flags = 0x%lx\n"
|
||||
" dv->Rank = 0x%lx\n"
|
||||
" dv->Resrvd = 0x%lx\n",
|
||||
dvp->Base,
|
||||
dvp->Len,
|
||||
dvp->Offset,
|
||||
dvp->Flags,
|
||||
dvp->Rank,
|
||||
dvp->Reserved);
|
||||
|
||||
for (int i = 0 ; i < dvp->Rank; i++) {
|
||||
OFFLOAD_TRACE(3,
|
||||
" (%d) Extent=%ld, Multiplier=%ld, LowerBound=%ld\n",
|
||||
i,
|
||||
dvp->Dim[i].Extent,
|
||||
dvp->Dim[i].Mult,
|
||||
dvp->Dim[i].LowerBound);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // OFFLOAD_DEBUG > 0
|
||||
@@ -0,0 +1,63 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 DV_UTIL_H_INCLUDED
|
||||
#define DV_UTIL_H_INCLUDED
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// Dope vector declarations
|
||||
#define ArrDescMaxArrayRank 31
|
||||
|
||||
// Dope vector flags
|
||||
#define ArrDescFlagsDefined 1
|
||||
#define ArrDescFlagsNodealloc 2
|
||||
#define ArrDescFlagsContiguous 4
|
||||
|
||||
typedef int64_t dv_size;
|
||||
|
||||
typedef struct DimDesc {
|
||||
dv_size Extent; // Number of elements in this dimension
|
||||
dv_size Mult; // Multiplier for this dimension.
|
||||
// The number of bytes between successive
|
||||
// elements in this dimension.
|
||||
dv_size LowerBound; // LowerBound of this dimension
|
||||
} DimDesc ;
|
||||
|
||||
typedef struct ArrDesc {
|
||||
dv_size Base; // Base address
|
||||
dv_size Len; // Length of data type, used only for
|
||||
// character strings.
|
||||
dv_size Offset;
|
||||
dv_size Flags; // Flags
|
||||
dv_size Rank; // Rank of pointer
|
||||
dv_size Reserved; // reserved for openmp requests
|
||||
DimDesc Dim[ArrDescMaxArrayRank];
|
||||
} ArrDesc ;
|
||||
|
||||
typedef ArrDesc* pArrDesc;
|
||||
|
||||
bool __dv_is_contiguous(const ArrDesc *dvp);
|
||||
|
||||
bool __dv_is_allocated(const ArrDesc *dvp);
|
||||
|
||||
uint64_t __dv_data_length(const ArrDesc *dvp);
|
||||
|
||||
uint64_t __dv_data_length(const ArrDesc *dvp, int64_t nelems);
|
||||
|
||||
CeanReadRanges * init_read_ranges_dv(const ArrDesc *dvp);
|
||||
|
||||
#if OFFLOAD_DEBUG > 0
|
||||
void __dv_desc_dump(const char *name, const ArrDesc *dvp);
|
||||
#else // OFFLOAD_DEBUG
|
||||
#define __dv_desc_dump(name, dvp)
|
||||
#endif // OFFLOAD_DEBUG
|
||||
|
||||
#endif // DV_UTIL_H_INCLUDED
|
||||
@@ -0,0 +1,452 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#ifndef va_copy
|
||||
#define va_copy(dst, src) ((dst) = (src))
|
||||
#endif
|
||||
|
||||
#include "liboffload_msg.h"
|
||||
|
||||
#include "liboffload_error_codes.h"
|
||||
|
||||
/***********************************************/
|
||||
/* error-handling function, liboffload_error_support */
|
||||
/***********************************************/
|
||||
|
||||
void __liboffload_error_support(error_types input_tag, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, input_tag);
|
||||
|
||||
switch (input_tag) {
|
||||
case c_device_is_not_available:
|
||||
write_message(stderr, msg_c_device_is_not_available, args);
|
||||
break;
|
||||
case c_invalid_device_number:
|
||||
write_message(stderr, msg_c_invalid_device_number, args);
|
||||
break;
|
||||
case c_send_func_ptr:
|
||||
write_message(stderr, msg_c_send_func_ptr, args);
|
||||
break;
|
||||
case c_receive_func_ptr:
|
||||
write_message(stderr, msg_c_receive_func_ptr, args);
|
||||
break;
|
||||
case c_offload_malloc:
|
||||
write_message(stderr, msg_c_offload_malloc, args);
|
||||
break;
|
||||
case c_offload1:
|
||||
write_message(stderr, msg_c_offload1, args);
|
||||
break;
|
||||
case c_unknown_var_type:
|
||||
write_message(stderr, c_unknown_var_type, args);
|
||||
break;
|
||||
case c_invalid_env_var_value:
|
||||
write_message(stderr, msg_c_invalid_env_var_value, args);
|
||||
break;
|
||||
case c_invalid_env_var_int_value:
|
||||
write_message(stderr, msg_c_invalid_env_var_int_value, args);
|
||||
break;
|
||||
case c_invalid_env_report_value:
|
||||
write_message(stderr, msg_c_invalid_env_report_value, args);
|
||||
break;
|
||||
case c_offload_signaled1:
|
||||
write_message(stderr, msg_c_offload_signaled1, args);
|
||||
break;
|
||||
case c_offload_signaled2:
|
||||
write_message(stderr, msg_c_offload_signaled2, args);
|
||||
break;
|
||||
case c_myowrapper_checkresult:
|
||||
write_message(stderr, msg_c_myowrapper_checkresult, args);
|
||||
break;
|
||||
case c_myotarget_checkresult:
|
||||
write_message(stderr, msg_c_myotarget_checkresult, args);
|
||||
break;
|
||||
case c_offload_descriptor_offload:
|
||||
write_message(stderr, msg_c_offload_descriptor_offload, args);
|
||||
break;
|
||||
case c_merge_var_descs1:
|
||||
write_message(stderr, msg_c_merge_var_descs1, args);
|
||||
break;
|
||||
case c_merge_var_descs2:
|
||||
write_message(stderr, msg_c_merge_var_descs2, args);
|
||||
break;
|
||||
case c_mic_parse_env_var_list1:
|
||||
write_message(stderr, msg_c_mic_parse_env_var_list1, args);
|
||||
break;
|
||||
case c_mic_parse_env_var_list2:
|
||||
write_message(stderr, msg_c_mic_parse_env_var_list2, args);
|
||||
break;
|
||||
case c_mic_process_exit_ret:
|
||||
write_message(stderr, msg_c_mic_process_exit_ret, args);
|
||||
break;
|
||||
case c_mic_process_exit_sig:
|
||||
write_message(stderr, msg_c_mic_process_exit_sig, args);
|
||||
break;
|
||||
case c_mic_process_exit:
|
||||
write_message(stderr, msg_c_mic_process_exit, args);
|
||||
break;
|
||||
case c_mic_init3:
|
||||
write_message(stderr, msg_c_mic_init3, args);
|
||||
break;
|
||||
case c_mic_init4:
|
||||
write_message(stderr, msg_c_mic_init4, args);
|
||||
break;
|
||||
case c_mic_init5:
|
||||
write_message(stderr, msg_c_mic_init5, args);
|
||||
break;
|
||||
case c_mic_init6:
|
||||
write_message(stderr, msg_c_mic_init6, args);
|
||||
break;
|
||||
case c_no_static_var_data:
|
||||
write_message(stderr, msg_c_no_static_var_data, args);
|
||||
break;
|
||||
case c_no_ptr_data:
|
||||
write_message(stderr, msg_c_no_ptr_data, args);
|
||||
break;
|
||||
case c_get_engine_handle:
|
||||
write_message(stderr, msg_c_get_engine_handle, args);
|
||||
break;
|
||||
case c_get_engine_index:
|
||||
write_message(stderr, msg_c_get_engine_index, args);
|
||||
break;
|
||||
case c_process_create:
|
||||
write_message(stderr, msg_c_process_create, args);
|
||||
break;
|
||||
case c_process_wait_shutdown:
|
||||
write_message(stderr, msg_c_process_wait_shutdown, args);
|
||||
break;
|
||||
case c_process_proxy_flush:
|
||||
write_message(stderr, msg_c_process_proxy_flush, args);
|
||||
break;
|
||||
case c_process_get_func_handles:
|
||||
write_message(stderr, msg_c_process_get_func_handles, args);
|
||||
break;
|
||||
case c_load_library:
|
||||
write_message(stderr, msg_c_load_library, args);
|
||||
break;
|
||||
case c_coipipe_max_number:
|
||||
write_message(stderr, msg_c_coi_pipeline_max_number, args);
|
||||
break;
|
||||
case c_pipeline_create:
|
||||
write_message(stderr, msg_c_pipeline_create, args);
|
||||
break;
|
||||
case c_pipeline_run_func:
|
||||
write_message(stderr, msg_c_pipeline_run_func, args);
|
||||
break;
|
||||
case c_pipeline_start_run_funcs:
|
||||
write_message(stderr, msg_c_pipeline_start_run_funcs, args);
|
||||
break;
|
||||
case c_buf_create:
|
||||
write_message(stderr, msg_c_buf_create, args);
|
||||
break;
|
||||
case c_buf_create_out_of_mem:
|
||||
write_message(stderr, msg_c_buf_create_out_of_mem, args);
|
||||
break;
|
||||
case c_buf_create_from_mem:
|
||||
write_message(stderr, msg_c_buf_create_from_mem, args);
|
||||
break;
|
||||
case c_buf_destroy:
|
||||
write_message(stderr, msg_c_buf_destroy, args);
|
||||
break;
|
||||
case c_buf_map:
|
||||
write_message(stderr, msg_c_buf_map, args);
|
||||
break;
|
||||
case c_buf_unmap:
|
||||
write_message(stderr, msg_c_buf_unmap, args);
|
||||
break;
|
||||
case c_buf_read:
|
||||
write_message(stderr, msg_c_buf_read, args);
|
||||
break;
|
||||
case c_buf_write:
|
||||
write_message(stderr, msg_c_buf_write, args);
|
||||
break;
|
||||
case c_buf_copy:
|
||||
write_message(stderr, msg_c_buf_copy, args);
|
||||
break;
|
||||
case c_buf_get_address:
|
||||
write_message(stderr, msg_c_buf_get_address, args);
|
||||
break;
|
||||
case c_buf_add_ref:
|
||||
write_message(stderr, msg_c_buf_add_ref, args);
|
||||
break;
|
||||
case c_buf_release_ref:
|
||||
write_message(stderr, msg_c_buf_release_ref, args);
|
||||
break;
|
||||
case c_buf_set_state:
|
||||
write_message(stderr, msg_c_buf_set_state, args);
|
||||
break;
|
||||
case c_event_wait:
|
||||
write_message(stderr, msg_c_event_wait, args);
|
||||
break;
|
||||
case c_zero_or_neg_ptr_len:
|
||||
write_message(stderr, msg_c_zero_or_neg_ptr_len, args);
|
||||
break;
|
||||
case c_zero_or_neg_transfer_size:
|
||||
write_message(stderr, msg_c_zero_or_neg_transfer_size, args);
|
||||
break;
|
||||
case c_bad_ptr_mem_range:
|
||||
write_message(stderr, msg_c_bad_ptr_mem_range, args);
|
||||
break;
|
||||
case c_different_src_and_dstn_sizes:
|
||||
write_message(stderr, msg_c_different_src_and_dstn_sizes, args);
|
||||
break;
|
||||
case c_ranges_dont_match:
|
||||
write_message(stderr, msg_c_ranges_dont_match, args);
|
||||
break;
|
||||
case c_destination_is_over:
|
||||
write_message(stderr, msg_c_destination_is_over, args);
|
||||
break;
|
||||
case c_slice_of_noncont_array:
|
||||
write_message(stderr, msg_c_slice_of_noncont_array, args);
|
||||
break;
|
||||
case c_non_contiguous_dope_vector:
|
||||
write_message(stderr, msg_c_non_contiguous_dope_vector, args);
|
||||
break;
|
||||
case c_pointer_array_mismatch:
|
||||
write_message(stderr, msg_c_pointer_array_mismatch, args);
|
||||
break;
|
||||
case c_omp_invalid_device_num_env:
|
||||
write_message(stderr, msg_c_omp_invalid_device_num_env, args);
|
||||
break;
|
||||
case c_omp_invalid_device_num:
|
||||
write_message(stderr, msg_c_omp_invalid_device_num, args);
|
||||
break;
|
||||
case c_unknown_binary_type:
|
||||
write_message(stderr, msg_c_unknown_binary_type, args);
|
||||
break;
|
||||
case c_multiple_target_exes:
|
||||
write_message(stderr, msg_c_multiple_target_exes, args);
|
||||
break;
|
||||
case c_no_target_exe:
|
||||
write_message(stderr, msg_c_no_target_exe, args);
|
||||
break;
|
||||
case c_report_unknown_timer_node:
|
||||
write_message(stderr, msg_c_report_unknown_timer_node, args);
|
||||
break;
|
||||
case c_report_unknown_trace_node:
|
||||
write_message(stderr, msg_c_report_unknown_trace_node, args);
|
||||
break;
|
||||
}
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
char const * report_get_message_str(error_types input_tag)
|
||||
{
|
||||
switch (input_tag) {
|
||||
case c_report_title:
|
||||
return (offload_get_message_str(msg_c_report_title));
|
||||
case c_report_from_file:
|
||||
return (offload_get_message_str(msg_c_report_from_file));
|
||||
case c_report_offload:
|
||||
return (offload_get_message_str(msg_c_report_offload));
|
||||
case c_report_mic:
|
||||
return (offload_get_message_str(msg_c_report_mic));
|
||||
case c_report_file:
|
||||
return (offload_get_message_str(msg_c_report_file));
|
||||
case c_report_line:
|
||||
return (offload_get_message_str(msg_c_report_line));
|
||||
case c_report_host:
|
||||
return (offload_get_message_str(msg_c_report_host));
|
||||
case c_report_tag:
|
||||
return (offload_get_message_str(msg_c_report_tag));
|
||||
case c_report_cpu_time:
|
||||
return (offload_get_message_str(msg_c_report_cpu_time));
|
||||
case c_report_seconds:
|
||||
return (offload_get_message_str(msg_c_report_seconds));
|
||||
case c_report_cpu_to_mic_data:
|
||||
return (offload_get_message_str(msg_c_report_cpu_to_mic_data));
|
||||
case c_report_bytes:
|
||||
return (offload_get_message_str(msg_c_report_bytes));
|
||||
case c_report_mic_time:
|
||||
return (offload_get_message_str(msg_c_report_mic_time));
|
||||
case c_report_mic_to_cpu_data:
|
||||
return (offload_get_message_str(msg_c_report_mic_to_cpu_data));
|
||||
case c_report_compute:
|
||||
return (offload_get_message_str(msg_c_report_compute));
|
||||
case c_report_copyin_data:
|
||||
return (offload_get_message_str(msg_c_report_copyin_data));
|
||||
case c_report_copyout_data:
|
||||
return (offload_get_message_str(msg_c_report_copyout_data));
|
||||
case c_report_create_buf_host:
|
||||
return (offload_get_message_str(c_report_create_buf_host));
|
||||
case c_report_create_buf_mic:
|
||||
return (offload_get_message_str(msg_c_report_create_buf_mic));
|
||||
case c_report_destroy:
|
||||
return (offload_get_message_str(msg_c_report_destroy));
|
||||
case c_report_gather_copyin_data:
|
||||
return (offload_get_message_str(msg_c_report_gather_copyin_data));
|
||||
case c_report_gather_copyout_data:
|
||||
return (offload_get_message_str(msg_c_report_gather_copyout_data));
|
||||
case c_report_state_signal:
|
||||
return (offload_get_message_str(msg_c_report_state_signal));
|
||||
case c_report_signal:
|
||||
return (offload_get_message_str(msg_c_report_signal));
|
||||
case c_report_wait:
|
||||
return (offload_get_message_str(msg_c_report_wait));
|
||||
case c_report_init:
|
||||
return (offload_get_message_str(msg_c_report_init));
|
||||
case c_report_init_func:
|
||||
return (offload_get_message_str(msg_c_report_init_func));
|
||||
case c_report_logical_card:
|
||||
return (offload_get_message_str(msg_c_report_logical_card));
|
||||
case c_report_mic_myo_fptr:
|
||||
return (offload_get_message_str(msg_c_report_mic_myo_fptr));
|
||||
case c_report_mic_myo_shared:
|
||||
return (offload_get_message_str(msg_c_report_mic_myo_shared));
|
||||
case c_report_myoacquire:
|
||||
return (offload_get_message_str(msg_c_report_myoacquire));
|
||||
case c_report_myofini:
|
||||
return (offload_get_message_str(msg_c_report_myofini));
|
||||
case c_report_myoinit:
|
||||
return (offload_get_message_str(msg_c_report_myoinit));
|
||||
case c_report_myoregister:
|
||||
return (offload_get_message_str(msg_c_report_myoregister));
|
||||
case c_report_myorelease:
|
||||
return (offload_get_message_str(msg_c_report_myorelease));
|
||||
case c_report_myosharedalignedfree:
|
||||
return (
|
||||
offload_get_message_str(msg_c_report_myosharedalignedfree));
|
||||
case c_report_myosharedalignedmalloc:
|
||||
return (
|
||||
offload_get_message_str(msg_c_report_myosharedalignedmalloc));
|
||||
case c_report_myosharedfree:
|
||||
return (offload_get_message_str(msg_c_report_myosharedfree));
|
||||
case c_report_myosharedmalloc:
|
||||
return (offload_get_message_str(msg_c_report_myosharedmalloc));
|
||||
case c_report_physical_card:
|
||||
return (offload_get_message_str(msg_c_report_physical_card));
|
||||
case c_report_receive_pointer_data:
|
||||
return (
|
||||
offload_get_message_str(msg_c_report_receive_pointer_data));
|
||||
case c_report_received_pointer_data:
|
||||
return (
|
||||
offload_get_message_str(msg_c_report_received_pointer_data));
|
||||
case c_report_register:
|
||||
return (offload_get_message_str(msg_c_report_register));
|
||||
case c_report_scatter_copyin_data:
|
||||
return (offload_get_message_str(msg_c_report_scatter_copyin_data));
|
||||
case c_report_scatter_copyout_data:
|
||||
return (
|
||||
offload_get_message_str(msg_c_report_scatter_copyout_data));
|
||||
case c_report_send_pointer_data:
|
||||
return (offload_get_message_str(msg_c_report_send_pointer_data));
|
||||
case c_report_sent_pointer_data:
|
||||
return (offload_get_message_str(msg_c_report_sent_pointer_data));
|
||||
case c_report_start:
|
||||
return (offload_get_message_str(msg_c_report_start));
|
||||
case c_report_start_target_func:
|
||||
return (offload_get_message_str(msg_c_report_start_target_func));
|
||||
case c_report_state:
|
||||
return (offload_get_message_str(msg_c_report_state));
|
||||
case c_report_unregister:
|
||||
return (offload_get_message_str(msg_c_report_unregister));
|
||||
case c_report_var:
|
||||
return (offload_get_message_str(msg_c_report_var));
|
||||
|
||||
default:
|
||||
LIBOFFLOAD_ERROR(c_report_unknown_trace_node);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
char const * report_get_host_stage_str(int i)
|
||||
{
|
||||
switch (i) {
|
||||
case c_offload_host_total_offload:
|
||||
return (
|
||||
offload_get_message_str(msg_c_report_host_total_offload_time));
|
||||
case c_offload_host_initialize:
|
||||
return (offload_get_message_str(msg_c_report_host_initialize));
|
||||
case c_offload_host_target_acquire:
|
||||
return (
|
||||
offload_get_message_str(msg_c_report_host_target_acquire));
|
||||
case c_offload_host_wait_deps:
|
||||
return (offload_get_message_str(msg_c_report_host_wait_deps));
|
||||
case c_offload_host_setup_buffers:
|
||||
return (offload_get_message_str(msg_c_report_host_setup_buffers));
|
||||
case c_offload_host_alloc_buffers:
|
||||
return (offload_get_message_str(msg_c_report_host_alloc_buffers));
|
||||
case c_offload_host_setup_misc_data:
|
||||
return (
|
||||
offload_get_message_str(msg_c_report_host_setup_misc_data));
|
||||
case c_offload_host_alloc_data_buffer:
|
||||
return (
|
||||
offload_get_message_str(msg_c_report_host_alloc_data_buffer));
|
||||
case c_offload_host_send_pointers:
|
||||
return (offload_get_message_str(msg_c_report_host_send_pointers));
|
||||
case c_offload_host_gather_inputs:
|
||||
return (offload_get_message_str(msg_c_report_host_gather_inputs));
|
||||
case c_offload_host_map_in_data_buffer:
|
||||
return (
|
||||
offload_get_message_str(msg_c_report_host_map_in_data_buffer));
|
||||
case c_offload_host_unmap_in_data_buffer:
|
||||
return (offload_get_message_str(
|
||||
msg_c_report_host_unmap_in_data_buffer));
|
||||
case c_offload_host_start_compute:
|
||||
return (offload_get_message_str(msg_c_report_host_start_compute));
|
||||
case c_offload_host_wait_compute:
|
||||
return (offload_get_message_str(msg_c_report_host_wait_compute));
|
||||
case c_offload_host_start_buffers_reads:
|
||||
return (offload_get_message_str(
|
||||
msg_c_report_host_start_buffers_reads));
|
||||
case c_offload_host_scatter_outputs:
|
||||
return (
|
||||
offload_get_message_str(msg_c_report_host_scatter_outputs));
|
||||
case c_offload_host_map_out_data_buffer:
|
||||
return (offload_get_message_str(
|
||||
msg_c_report_host_map_out_data_buffer));
|
||||
case c_offload_host_unmap_out_data_buffer:
|
||||
return (offload_get_message_str(
|
||||
msg_c_report_host_unmap_out_data_buffer));
|
||||
case c_offload_host_wait_buffers_reads:
|
||||
return (
|
||||
offload_get_message_str(msg_c_report_host_wait_buffers_reads));
|
||||
case c_offload_host_destroy_buffers:
|
||||
return (
|
||||
offload_get_message_str(msg_c_report_host_destroy_buffers));
|
||||
default:
|
||||
LIBOFFLOAD_ERROR(c_report_unknown_timer_node);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
char const * report_get_target_stage_str(int i)
|
||||
{
|
||||
switch (i) {
|
||||
case c_offload_target_total_time:
|
||||
return (offload_get_message_str(msg_c_report_target_total_time));
|
||||
case c_offload_target_descriptor_setup:
|
||||
return (
|
||||
offload_get_message_str(msg_c_report_target_descriptor_setup));
|
||||
case c_offload_target_func_lookup:
|
||||
return (offload_get_message_str(msg_c_report_target_func_lookup));
|
||||
case c_offload_target_func_time:
|
||||
return (offload_get_message_str(msg_c_report_target_func_time));
|
||||
case c_offload_target_scatter_inputs:
|
||||
return (
|
||||
offload_get_message_str(msg_c_report_target_scatter_inputs));
|
||||
case c_offload_target_add_buffer_refs:
|
||||
return (
|
||||
offload_get_message_str(msg_c_report_target_add_buffer_refs));
|
||||
case c_offload_target_compute:
|
||||
return (offload_get_message_str(msg_c_report_target_compute));
|
||||
case c_offload_target_gather_outputs:
|
||||
return (offload_get_message_str
|
||||
(msg_c_report_target_gather_outputs));
|
||||
case c_offload_target_release_buffer_refs:
|
||||
return (offload_get_message_str(
|
||||
msg_c_report_target_release_buffer_refs));
|
||||
default:
|
||||
LIBOFFLOAD_ERROR(c_report_unknown_timer_node);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,276 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
#if !defined(LIBOFFLOAD_ERROR_CODES_H)
|
||||
#define LIBOFFLOAD_ERROR_CODES_H
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
typedef enum
|
||||
{
|
||||
c_device_is_not_available = 0,
|
||||
c_invalid_device_number,
|
||||
c_offload1,
|
||||
c_unknown_var_type,
|
||||
c_send_func_ptr,
|
||||
c_receive_func_ptr,
|
||||
c_offload_malloc,
|
||||
c_invalid_env_var_value,
|
||||
c_invalid_env_var_int_value,
|
||||
c_invalid_env_report_value,
|
||||
c_offload_signaled1,
|
||||
c_offload_signaled2,
|
||||
c_myotarget_checkresult,
|
||||
c_myowrapper_checkresult,
|
||||
c_offload_descriptor_offload,
|
||||
c_merge_var_descs1,
|
||||
c_merge_var_descs2,
|
||||
c_mic_parse_env_var_list1,
|
||||
c_mic_parse_env_var_list2,
|
||||
c_mic_process_exit_ret,
|
||||
c_mic_process_exit_sig,
|
||||
c_mic_process_exit,
|
||||
c_mic_init3,
|
||||
c_mic_init4,
|
||||
c_mic_init5,
|
||||
c_mic_init6,
|
||||
c_no_static_var_data,
|
||||
c_no_ptr_data,
|
||||
c_get_engine_handle,
|
||||
c_get_engine_index,
|
||||
c_process_create,
|
||||
c_process_get_func_handles,
|
||||
c_process_wait_shutdown,
|
||||
c_process_proxy_flush,
|
||||
c_load_library,
|
||||
c_pipeline_create,
|
||||
c_pipeline_run_func,
|
||||
c_pipeline_start_run_funcs,
|
||||
c_buf_create,
|
||||
c_buf_create_out_of_mem,
|
||||
c_buf_create_from_mem,
|
||||
c_buf_destroy,
|
||||
c_buf_map,
|
||||
c_buf_unmap,
|
||||
c_buf_read,
|
||||
c_buf_write,
|
||||
c_buf_copy,
|
||||
c_buf_get_address,
|
||||
c_buf_add_ref,
|
||||
c_buf_release_ref,
|
||||
c_buf_set_state,
|
||||
c_event_wait,
|
||||
c_zero_or_neg_ptr_len,
|
||||
c_zero_or_neg_transfer_size,
|
||||
c_bad_ptr_mem_range,
|
||||
c_different_src_and_dstn_sizes,
|
||||
c_ranges_dont_match,
|
||||
c_destination_is_over,
|
||||
c_slice_of_noncont_array,
|
||||
c_non_contiguous_dope_vector,
|
||||
c_pointer_array_mismatch,
|
||||
c_omp_invalid_device_num_env,
|
||||
c_omp_invalid_device_num,
|
||||
c_unknown_binary_type,
|
||||
c_multiple_target_exes,
|
||||
c_no_target_exe,
|
||||
c_report_host,
|
||||
c_report_target,
|
||||
c_report_title,
|
||||
c_report_from_file,
|
||||
c_report_file,
|
||||
c_report_line,
|
||||
c_report_tag,
|
||||
c_report_seconds,
|
||||
c_report_bytes,
|
||||
c_report_mic,
|
||||
c_report_cpu_time,
|
||||
c_report_cpu_to_mic_data,
|
||||
c_report_mic_time,
|
||||
c_report_mic_to_cpu_data,
|
||||
c_report_unknown_timer_node,
|
||||
c_report_unknown_trace_node,
|
||||
c_report_offload,
|
||||
c_report_w_tag,
|
||||
c_report_state,
|
||||
c_report_start,
|
||||
c_report_init,
|
||||
c_report_logical_card,
|
||||
c_report_physical_card,
|
||||
c_report_register,
|
||||
c_report_init_func,
|
||||
c_report_create_buf_host,
|
||||
c_report_create_buf_mic,
|
||||
c_report_send_pointer_data,
|
||||
c_report_sent_pointer_data,
|
||||
c_report_gather_copyin_data,
|
||||
c_report_copyin_data,
|
||||
c_report_state_signal,
|
||||
c_report_signal,
|
||||
c_report_wait,
|
||||
c_report_compute,
|
||||
c_report_receive_pointer_data,
|
||||
c_report_received_pointer_data,
|
||||
c_report_start_target_func,
|
||||
c_report_var,
|
||||
c_report_scatter_copyin_data,
|
||||
c_report_gather_copyout_data,
|
||||
c_report_scatter_copyout_data,
|
||||
c_report_copyout_data,
|
||||
c_report_unregister,
|
||||
c_report_destroy,
|
||||
c_report_myoinit,
|
||||
c_report_myoregister,
|
||||
c_report_myofini,
|
||||
c_report_mic_myo_shared,
|
||||
c_report_mic_myo_fptr,
|
||||
c_report_myosharedmalloc,
|
||||
c_report_myosharedfree,
|
||||
c_report_myosharedalignedmalloc,
|
||||
c_report_myosharedalignedfree,
|
||||
c_report_myoacquire,
|
||||
c_report_myorelease,
|
||||
c_coipipe_max_number
|
||||
} error_types;
|
||||
|
||||
enum OffloadHostPhase {
|
||||
// Total time on host for entire offload
|
||||
c_offload_host_total_offload = 0,
|
||||
|
||||
// Time to load target binary
|
||||
c_offload_host_initialize,
|
||||
|
||||
// Time to acquire lrb availability dynamically
|
||||
c_offload_host_target_acquire,
|
||||
|
||||
// Time to wait for dependencies
|
||||
c_offload_host_wait_deps,
|
||||
|
||||
// Time to allocate pointer buffers, initiate writes for pointers
|
||||
// and calculate size of copyin/copyout buffer
|
||||
c_offload_host_setup_buffers,
|
||||
|
||||
// Time to allocate pointer buffers
|
||||
c_offload_host_alloc_buffers,
|
||||
|
||||
// Time to initialize misc data
|
||||
c_offload_host_setup_misc_data,
|
||||
|
||||
// Time to allocate copyin/copyout buffer
|
||||
c_offload_host_alloc_data_buffer,
|
||||
|
||||
// Time to initiate writes from host pointers to buffers
|
||||
c_offload_host_send_pointers,
|
||||
|
||||
// Time to Gather IN data of offload into buffer
|
||||
c_offload_host_gather_inputs,
|
||||
|
||||
// Time to map buffer
|
||||
c_offload_host_map_in_data_buffer,
|
||||
|
||||
// Time to unmap buffer
|
||||
c_offload_host_unmap_in_data_buffer,
|
||||
|
||||
// Time to start remote function call that does computation on lrb
|
||||
c_offload_host_start_compute,
|
||||
|
||||
// Time to wait for compute to finish
|
||||
c_offload_host_wait_compute,
|
||||
|
||||
// Time to initiate reads from pointer buffers
|
||||
c_offload_host_start_buffers_reads,
|
||||
|
||||
// Time to update host variabels with OUT data from buffer
|
||||
c_offload_host_scatter_outputs,
|
||||
|
||||
// Time to map buffer
|
||||
c_offload_host_map_out_data_buffer,
|
||||
|
||||
// Time to unmap buffer
|
||||
c_offload_host_unmap_out_data_buffer,
|
||||
|
||||
// Time to wait reads from buffers to finish
|
||||
c_offload_host_wait_buffers_reads,
|
||||
|
||||
// Time to destroy buffers that are no longer needed
|
||||
c_offload_host_destroy_buffers,
|
||||
|
||||
// LAST TIME MONITOR
|
||||
c_offload_host_max_phase
|
||||
};
|
||||
|
||||
enum OffloadTargetPhase {
|
||||
// Total time spent on the target
|
||||
c_offload_target_total_time = 0,
|
||||
|
||||
// Time to initialize offload descriptor
|
||||
c_offload_target_descriptor_setup,
|
||||
|
||||
// Time to find target entry point in lookup table
|
||||
c_offload_target_func_lookup,
|
||||
|
||||
// Total time spend executing offload entry
|
||||
c_offload_target_func_time,
|
||||
|
||||
// Time to initialize target variables with IN values from buffer
|
||||
c_offload_target_scatter_inputs,
|
||||
|
||||
// Time to add buffer reference for pointer buffers
|
||||
c_offload_target_add_buffer_refs,
|
||||
|
||||
// Total time on lrb for computation
|
||||
c_offload_target_compute,
|
||||
|
||||
// On lrb, time to copy OUT into buffer
|
||||
c_offload_target_gather_outputs,
|
||||
|
||||
// Time to release buffer references
|
||||
c_offload_target_release_buffer_refs,
|
||||
|
||||
// LAST TIME MONITOR
|
||||
c_offload_target_max_phase
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void __liboffload_error_support(error_types input_tag, ...);
|
||||
void __liboffload_report_support(error_types input_tag, ...);
|
||||
char const *offload_get_message_str(int msgCode);
|
||||
char const * report_get_message_str(error_types input_tag);
|
||||
char const * report_get_host_stage_str(int i);
|
||||
char const * report_get_target_stage_str(int i);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#define test_msg_cat(nm, msg) \
|
||||
fprintf(stderr, "\t TEST for %s \n \t", nm); \
|
||||
__liboffload_error_support(msg);
|
||||
|
||||
#define test_msg_cat1(nm, msg, ...) \
|
||||
fprintf(stderr, "\t TEST for %s \n \t", nm); \
|
||||
__liboffload_error_support(msg, __VA_ARGS__);
|
||||
|
||||
void write_message(FILE * file, int msgCode, va_list args_p);
|
||||
|
||||
#define LIBOFFLOAD_ERROR __liboffload_error_support
|
||||
|
||||
#ifdef TARGET_WINNT
|
||||
#define LIBOFFLOAD_ABORT \
|
||||
_set_abort_behavior(0, _WRITE_ABORT_MSG); \
|
||||
abort()
|
||||
#else
|
||||
#define LIBOFFLOAD_ABORT \
|
||||
abort()
|
||||
#endif
|
||||
|
||||
#endif // !defined(LIBOFFLOAD_ERROR_CODES_H)
|
||||
@@ -0,0 +1,35 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 <stdio.h>
|
||||
|
||||
// ===========================================================================
|
||||
// Bring in the static string table and the enumerations for indexing into
|
||||
// it.
|
||||
// ===========================================================================
|
||||
|
||||
#include "liboffload_msg.h"
|
||||
|
||||
# define DYNART_STDERR_PUTS(__message_text__) fputs((__message_text__),stderr)
|
||||
|
||||
// ===========================================================================
|
||||
// Now the code for accessing the message catalogs
|
||||
// ===========================================================================
|
||||
|
||||
|
||||
void write_message(FILE * file, int msgCode) {
|
||||
fputs(MESSAGE_TABLE_NAME[ msgCode ], file);
|
||||
fflush(file);
|
||||
}
|
||||
|
||||
char const *offload_get_message_str(int msgCode) {
|
||||
return MESSAGE_TABLE_NAME[ msgCode ];
|
||||
}
|
||||
@@ -0,0 +1,326 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// file: liboffload_msg.h
|
||||
enum {
|
||||
__dummy__ = 0,
|
||||
msg_c_device_is_not_available,
|
||||
msg_c_invalid_device_number,
|
||||
msg_c_send_func_ptr,
|
||||
msg_c_receive_func_ptr,
|
||||
msg_c_offload_malloc,
|
||||
msg_c_offload1,
|
||||
msg_c_unknown_var_type,
|
||||
msg_c_invalid_env_var_value,
|
||||
msg_c_invalid_env_var_int_value,
|
||||
msg_c_invalid_env_report_value,
|
||||
msg_c_offload_signaled1,
|
||||
msg_c_offload_signaled2,
|
||||
msg_c_myowrapper_checkresult,
|
||||
msg_c_myotarget_checkresult,
|
||||
msg_c_offload_descriptor_offload,
|
||||
msg_c_merge_var_descs1,
|
||||
msg_c_merge_var_descs2,
|
||||
msg_c_mic_parse_env_var_list1,
|
||||
msg_c_mic_parse_env_var_list2,
|
||||
msg_c_mic_process_exit_ret,
|
||||
msg_c_mic_process_exit_sig,
|
||||
msg_c_mic_process_exit,
|
||||
msg_c_mic_init3,
|
||||
msg_c_mic_init4,
|
||||
msg_c_mic_init5,
|
||||
msg_c_mic_init6,
|
||||
msg_c_no_static_var_data,
|
||||
msg_c_no_ptr_data,
|
||||
msg_c_get_engine_handle,
|
||||
msg_c_get_engine_index,
|
||||
msg_c_process_create,
|
||||
msg_c_process_get_func_handles,
|
||||
msg_c_process_wait_shutdown,
|
||||
msg_c_process_proxy_flush,
|
||||
msg_c_load_library,
|
||||
msg_c_pipeline_create,
|
||||
msg_c_pipeline_run_func,
|
||||
msg_c_pipeline_start_run_funcs,
|
||||
msg_c_buf_create,
|
||||
msg_c_buf_create_out_of_mem,
|
||||
msg_c_buf_create_from_mem,
|
||||
msg_c_buf_destroy,
|
||||
msg_c_buf_map,
|
||||
msg_c_buf_unmap,
|
||||
msg_c_buf_read,
|
||||
msg_c_buf_write,
|
||||
msg_c_buf_copy,
|
||||
msg_c_buf_get_address,
|
||||
msg_c_buf_add_ref,
|
||||
msg_c_buf_release_ref,
|
||||
msg_c_buf_set_state,
|
||||
msg_c_event_wait,
|
||||
msg_c_zero_or_neg_ptr_len,
|
||||
msg_c_zero_or_neg_transfer_size,
|
||||
msg_c_bad_ptr_mem_range,
|
||||
msg_c_different_src_and_dstn_sizes,
|
||||
msg_c_non_contiguous_dope_vector,
|
||||
msg_c_omp_invalid_device_num_env,
|
||||
msg_c_omp_invalid_device_num,
|
||||
msg_c_unknown_binary_type,
|
||||
msg_c_multiple_target_exes,
|
||||
msg_c_no_target_exe,
|
||||
msg_c_report_unknown_timer_node,
|
||||
msg_c_report_unknown_trace_node,
|
||||
msg_c_report_host,
|
||||
msg_c_report_mic,
|
||||
msg_c_report_title,
|
||||
msg_c_report_seconds,
|
||||
msg_c_report_bytes,
|
||||
msg_c_report_cpu_time,
|
||||
msg_c_report_mic_time,
|
||||
msg_c_report_tag,
|
||||
msg_c_report_from_file,
|
||||
msg_c_report_file,
|
||||
msg_c_report_line,
|
||||
msg_c_report_cpu_to_mic_data,
|
||||
msg_c_report_mic_to_cpu_data,
|
||||
msg_c_report_offload,
|
||||
msg_c_report_w_tag,
|
||||
msg_c_report_state,
|
||||
msg_c_report_start,
|
||||
msg_c_report_init,
|
||||
msg_c_report_logical_card,
|
||||
msg_c_report_physical_card,
|
||||
msg_c_report_register,
|
||||
msg_c_report_init_func,
|
||||
msg_c_report_create_buf_host,
|
||||
msg_c_report_create_buf_mic,
|
||||
msg_c_report_send_pointer_data,
|
||||
msg_c_report_sent_pointer_data,
|
||||
msg_c_report_gather_copyin_data,
|
||||
msg_c_report_copyin_data,
|
||||
msg_c_report_state_signal,
|
||||
msg_c_report_signal,
|
||||
msg_c_report_wait,
|
||||
msg_c_report_compute,
|
||||
msg_c_report_receive_pointer_data,
|
||||
msg_c_report_received_pointer_data,
|
||||
msg_c_report_start_target_func,
|
||||
msg_c_report_var,
|
||||
msg_c_report_scatter_copyin_data,
|
||||
msg_c_report_gather_copyout_data,
|
||||
msg_c_report_scatter_copyout_data,
|
||||
msg_c_report_copyout_data,
|
||||
msg_c_report_unregister,
|
||||
msg_c_report_destroy,
|
||||
msg_c_report_myoinit,
|
||||
msg_c_report_myoregister,
|
||||
msg_c_report_myofini,
|
||||
msg_c_report_mic_myo_shared,
|
||||
msg_c_report_mic_myo_fptr,
|
||||
msg_c_report_myosharedmalloc,
|
||||
msg_c_report_myosharedfree,
|
||||
msg_c_report_myosharedalignedmalloc,
|
||||
msg_c_report_myosharedalignedfree,
|
||||
msg_c_report_myoacquire,
|
||||
msg_c_report_myorelease,
|
||||
msg_c_report_host_total_offload_time,
|
||||
msg_c_report_host_initialize,
|
||||
msg_c_report_host_target_acquire,
|
||||
msg_c_report_host_wait_deps,
|
||||
msg_c_report_host_setup_buffers,
|
||||
msg_c_report_host_alloc_buffers,
|
||||
msg_c_report_host_setup_misc_data,
|
||||
msg_c_report_host_alloc_data_buffer,
|
||||
msg_c_report_host_send_pointers,
|
||||
msg_c_report_host_gather_inputs,
|
||||
msg_c_report_host_map_in_data_buffer,
|
||||
msg_c_report_host_unmap_in_data_buffer,
|
||||
msg_c_report_host_start_compute,
|
||||
msg_c_report_host_wait_compute,
|
||||
msg_c_report_host_start_buffers_reads,
|
||||
msg_c_report_host_scatter_outputs,
|
||||
msg_c_report_host_map_out_data_buffer,
|
||||
msg_c_report_host_unmap_out_data_buffer,
|
||||
msg_c_report_host_wait_buffers_reads,
|
||||
msg_c_report_host_destroy_buffers,
|
||||
msg_c_report_target_total_time,
|
||||
msg_c_report_target_descriptor_setup,
|
||||
msg_c_report_target_func_lookup,
|
||||
msg_c_report_target_func_time,
|
||||
msg_c_report_target_scatter_inputs,
|
||||
msg_c_report_target_add_buffer_refs,
|
||||
msg_c_report_target_compute,
|
||||
msg_c_report_target_gather_outputs,
|
||||
msg_c_report_target_release_buffer_refs,
|
||||
msg_c_coi_pipeline_max_number,
|
||||
msg_c_ranges_dont_match,
|
||||
msg_c_destination_is_over,
|
||||
msg_c_slice_of_noncont_array,
|
||||
msg_c_pointer_array_mismatch,
|
||||
lastMsg = 152,
|
||||
firstMsg = 1
|
||||
};
|
||||
|
||||
|
||||
#if !defined(MESSAGE_TABLE_NAME)
|
||||
# define MESSAGE_TABLE_NAME __liboffload_message_table
|
||||
#endif
|
||||
|
||||
static char const * MESSAGE_TABLE_NAME[] = {
|
||||
/* 0 __dummy__ */ "Un-used message",
|
||||
/* 1 msg_c_device_is_not_available */ "offload error: cannot offload to MIC - device is not available",
|
||||
/* 2 msg_c_invalid_device_number */ "offload error: expected a number greater than or equal to -1",
|
||||
/* 3 msg_c_send_func_ptr */ "offload error: cannot find function name for address %p",
|
||||
/* 4 msg_c_receive_func_ptr */ "offload error: cannot find address of function %s",
|
||||
/* 5 msg_c_offload_malloc */ "offload error: memory allocation failed (requested=%lld bytes, align %lld)",
|
||||
/* 6 msg_c_offload1 */ "offload error: device %d does not have a pending signal for wait(%p)",
|
||||
/* 7 msg_c_unknown_var_type */ "offload error: unknown variable type %d",
|
||||
/* 8 msg_c_invalid_env_var_value */ "offload warning: ignoring invalid value specified for %s",
|
||||
/* 9 msg_c_invalid_env_var_int_value */ "offload warning: specify an integer value for %s",
|
||||
/* 10 msg_c_invalid_env_report_value */ "offload warning: ignoring %s setting; use a value in range 1-3",
|
||||
/* 11 msg_c_offload_signaled1 */ "offload error: invalid device number %d specified in _Offload_signaled",
|
||||
/* 12 msg_c_offload_signaled2 */ "offload error: invalid signal %p specified for _Offload_signaled",
|
||||
/* 13 msg_c_myowrapper_checkresult */ "offload error: %s failed with error %d",
|
||||
/* 14 msg_c_myotarget_checkresult */ "offload error: %s failed with error %d",
|
||||
/* 15 msg_c_offload_descriptor_offload */ "offload error: cannot find offload entry %s",
|
||||
/* 16 msg_c_merge_var_descs1 */ "offload error: unexpected number of variable descriptors",
|
||||
/* 17 msg_c_merge_var_descs2 */ "offload error: unexpected variable type",
|
||||
/* 18 msg_c_mic_parse_env_var_list1 */ "offload_error: MIC environment variable must begin with an alpabetic character",
|
||||
/* 19 msg_c_mic_parse_env_var_list2 */ "offload_error: MIC environment variable value must be specified with ‘=’",
|
||||
/* 20 msg_c_mic_process_exit_ret */ "offload error: process on the device %d unexpectedly exited with code %d",
|
||||
/* 21 msg_c_mic_process_exit_sig */ "offload error: process on the device %d was terminated by signal %d (%s)",
|
||||
/* 22 msg_c_mic_process_exit */ "offload error: process on the device %d was unexpectedly terminated",
|
||||
/* 23 msg_c_mic_init3 */ "offload warning: ignoring MIC_STACKSIZE setting; use a value >= 16K and a multiple of 4K",
|
||||
/* 24 msg_c_mic_init4 */ "offload error: thread key create failed with error %d",
|
||||
/* 25 msg_c_mic_init5 */ "offload warning: specify OFFLOAD_DEVICES as comma-separated physical device numbers or 'none'",
|
||||
/* 26 msg_c_mic_init6 */ "offload warning: OFFLOAD_DEVICES device number %d does not correspond to a physical device",
|
||||
/* 27 msg_c_no_static_var_data */ "offload error: cannot find data associated with statically allocated variable %p",
|
||||
/* 28 msg_c_no_ptr_data */ "offload error: cannot find data associated with pointer variable %p",
|
||||
/* 29 msg_c_get_engine_handle */ "offload error: cannot get device %d handle (error code %d)",
|
||||
/* 30 msg_c_get_engine_index */ "offload error: cannot get physical index for logical device %d (error code %d)",
|
||||
/* 31 msg_c_process_create */ "offload error: cannot start process on the device %d (error code %d)",
|
||||
/* 32 msg_c_process_get_func_handles */ "offload error: cannot get function handles on the device %d (error code %d)",
|
||||
/* 33 msg_c_process_wait_shutdown */ "offload error: wait for process shutdown failed on device %d (error code %d)",
|
||||
/* 34 msg_c_process_proxy_flush */ "offload error: cannot flush process output on device %d (error code %d)",
|
||||
/* 35 msg_c_load_library */ "offload error: cannot load library to the device %d (error code %d)",
|
||||
/* 36 msg_c_pipeline_create */ "offload error: cannot create pipeline on the device %d (error code %d)",
|
||||
/* 37 msg_c_pipeline_run_func */ "offload error: cannot execute function on the device %d (error code %d)",
|
||||
/* 38 msg_c_pipeline_start_run_funcs */ "offload error: cannot start executing pipeline function on the device %d (error code %d)",
|
||||
/* 39 msg_c_buf_create */ "offload error: cannot create buffer on device %d (error code %d)",
|
||||
/* 40 msg_c_buf_create_out_of_mem */ "offload error: cannot create buffer on device %d, out of memory",
|
||||
/* 41 msg_c_buf_create_from_mem */ "offload error: cannot create buffer from memory on device %d (error code %d)",
|
||||
/* 42 msg_c_buf_destroy */ "offload error: buffer destroy failed (error code %d)",
|
||||
/* 43 msg_c_buf_map */ "offload error: buffer map failed (error code %d)",
|
||||
/* 44 msg_c_buf_unmap */ "offload error: buffer unmap failed (error code %d)",
|
||||
/* 45 msg_c_buf_read */ "offload error: buffer read failed (error code %d)",
|
||||
/* 46 msg_c_buf_write */ "offload error: buffer write failed (error code %d)",
|
||||
/* 47 msg_c_buf_copy */ "offload error: buffer copy failed (error code %d)",
|
||||
/* 48 msg_c_buf_get_address */ "offload error: cannot get buffer address on device %d (error code %d)",
|
||||
/* 49 msg_c_buf_add_ref */ "offload error: cannot reuse buffer memory on device %d (error code %d)",
|
||||
/* 50 msg_c_buf_release_ref */ "offload error: cannot release buffer memory on device %d (error code %d)",
|
||||
/* 51 msg_c_buf_set_state */ "offload error: buffer set state failed (error code %d)",
|
||||
/* 52 msg_c_event_wait */ "offload error: wait for event to become signaled failed (error code %d)",
|
||||
/* 53 msg_c_zero_or_neg_ptr_len */ "offload error: memory allocation of negative length is not supported",
|
||||
/* 54 msg_c_zero_or_neg_transfer_size */ "offload error: data transfer of zero or negative size is not supported",
|
||||
/* 55 msg_c_bad_ptr_mem_range */ "offload error: address range partially overlaps with existing allocation",
|
||||
/* 56 msg_c_different_src_and_dstn_sizes */ "offload error: size of the source %d differs from size of the destination %d",
|
||||
/* 57 msg_c_non_contiguous_dope_vector */ "offload error: offload data transfer supports only a single contiguous memory range per variable",
|
||||
/* 58 msg_c_omp_invalid_device_num_env */ "offload warning: ignoring %s setting; use a non-negative integer value",
|
||||
/* 59 msg_c_omp_invalid_device_num */ "offload error: device number should be a non-negative integer value",
|
||||
/* 60 msg_c_unknown_binary_type */ "offload error: unexpected embedded target binary type, expected either an executable or shared library",
|
||||
/* 61 msg_c_multiple_target_exes */ "offload error: more that one target executable found",
|
||||
/* 62 msg_c_no_target_exe */ "offload error: target executable is not available",
|
||||
/* 63 msg_c_report_unknown_timer_node */ "offload error: unknown timer node",
|
||||
/* 64 msg_c_report_unknown_trace_node */ "offload error: unknown trace node",
|
||||
/* 65 msg_c_report_host */ "HOST",
|
||||
/* 66 msg_c_report_mic */ "MIC",
|
||||
/* 67 msg_c_report_title */ "timer data (sec)",
|
||||
/* 68 msg_c_report_seconds */ "(seconds)",
|
||||
/* 69 msg_c_report_bytes */ "(bytes)",
|
||||
/* 70 msg_c_report_cpu_time */ "CPU Time",
|
||||
/* 71 msg_c_report_mic_time */ "MIC Time",
|
||||
/* 72 msg_c_report_tag */ "Tag",
|
||||
/* 73 msg_c_report_from_file */ "Offload from file",
|
||||
/* 74 msg_c_report_file */ "File",
|
||||
/* 75 msg_c_report_line */ "Line",
|
||||
/* 76 msg_c_report_cpu_to_mic_data */ "CPU->MIC Data",
|
||||
/* 77 msg_c_report_mic_to_cpu_data */ "MIC->CPU Data",
|
||||
/* 78 msg_c_report_offload */ "Offload",
|
||||
/* 79 msg_c_report_w_tag */ "Tag %d",
|
||||
/* 80 msg_c_report_state */ "State",
|
||||
/* 81 msg_c_report_start */ "Start target",
|
||||
/* 82 msg_c_report_init */ "Initialize",
|
||||
/* 83 msg_c_report_logical_card */ "logical card",
|
||||
/* 84 msg_c_report_physical_card */ "physical card",
|
||||
/* 85 msg_c_report_register */ "Register static data tables",
|
||||
/* 86 msg_c_report_init_func */ "Setup target entry",
|
||||
/* 87 msg_c_report_create_buf_host */ "Create host buffer",
|
||||
/* 88 msg_c_report_create_buf_mic */ "Create target buffer",
|
||||
/* 89 msg_c_report_send_pointer_data */ "Send pointer data",
|
||||
/* 90 msg_c_report_sent_pointer_data */ "Host->target pointer data",
|
||||
/* 91 msg_c_report_gather_copyin_data */ "Gather copyin data",
|
||||
/* 92 msg_c_report_copyin_data */ "Host->target copyin data",
|
||||
/* 93 msg_c_report_state_signal */ "Signal",
|
||||
/* 94 msg_c_report_signal */ "signal :",
|
||||
/* 95 msg_c_report_wait */ "waits :",
|
||||
/* 96 msg_c_report_compute */ "Execute task on target",
|
||||
/* 97 msg_c_report_receive_pointer_data */ "Receive pointer data",
|
||||
/* 98 msg_c_report_received_pointer_data */ "Target->host pointer data",
|
||||
/* 99 msg_c_report_start_target_func */ "Start target entry",
|
||||
/* 100 msg_c_report_var */ "Var",
|
||||
/* 101 msg_c_report_scatter_copyin_data */ "Scatter copyin data",
|
||||
/* 102 msg_c_report_gather_copyout_data */ "Gather copyout data",
|
||||
/* 103 msg_c_report_scatter_copyout_data */ "Scatter copyout data",
|
||||
/* 104 msg_c_report_copyout_data */ "Target->host copyout data",
|
||||
/* 105 msg_c_report_unregister */ "Unregister data tables",
|
||||
/* 106 msg_c_report_destroy */ "Destroy",
|
||||
/* 107 msg_c_report_myoinit */ "Initialize MYO",
|
||||
/* 108 msg_c_report_myoregister */ "Register MYO tables",
|
||||
/* 109 msg_c_report_myofini */ "Finalize MYO",
|
||||
/* 110 msg_c_report_mic_myo_shared */ "MIC MYO shared table register",
|
||||
/* 111 msg_c_report_mic_myo_fptr */ "MIC MYO fptr table register",
|
||||
/* 112 msg_c_report_myosharedmalloc */ "MYO shared malloc",
|
||||
/* 113 msg_c_report_myosharedfree */ "MYO shared free",
|
||||
/* 114 msg_c_report_myosharedalignedmalloc */ "MYO shared aligned malloc",
|
||||
/* 115 msg_c_report_myosharedalignedfree */ "MYO shared aligned free",
|
||||
/* 116 msg_c_report_myoacquire */ "MYO acquire",
|
||||
/* 117 msg_c_report_myorelease */ "MYO release",
|
||||
/* 118 msg_c_report_host_total_offload_time */ "host: total offload time",
|
||||
/* 119 msg_c_report_host_initialize */ "host: initialize target",
|
||||
/* 120 msg_c_report_host_target_acquire */ "host: acquire target",
|
||||
/* 121 msg_c_report_host_wait_deps */ "host: wait dependencies",
|
||||
/* 122 msg_c_report_host_setup_buffers */ "host: setup buffers",
|
||||
/* 123 msg_c_report_host_alloc_buffers */ "host: allocate buffers",
|
||||
/* 124 msg_c_report_host_setup_misc_data */ "host: setup misc_data",
|
||||
/* 125 msg_c_report_host_alloc_data_buffer */ "host: allocate buffer",
|
||||
/* 126 msg_c_report_host_send_pointers */ "host: send pointers",
|
||||
/* 127 msg_c_report_host_gather_inputs */ "host: gather inputs",
|
||||
/* 128 msg_c_report_host_map_in_data_buffer */ "host: map IN data buffer",
|
||||
/* 129 msg_c_report_host_unmap_in_data_buffer */ "host: unmap IN data buffer",
|
||||
/* 130 msg_c_report_host_start_compute */ "host: initiate compute",
|
||||
/* 131 msg_c_report_host_wait_compute */ "host: wait compute",
|
||||
/* 132 msg_c_report_host_start_buffers_reads */ "host: initiate pointer reads",
|
||||
/* 133 msg_c_report_host_scatter_outputs */ "host: scatter outputs",
|
||||
/* 134 msg_c_report_host_map_out_data_buffer */ "host: map OUT data buffer",
|
||||
/* 135 msg_c_report_host_unmap_out_data_buffer */ "host: unmap OUT data buffer",
|
||||
/* 136 msg_c_report_host_wait_buffers_reads */ "host: wait pointer reads",
|
||||
/* 137 msg_c_report_host_destroy_buffers */ "host: destroy buffers",
|
||||
/* 138 msg_c_report_target_total_time */ "target: total time",
|
||||
/* 139 msg_c_report_target_descriptor_setup */ "target: setup offload descriptor",
|
||||
/* 140 msg_c_report_target_func_lookup */ "target: entry lookup",
|
||||
/* 141 msg_c_report_target_func_time */ "target: entry time",
|
||||
/* 142 msg_c_report_target_scatter_inputs */ "target: scatter inputs",
|
||||
/* 143 msg_c_report_target_add_buffer_refs */ "target: add buffer reference",
|
||||
/* 144 msg_c_report_target_compute */ "target: compute",
|
||||
/* 145 msg_c_report_target_gather_outputs */ "target: gather outputs",
|
||||
/* 146 msg_c_report_target_release_buffer_refs */ "target: remove buffer reference",
|
||||
/* 147 msg_c_coi_pipeline_max_number */ "number of host threads doing offload exceeds maximum of %d",
|
||||
/* 148 msg_c_ranges_dont_match */ "ranges of source and destination don't match together",
|
||||
/* 149 msg_c_destination_is_over */ "insufficient destination memory to transfer source",
|
||||
/* 150 msg_c_slice_of_noncont_array */ "a non-contiguous slice may be taken of contiguous arrays only",
|
||||
/* 151 msg_c_pointer_array_mismatch */ "number of %s elements is less than described by the source",
|
||||
};
|
||||
@@ -0,0 +1,441 @@
|
||||
!
|
||||
!//===----------------------------------------------------------------------===//
|
||||
!//
|
||||
!// 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 is intended to support the Intel(r) Many Integrated Core Architecture.
|
||||
! **********************************************************************************
|
||||
! free form Fortran source - should be named .f90
|
||||
! lines are longer than 72 characters
|
||||
|
||||
module mic_lib
|
||||
use, intrinsic :: iso_c_binding
|
||||
|
||||
integer, parameter:: target_mic=2
|
||||
integer, parameter:: default_target_type=target_mic
|
||||
integer, parameter:: default_target_number=0
|
||||
|
||||
enum, bind(C)
|
||||
enumerator :: OFFLOAD_SUCCESS = 0
|
||||
enumerator :: OFFLOAD_DISABLED ! offload is disabled
|
||||
enumerator :: OFFLOAD_UNAVAILABLE ! card is not available
|
||||
enumerator :: OFFLOAD_OUT_OF_MEMORY ! not enough memory on device
|
||||
enumerator :: OFFLOAD_PROCESS_DIED ! target process has died
|
||||
enumerator :: OFFLOAD_ERROR ! unspecified error
|
||||
end enum
|
||||
|
||||
type, bind (C) :: offload_status
|
||||
integer(kind=c_int) :: result = OFFLOAD_DISABLED
|
||||
integer(kind=c_int) :: device_number = -1
|
||||
integer(kind=c_size_t) :: data_sent = 0
|
||||
integer(kind=c_size_t) :: data_received = 0
|
||||
end type offload_status
|
||||
|
||||
interface
|
||||
function offload_number_of_devices () &
|
||||
bind (C, name = "_Offload_number_of_devices")
|
||||
!dec$ attributes default :: offload_number_of_devices
|
||||
import :: c_int
|
||||
integer (kind=c_int) :: offload_number_of_devices
|
||||
!dec$ attributes offload:mic :: offload_number_of_devices
|
||||
!dir$ attributes known_intrinsic :: offload_number_of_devices
|
||||
end function offload_number_of_devices
|
||||
|
||||
function offload_signaled(target_number, signal) &
|
||||
bind (C, name = "_Offload_signaled")
|
||||
!dec$ attributes default :: offload_signaled
|
||||
import :: c_int, c_int64_t
|
||||
integer (kind=c_int) :: offload_signaled
|
||||
integer (kind=c_int), value :: target_number
|
||||
integer (kind=c_int64_t), value :: signal
|
||||
!dec$ attributes offload:mic :: offload_signaled
|
||||
end function offload_signaled
|
||||
|
||||
subroutine offload_report(val) &
|
||||
bind (C, name = "_Offload_report")
|
||||
!dec$ attributes default :: offload_report
|
||||
import :: c_int
|
||||
integer (kind=c_int), value :: val
|
||||
!dec$ attributes offload:mic :: offload_report
|
||||
end subroutine offload_report
|
||||
|
||||
function offload_get_device_number() &
|
||||
bind (C, name = "_Offload_get_device_number")
|
||||
!dec$ attributes default :: offload_get_device_number
|
||||
import :: c_int
|
||||
integer (kind=c_int) :: offload_get_device_number
|
||||
!dec$ attributes offload:mic :: offload_get_device_number
|
||||
end function offload_get_device_number
|
||||
|
||||
function offload_get_physical_device_number() &
|
||||
bind (C, name = "_Offload_get_physical_device_number")
|
||||
!dec$ attributes default :: offload_get_physical_device_number
|
||||
import :: c_int
|
||||
integer (kind=c_int) :: offload_get_physical_device_number
|
||||
!dec$ attributes offload:mic :: offload_get_physical_device_number
|
||||
end function offload_get_physical_device_number
|
||||
|
||||
! OpenMP API wrappers
|
||||
|
||||
subroutine omp_set_num_threads_target (target_type, &
|
||||
target_number, &
|
||||
num_threads) &
|
||||
bind (C, name = "omp_set_num_threads_target")
|
||||
import :: c_int
|
||||
integer (kind=c_int), value :: target_type, target_number, num_threads
|
||||
end subroutine omp_set_num_threads_target
|
||||
|
||||
function omp_get_max_threads_target (target_type, &
|
||||
target_number) &
|
||||
bind (C, name = "omp_get_max_threads_target")
|
||||
import :: c_int
|
||||
integer (kind=c_int) :: omp_get_max_threads_target
|
||||
integer (kind=c_int), value :: target_type, target_number
|
||||
end function omp_get_max_threads_target
|
||||
|
||||
function omp_get_num_procs_target (target_type, &
|
||||
target_number) &
|
||||
bind (C, name = "omp_get_num_procs_target")
|
||||
import :: c_int
|
||||
integer (kind=c_int) :: omp_get_num_procs_target
|
||||
integer (kind=c_int), value :: target_type, target_number
|
||||
end function omp_get_num_procs_target
|
||||
|
||||
subroutine omp_set_dynamic_target (target_type, &
|
||||
target_number, &
|
||||
num_threads) &
|
||||
bind (C, name = "omp_set_dynamic_target")
|
||||
import :: c_int
|
||||
integer (kind=c_int), value :: target_type, target_number, num_threads
|
||||
end subroutine omp_set_dynamic_target
|
||||
|
||||
function omp_get_dynamic_target (target_type, &
|
||||
target_number) &
|
||||
bind (C, name = "omp_get_dynamic_target")
|
||||
import :: c_int
|
||||
integer (kind=c_int) :: omp_get_dynamic_target
|
||||
integer (kind=c_int), value :: target_type, target_number
|
||||
end function omp_get_dynamic_target
|
||||
|
||||
subroutine omp_set_nested_target (target_type, &
|
||||
target_number, &
|
||||
nested) &
|
||||
bind (C, name = "omp_set_nested_target")
|
||||
import :: c_int
|
||||
integer (kind=c_int), value :: target_type, target_number, nested
|
||||
end subroutine omp_set_nested_target
|
||||
|
||||
function omp_get_nested_target (target_type, &
|
||||
target_number) &
|
||||
bind (C, name = "omp_get_nested_target")
|
||||
import :: c_int
|
||||
integer (kind=c_int) :: omp_get_nested_target
|
||||
integer (kind=c_int), value :: target_type, target_number
|
||||
end function omp_get_nested_target
|
||||
|
||||
subroutine omp_set_schedule_target (target_type, &
|
||||
target_number, &
|
||||
kind, &
|
||||
modifier) &
|
||||
bind (C, name = "omp_set_schedule_target")
|
||||
import :: c_int
|
||||
integer (kind=c_int), value :: target_type, target_number, kind, modifier
|
||||
end subroutine omp_set_schedule_target
|
||||
|
||||
subroutine omp_get_schedule_target (target_type, &
|
||||
target_number, &
|
||||
kind, &
|
||||
modifier) &
|
||||
bind (C, name = "omp_get_schedule_target")
|
||||
import :: c_int, c_intptr_t
|
||||
integer (kind=c_int), value :: target_type, target_number
|
||||
integer (kind=c_intptr_t), value :: kind, modifier
|
||||
end subroutine omp_get_schedule_target
|
||||
|
||||
! lock API functions
|
||||
|
||||
subroutine omp_init_lock_target (target_type, &
|
||||
target_number, &
|
||||
lock) &
|
||||
bind (C, name = "omp_init_lock_target")
|
||||
import :: c_int, c_intptr_t
|
||||
!dir$ attributes known_intrinsic :: omp_init_lock_target
|
||||
integer (kind=c_int), value :: target_type, target_number
|
||||
integer (kind=c_intptr_t), value :: lock
|
||||
end subroutine omp_init_lock_target
|
||||
|
||||
subroutine omp_destroy_lock_target (target_type, &
|
||||
target_number, &
|
||||
lock) &
|
||||
bind (C, name = "omp_destroy_lock_target")
|
||||
import :: c_int, c_intptr_t
|
||||
!dir$ attributes known_intrinsic :: omp_destroy_lock_target
|
||||
integer (kind=c_int), value :: target_type, target_number
|
||||
integer (kind=c_intptr_t), value :: lock
|
||||
end subroutine omp_destroy_lock_target
|
||||
|
||||
subroutine omp_set_lock_target (target_type, &
|
||||
target_number, &
|
||||
lock) &
|
||||
bind (C, name = "omp_set_lock_target")
|
||||
import :: c_int, c_intptr_t
|
||||
!dir$ attributes known_intrinsic :: omp_set_lock_target
|
||||
integer (kind=c_int), value :: target_type, target_number
|
||||
integer (kind=c_intptr_t), value :: lock
|
||||
end subroutine omp_set_lock_target
|
||||
|
||||
subroutine omp_unset_lock_target (target_type, &
|
||||
target_number, &
|
||||
lock) &
|
||||
bind (C, name = "omp_unset_lock_target")
|
||||
import :: c_int, c_intptr_t
|
||||
!dir$ attributes known_intrinsic :: omp_unset_lock_target
|
||||
integer (kind=c_int), value :: target_type, target_number
|
||||
integer (kind=c_intptr_t), value :: lock
|
||||
end subroutine omp_unset_lock_target
|
||||
|
||||
function omp_test_lock_target (target_type, &
|
||||
target_number, &
|
||||
lock) &
|
||||
bind (C, name = "omp_test_lock_target")
|
||||
import :: c_int, c_intptr_t
|
||||
integer (kind=c_int) :: omp_test_lock_target
|
||||
integer (kind=c_int), value :: target_type, target_number
|
||||
integer (kind=c_intptr_t), value :: lock
|
||||
end function omp_test_lock_target
|
||||
|
||||
! nested lock API functions
|
||||
|
||||
subroutine omp_init_nest_lock_target (target_type, &
|
||||
target_number, &
|
||||
lock) &
|
||||
bind (C, name = "omp_init_nest_lock_target")
|
||||
import :: c_int, c_intptr_t
|
||||
integer (kind=c_int), value :: target_type, target_number
|
||||
integer (kind=c_intptr_t), value :: lock
|
||||
end subroutine omp_init_nest_lock_target
|
||||
|
||||
subroutine omp_destroy_nest_lock_target (target_type, &
|
||||
target_number, &
|
||||
lock) &
|
||||
bind (C, name = "omp_destroy_nest_lock_target")
|
||||
import :: c_int, c_intptr_t
|
||||
integer (kind=c_int), value :: target_type, target_number
|
||||
integer (kind=c_intptr_t), value :: lock
|
||||
end subroutine omp_destroy_nest_lock_target
|
||||
|
||||
subroutine omp_set_nest_lock_target (target_type, &
|
||||
target_number, &
|
||||
lock) &
|
||||
bind (C, name = "omp_set_nest_lock_target")
|
||||
import :: c_int, c_intptr_t
|
||||
integer (kind=c_int), value :: target_type, target_number
|
||||
integer (kind=c_intptr_t), value :: lock
|
||||
end subroutine omp_set_nest_lock_target
|
||||
|
||||
subroutine omp_unset_nest_lock_target (target_type, &
|
||||
target_number, &
|
||||
lock) &
|
||||
bind (C, name = "omp_unset_nest_lock_target")
|
||||
import :: c_int, c_intptr_t
|
||||
integer (kind=c_int), value :: target_type, target_number
|
||||
integer (kind=c_intptr_t), value :: lock
|
||||
end subroutine omp_unset_nest_lock_target
|
||||
|
||||
function omp_test_nest_lock_target (target_type, &
|
||||
target_number, &
|
||||
lock) &
|
||||
bind (C, name = "omp_test_nest_lock_target")
|
||||
import :: c_int, c_intptr_t
|
||||
integer (kind=c_int) :: omp_test_nest_lock_target
|
||||
integer (kind=c_int), value :: target_type, target_number
|
||||
integer (kind=c_intptr_t), value :: lock
|
||||
end function omp_test_nest_lock_target
|
||||
|
||||
! kmp API functions
|
||||
|
||||
subroutine kmp_set_stacksize_target (target_type, &
|
||||
target_number, &
|
||||
size) &
|
||||
bind (C, name = "kmp_set_stacksize_target")
|
||||
import :: c_int
|
||||
integer (kind=c_int), value :: target_type, target_number, size
|
||||
end subroutine kmp_set_stacksize_target
|
||||
|
||||
function kmp_get_stacksize_target (target_type, &
|
||||
target_number) &
|
||||
bind (C, name = "kmp_get_stacksize_target")
|
||||
import :: c_int
|
||||
integer (kind=c_int) :: kmp_get_stacksize_target
|
||||
integer (kind=c_int), value :: target_type, target_number
|
||||
end function kmp_get_stacksize_target
|
||||
|
||||
subroutine kmp_set_stacksize_s_target (target_type, &
|
||||
target_number, &
|
||||
size) &
|
||||
bind (C, name = "kmp_set_stacksize_s_target")
|
||||
import :: c_int
|
||||
integer (kind=c_int), value :: target_type, target_number, size
|
||||
end subroutine kmp_set_stacksize_s_target
|
||||
|
||||
function kmp_get_stacksize_s_target (target_type, &
|
||||
target_number) &
|
||||
bind (C, name = "kmp_get_stacksize_s_target")
|
||||
import :: c_int
|
||||
integer (kind=c_int) :: kmp_get_stacksize_s_target
|
||||
integer (kind=c_int), value :: target_type, target_number
|
||||
end function kmp_get_stacksize_s_target
|
||||
|
||||
subroutine kmp_set_blocktime_target (target_type, &
|
||||
target_number, &
|
||||
time) &
|
||||
bind (C, name = "kmp_set_blocktime_target")
|
||||
import :: c_int
|
||||
integer (kind=c_int), value :: target_type, target_number, time
|
||||
end subroutine kmp_set_blocktime_target
|
||||
|
||||
function kmp_get_blocktime_target (target_type, &
|
||||
target_number) &
|
||||
bind (C, name = "kmp_get_blocktime_target")
|
||||
import :: c_int
|
||||
integer (kind=c_int) :: kmp_get_blocktime_target
|
||||
integer (kind=c_int), value :: target_type, target_number
|
||||
end function kmp_get_blocktime_target
|
||||
|
||||
subroutine kmp_set_library_serial_target (target_type, &
|
||||
target_number) &
|
||||
bind (C, name = "kmp_set_library_serial_target")
|
||||
import :: c_int
|
||||
integer (kind=c_int), value :: target_type, target_number
|
||||
end subroutine kmp_set_library_serial_target
|
||||
|
||||
subroutine kmp_set_library_turnaround_target (target_type, &
|
||||
target_number) &
|
||||
bind (C, name = "kmp_set_library_turnaround_target")
|
||||
import :: c_int
|
||||
integer (kind=c_int), value :: target_type, target_number
|
||||
end subroutine kmp_set_library_turnaround_target
|
||||
|
||||
subroutine kmp_set_library_throughput_target (target_type, &
|
||||
target_number) &
|
||||
bind (C, name = "kmp_set_library_throughput_target")
|
||||
import :: c_int
|
||||
integer (kind=c_int), value :: target_type, target_number
|
||||
end subroutine kmp_set_library_throughput_target
|
||||
|
||||
subroutine kmp_set_library_target (target_type, &
|
||||
target_number, &
|
||||
mode) &
|
||||
bind (C, name = "kmp_set_library_target")
|
||||
import :: c_int
|
||||
integer (kind=c_int), value :: target_type, target_number, mode
|
||||
end subroutine kmp_set_library_target
|
||||
|
||||
function kmp_get_library_target (target_type, &
|
||||
target_number) &
|
||||
bind (C, name = "kmp_get_library_target")
|
||||
import :: c_int
|
||||
integer (kind=c_int) :: kmp_get_library_target
|
||||
integer (kind=c_int), value :: target_type, target_number
|
||||
end function kmp_get_library_target
|
||||
|
||||
subroutine kmp_set_defaults_target (target_type, &
|
||||
target_number, &
|
||||
defaults) &
|
||||
bind (C, name = "kmp_set_defaults_target")
|
||||
import :: c_int, c_char
|
||||
character (kind=c_char) :: defaults(*)
|
||||
integer (kind=c_int), value :: target_type, target_number
|
||||
end subroutine kmp_set_defaults_target
|
||||
|
||||
! affinity API functions
|
||||
|
||||
subroutine kmp_create_affinity_mask_target (target_type, &
|
||||
target_number, &
|
||||
mask) &
|
||||
bind (C, name = "kmp_create_affinity_mask_target")
|
||||
import :: c_int, c_intptr_t
|
||||
integer (kind=c_int), value :: target_type, target_number
|
||||
integer (kind=c_intptr_t), value :: mask
|
||||
end subroutine kmp_create_affinity_mask_target
|
||||
|
||||
subroutine kmp_destroy_affinity_mask_target (target_type, &
|
||||
target_number, &
|
||||
mask) &
|
||||
bind (C, name = "kmp_destroy_affinity_mask_target")
|
||||
import :: c_int, c_intptr_t
|
||||
integer (kind=c_int), value :: target_type, target_number
|
||||
integer (kind=c_intptr_t), value :: mask
|
||||
end subroutine kmp_destroy_affinity_mask_target
|
||||
|
||||
function kmp_set_affinity_target (target_type, &
|
||||
target_number, &
|
||||
mask) &
|
||||
bind (C, name = "kmp_set_affinity_target")
|
||||
import :: c_int, c_intptr_t
|
||||
integer (kind=c_int) :: kmp_set_affinity_target
|
||||
integer (kind=c_int), value :: target_type, target_number
|
||||
integer (kind=c_intptr_t), value :: mask
|
||||
end function kmp_set_affinity_target
|
||||
|
||||
function kmp_get_affinity_target (target_type, &
|
||||
target_number, &
|
||||
mask) &
|
||||
bind (C, name = "kmp_get_affinity_target")
|
||||
import :: c_int, c_intptr_t
|
||||
integer (kind=c_int) :: kmp_get_affinity_target
|
||||
integer (kind=c_int), value :: target_type, target_number
|
||||
integer (kind=c_intptr_t), value :: mask
|
||||
end function kmp_get_affinity_target
|
||||
|
||||
function kmp_get_affinity_max_proc_target (target_type, &
|
||||
target_number) &
|
||||
bind (C, name = "kmp_get_affinity_max_proc_target")
|
||||
import :: c_int
|
||||
integer (kind=c_int) :: kmp_get_affinity_max_proc_target
|
||||
integer (kind=c_int), value :: target_type, target_number
|
||||
end function kmp_get_affinity_max_proc_target
|
||||
|
||||
function kmp_set_affinity_mask_proc_target (target_type, &
|
||||
target_number, &
|
||||
proc, &
|
||||
mask) &
|
||||
bind (C, name = "kmp_set_affinity_mask_proc_target")
|
||||
import :: c_int, c_intptr_t
|
||||
integer (kind=c_int) :: kmp_set_affinity_mask_proc_target
|
||||
integer (kind=c_int), value :: target_type, target_number, proc
|
||||
integer (kind=c_intptr_t), value :: mask
|
||||
end function kmp_set_affinity_mask_proc_target
|
||||
|
||||
function kmp_unset_affinity_mask_proc_target (target_type, &
|
||||
target_number, &
|
||||
proc, &
|
||||
mask) &
|
||||
bind (C, name = "kmp_unset_affinity_mask_proc_target")
|
||||
import :: c_int, c_intptr_t
|
||||
integer (kind=c_int) :: kmp_unset_affinity_mask_proc_target
|
||||
integer (kind=c_int), value :: target_type, target_number, proc
|
||||
integer (kind=c_intptr_t), value :: mask
|
||||
end function kmp_unset_affinity_mask_proc_target
|
||||
|
||||
function kmp_get_affinity_mask_proc_target (target_type, &
|
||||
target_number, &
|
||||
proc, &
|
||||
mask) &
|
||||
bind (C, name = "kmp_get_affinity_mask_proc_target")
|
||||
import :: c_int, c_intptr_t
|
||||
integer (kind=c_int) :: kmp_get_affinity_mask_proc_target
|
||||
integer (kind=c_int), value :: target_type, target_number, proc
|
||||
integer (kind=c_intptr_t), value :: mask
|
||||
end function kmp_get_affinity_mask_proc_target
|
||||
|
||||
end interface
|
||||
end module mic_lib
|
||||
@@ -0,0 +1,474 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 file for Offload API.
|
||||
*/
|
||||
|
||||
#ifndef OFFLOAD_H_INCLUDED
|
||||
#define OFFLOAD_H_INCLUDED
|
||||
|
||||
#if defined(LINUX) || defined(FREEBSD)
|
||||
#include <bits/functexcept.h>
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <omp.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define TARGET_ATTRIBUTE __declspec(target(mic))
|
||||
|
||||
/*
|
||||
* The target architecture.
|
||||
*/
|
||||
typedef enum TARGET_TYPE {
|
||||
TARGET_NONE, /* Undefine target */
|
||||
TARGET_HOST, /* Host used as target */
|
||||
TARGET_MIC /* MIC target */
|
||||
} TARGET_TYPE;
|
||||
|
||||
/*
|
||||
* The default target type.
|
||||
*/
|
||||
#define DEFAULT_TARGET_TYPE TARGET_MIC
|
||||
|
||||
/*
|
||||
* The default target number.
|
||||
*/
|
||||
#define DEFAULT_TARGET_NUMBER 0
|
||||
|
||||
/*
|
||||
* Offload status.
|
||||
*/
|
||||
typedef enum {
|
||||
OFFLOAD_SUCCESS = 0,
|
||||
OFFLOAD_DISABLED, /* offload is disabled */
|
||||
OFFLOAD_UNAVAILABLE, /* card is not available */
|
||||
OFFLOAD_OUT_OF_MEMORY, /* not enough memory on device */
|
||||
OFFLOAD_PROCESS_DIED, /* target process has died */
|
||||
OFFLOAD_ERROR /* unspecified error */
|
||||
} _Offload_result;
|
||||
|
||||
typedef struct {
|
||||
_Offload_result result; /* result, see above */
|
||||
int device_number; /* device number */
|
||||
size_t data_sent; /* number of bytes sent to the target */
|
||||
size_t data_received; /* number of bytes received by host */
|
||||
} _Offload_status;
|
||||
|
||||
#define OFFLOAD_STATUS_INIT(x) \
|
||||
((x).result = OFFLOAD_DISABLED)
|
||||
|
||||
#define OFFLOAD_STATUS_INITIALIZER \
|
||||
{ OFFLOAD_DISABLED, -1, 0, 0 }
|
||||
|
||||
/* Offload runtime interfaces */
|
||||
|
||||
extern int _Offload_number_of_devices(void);
|
||||
extern int _Offload_get_device_number(void);
|
||||
extern int _Offload_get_physical_device_number(void);
|
||||
|
||||
extern void* _Offload_shared_malloc(size_t size);
|
||||
extern void _Offload_shared_free(void *ptr);
|
||||
|
||||
extern void* _Offload_shared_aligned_malloc(size_t size, size_t align);
|
||||
extern void _Offload_shared_aligned_free(void *ptr);
|
||||
|
||||
extern int _Offload_signaled(int index, void *signal);
|
||||
extern void _Offload_report(int val);
|
||||
|
||||
/* OpenMP API */
|
||||
|
||||
extern void omp_set_default_device(int num);
|
||||
extern int omp_get_default_device(void);
|
||||
extern int omp_get_num_devices(void);
|
||||
|
||||
/* OpenMP API wrappers */
|
||||
|
||||
/* Set num_threads on target */
|
||||
extern void omp_set_num_threads_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
int num_threads
|
||||
);
|
||||
|
||||
/* Get max_threads from target */
|
||||
extern int omp_get_max_threads_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number
|
||||
);
|
||||
|
||||
/* Get num_procs from target */
|
||||
extern int omp_get_num_procs_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number
|
||||
);
|
||||
|
||||
/* Set dynamic on target */
|
||||
extern void omp_set_dynamic_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
int num_threads
|
||||
);
|
||||
|
||||
/* Get dynamic from target */
|
||||
extern int omp_get_dynamic_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number
|
||||
);
|
||||
|
||||
/* Set nested on target */
|
||||
extern void omp_set_nested_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
int nested
|
||||
);
|
||||
|
||||
/* Get nested from target */
|
||||
extern int omp_get_nested_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number
|
||||
);
|
||||
|
||||
extern void omp_set_num_threads_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
int num_threads
|
||||
);
|
||||
|
||||
extern int omp_get_max_threads_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number
|
||||
);
|
||||
|
||||
extern int omp_get_num_procs_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number
|
||||
);
|
||||
|
||||
extern void omp_set_dynamic_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
int num_threads
|
||||
);
|
||||
|
||||
extern int omp_get_dynamic_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number
|
||||
);
|
||||
|
||||
extern void omp_set_nested_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
int num_threads
|
||||
);
|
||||
|
||||
extern int omp_get_nested_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number
|
||||
);
|
||||
|
||||
extern void omp_set_schedule_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
omp_sched_t kind,
|
||||
int modifier
|
||||
);
|
||||
|
||||
extern void omp_get_schedule_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
omp_sched_t *kind,
|
||||
int *modifier
|
||||
);
|
||||
|
||||
/* lock API functions */
|
||||
|
||||
typedef struct {
|
||||
omp_lock_t lock;
|
||||
} omp_lock_target_t;
|
||||
|
||||
extern void omp_init_lock_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
omp_lock_target_t *lock
|
||||
);
|
||||
|
||||
extern void omp_destroy_lock_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
omp_lock_target_t *lock
|
||||
);
|
||||
|
||||
extern void omp_set_lock_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
omp_lock_target_t *lock
|
||||
);
|
||||
|
||||
extern void omp_unset_lock_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
omp_lock_target_t *lock
|
||||
);
|
||||
|
||||
extern int omp_test_lock_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
omp_lock_target_t *lock
|
||||
);
|
||||
|
||||
/* nested lock API functions */
|
||||
|
||||
typedef struct {
|
||||
omp_nest_lock_t lock;
|
||||
} omp_nest_lock_target_t;
|
||||
|
||||
extern void omp_init_nest_lock_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
omp_nest_lock_target_t *lock
|
||||
);
|
||||
|
||||
extern void omp_destroy_nest_lock_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
omp_nest_lock_target_t *lock
|
||||
);
|
||||
|
||||
extern void omp_set_nest_lock_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
omp_nest_lock_target_t *lock
|
||||
);
|
||||
|
||||
extern void omp_unset_nest_lock_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
omp_nest_lock_target_t *lock
|
||||
);
|
||||
|
||||
extern int omp_test_nest_lock_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
omp_nest_lock_target_t *lock
|
||||
);
|
||||
|
||||
/* kmp API functions */
|
||||
|
||||
extern void kmp_set_stacksize_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
int size
|
||||
);
|
||||
|
||||
extern int kmp_get_stacksize_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number
|
||||
);
|
||||
|
||||
extern void kmp_set_stacksize_s_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
size_t size
|
||||
);
|
||||
|
||||
extern size_t kmp_get_stacksize_s_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number
|
||||
);
|
||||
|
||||
extern void kmp_set_blocktime_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
int time
|
||||
);
|
||||
|
||||
extern int kmp_get_blocktime_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number
|
||||
);
|
||||
|
||||
extern void kmp_set_library_serial_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number
|
||||
);
|
||||
|
||||
extern void kmp_set_library_turnaround_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number
|
||||
);
|
||||
|
||||
extern void kmp_set_library_throughput_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number
|
||||
);
|
||||
|
||||
extern void kmp_set_library_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
int mode
|
||||
);
|
||||
|
||||
extern int kmp_get_library_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number
|
||||
);
|
||||
|
||||
extern void kmp_set_defaults_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
char const *defaults
|
||||
);
|
||||
|
||||
/* affinity API functions */
|
||||
|
||||
typedef struct {
|
||||
kmp_affinity_mask_t mask;
|
||||
} kmp_affinity_mask_target_t;
|
||||
|
||||
extern void kmp_create_affinity_mask_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
kmp_affinity_mask_target_t *mask
|
||||
);
|
||||
|
||||
extern void kmp_destroy_affinity_mask_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
kmp_affinity_mask_target_t *mask
|
||||
);
|
||||
|
||||
extern int kmp_set_affinity_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
kmp_affinity_mask_target_t *mask
|
||||
);
|
||||
|
||||
extern int kmp_get_affinity_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
kmp_affinity_mask_target_t *mask
|
||||
);
|
||||
|
||||
extern int kmp_get_affinity_max_proc_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number
|
||||
);
|
||||
|
||||
extern int kmp_set_affinity_mask_proc_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
int proc,
|
||||
kmp_affinity_mask_target_t *mask
|
||||
);
|
||||
|
||||
extern int kmp_unset_affinity_mask_proc_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
int proc,
|
||||
kmp_affinity_mask_target_t *mask
|
||||
);
|
||||
|
||||
extern int kmp_get_affinity_mask_proc_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
int proc,
|
||||
kmp_affinity_mask_target_t *mask
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
||||
/* Namespace for the shared_allocator. */
|
||||
namespace __offload {
|
||||
/* This follows the specification for std::allocator. */
|
||||
/* Forward declaration of the class template. */
|
||||
template <typename T>
|
||||
class shared_allocator;
|
||||
|
||||
/* Specialization for shared_allocator<void>. */
|
||||
template <>
|
||||
class shared_allocator<void> {
|
||||
public:
|
||||
typedef void *pointer;
|
||||
typedef const void *const_pointer;
|
||||
typedef void value_type;
|
||||
template <class U> struct rebind { typedef shared_allocator<U> other; };
|
||||
};
|
||||
|
||||
/* Definition of shared_allocator<T>. */
|
||||
template <class T>
|
||||
class shared_allocator {
|
||||
public:
|
||||
typedef size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
typedef T *pointer;
|
||||
typedef const T *const_pointer;
|
||||
typedef T &reference;
|
||||
typedef const T &const_reference;
|
||||
typedef T value_type;
|
||||
template <class U> struct rebind { typedef shared_allocator<U> other; };
|
||||
shared_allocator() throw() { }
|
||||
shared_allocator(const shared_allocator&) throw() { }
|
||||
template <class U> shared_allocator(const shared_allocator<U>&) throw() { }
|
||||
~shared_allocator() throw() { }
|
||||
pointer address(reference x) const { return &x; }
|
||||
const_pointer address(const_reference x) const { return &x; }
|
||||
pointer allocate(
|
||||
size_type, shared_allocator<void>::const_pointer hint = 0);
|
||||
void deallocate(pointer p, size_type n);
|
||||
size_type max_size() const throw() {
|
||||
return size_type(-1)/sizeof(T);
|
||||
} /* max_size */
|
||||
void construct(pointer p, const T& arg) {
|
||||
::new (p) T(arg);
|
||||
} /* construct */
|
||||
void destroy(pointer p) {
|
||||
p->~T();
|
||||
} /* destroy */
|
||||
};
|
||||
|
||||
/* Definition for allocate. */
|
||||
template <class T>
|
||||
typename shared_allocator<T>::pointer
|
||||
shared_allocator<T>::allocate(shared_allocator<T>::size_type s,
|
||||
shared_allocator<void>::const_pointer) {
|
||||
/* Allocate from shared memory. */
|
||||
void *ptr = _Offload_shared_malloc(s*sizeof(T));
|
||||
if (ptr == 0) std::__throw_bad_alloc();
|
||||
return static_cast<pointer>(ptr);
|
||||
} /* allocate */
|
||||
|
||||
template <class T>
|
||||
void shared_allocator<T>::deallocate(pointer p,
|
||||
shared_allocator<T>::size_type) {
|
||||
/* Free the shared memory. */
|
||||
_Offload_shared_free(p);
|
||||
} /* deallocate */
|
||||
|
||||
template <typename _T1, typename _T2>
|
||||
inline bool operator==(const shared_allocator<_T1> &,
|
||||
const shared_allocator<_T2> &) throw() {
|
||||
return true;
|
||||
} /* operator== */
|
||||
|
||||
template <typename _T1, typename _T2>
|
||||
inline bool operator!=(const shared_allocator<_T1> &,
|
||||
const shared_allocator<_T2> &) throw() {
|
||||
return false;
|
||||
} /* operator!= */
|
||||
} /* __offload */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* OFFLOAD_H_INCLUDED */
|
||||
@@ -0,0 +1,170 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
#if defined(LINUX) || defined(FREEBSD)
|
||||
#include <mm_malloc.h>
|
||||
#endif
|
||||
|
||||
#include "offload_common.h"
|
||||
|
||||
// The debug routines
|
||||
|
||||
#if OFFLOAD_DEBUG > 0
|
||||
|
||||
void __dump_bytes(
|
||||
int trace_level,
|
||||
const void *data,
|
||||
int len
|
||||
)
|
||||
{
|
||||
if (console_enabled > trace_level) {
|
||||
const uint8_t *arr = (const uint8_t*) data;
|
||||
char buffer[4096];
|
||||
char *bufferp;
|
||||
int count = 0;
|
||||
|
||||
bufferp = buffer;
|
||||
while (len--) {
|
||||
sprintf(bufferp, "%02x", *arr++);
|
||||
bufferp += 2;
|
||||
count++;
|
||||
if ((count&3) == 0) {
|
||||
sprintf(bufferp, " ");
|
||||
bufferp++;
|
||||
}
|
||||
if ((count&63) == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(trace_level, "%s\n", buffer);
|
||||
bufferp = buffer;
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
if (count) {
|
||||
OFFLOAD_DEBUG_TRACE(trace_level, "%s\n", buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // OFFLOAD_DEBUG
|
||||
|
||||
// The Marshaller and associated routines
|
||||
|
||||
void Marshaller::send_data(
|
||||
const void *data,
|
||||
int64_t length
|
||||
)
|
||||
{
|
||||
OFFLOAD_DEBUG_TRACE(2, "send_data(%p, %lld)\n",
|
||||
data, length);
|
||||
memcpy(buffer_ptr, data, (size_t)length);
|
||||
buffer_ptr += length;
|
||||
tfr_size += length;
|
||||
}
|
||||
|
||||
void Marshaller::receive_data(
|
||||
void *data,
|
||||
int64_t length
|
||||
)
|
||||
{
|
||||
OFFLOAD_DEBUG_TRACE(2, "receive_data(%p, %lld)\n",
|
||||
data, length);
|
||||
memcpy(data, buffer_ptr, (size_t)length);
|
||||
buffer_ptr += length;
|
||||
tfr_size += length;
|
||||
}
|
||||
|
||||
// Send function pointer
|
||||
void Marshaller::send_func_ptr(
|
||||
const void* data
|
||||
)
|
||||
{
|
||||
const char* name;
|
||||
size_t length;
|
||||
|
||||
if (data != 0) {
|
||||
name = __offload_funcs.find_name(data);
|
||||
if (name == 0) {
|
||||
#if OFFLOAD_DEBUG > 0
|
||||
if (console_enabled > 2) {
|
||||
__offload_funcs.dump();
|
||||
}
|
||||
#endif // OFFLOAD_DEBUG > 0
|
||||
|
||||
LIBOFFLOAD_ERROR(c_send_func_ptr, data);
|
||||
exit(1);
|
||||
}
|
||||
length = strlen(name) + 1;
|
||||
}
|
||||
else {
|
||||
name = "";
|
||||
length = 1;
|
||||
}
|
||||
|
||||
memcpy(buffer_ptr, name, length);
|
||||
buffer_ptr += length;
|
||||
tfr_size += length;
|
||||
}
|
||||
|
||||
// Receive function pointer
|
||||
void Marshaller::receive_func_ptr(
|
||||
const void** data
|
||||
)
|
||||
{
|
||||
const char* name;
|
||||
size_t length;
|
||||
|
||||
name = (const char*) buffer_ptr;
|
||||
if (name[0] != '\0') {
|
||||
*data = __offload_funcs.find_addr(name);
|
||||
if (*data == 0) {
|
||||
#if OFFLOAD_DEBUG > 0
|
||||
if (console_enabled > 2) {
|
||||
__offload_funcs.dump();
|
||||
}
|
||||
#endif // OFFLOAD_DEBUG > 0
|
||||
|
||||
LIBOFFLOAD_ERROR(c_receive_func_ptr, name);
|
||||
exit(1);
|
||||
}
|
||||
length = strlen(name) + 1;
|
||||
}
|
||||
else {
|
||||
*data = 0;
|
||||
length = 1;
|
||||
}
|
||||
|
||||
buffer_ptr += length;
|
||||
tfr_size += length;
|
||||
}
|
||||
|
||||
// End of the Marshaller and associated routines
|
||||
|
||||
extern void *OFFLOAD_MALLOC(
|
||||
size_t size,
|
||||
size_t align
|
||||
)
|
||||
{
|
||||
void *ptr;
|
||||
int err;
|
||||
|
||||
OFFLOAD_DEBUG_TRACE(2, "%s(%lld, %lld)\n", __func__, size, align);
|
||||
|
||||
if (align < sizeof(void*)) {
|
||||
align = sizeof(void*);
|
||||
}
|
||||
|
||||
ptr = _mm_malloc(size, align);
|
||||
if (ptr == NULL) {
|
||||
LIBOFFLOAD_ERROR(c_offload_malloc, size, align);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
OFFLOAD_DEBUG_TRACE(2, "%s returned %p\n", __func__, ptr);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
@@ -0,0 +1,444 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
/*! \file
|
||||
\brief The parts of the runtime library common to host and target
|
||||
*/
|
||||
|
||||
#ifndef OFFLOAD_COMMON_H_INCLUDED
|
||||
#define OFFLOAD_COMMON_H_INCLUDED
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <memory.h>
|
||||
|
||||
#include "offload.h"
|
||||
#include "offload_table.h"
|
||||
#include "offload_trace.h"
|
||||
#include "offload_timer.h"
|
||||
#include "offload_util.h"
|
||||
#include "cean_util.h"
|
||||
#include "dv_util.h"
|
||||
#include "liboffload_error_codes.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
// The debug routines
|
||||
|
||||
// Host console and file logging
|
||||
extern int console_enabled;
|
||||
extern int offload_report_level;
|
||||
|
||||
#define OFFLOAD_DO_TRACE (offload_report_level == 3)
|
||||
|
||||
extern const char *prefix;
|
||||
extern int offload_number;
|
||||
#if !HOST_LIBRARY
|
||||
extern int mic_index;
|
||||
#endif
|
||||
|
||||
#if HOST_LIBRARY
|
||||
void Offload_Report_Prolog(OffloadHostTimerData* timer_data);
|
||||
void Offload_Report_Epilog(OffloadHostTimerData* timer_data);
|
||||
void offload_report_free_data(OffloadHostTimerData * timer_data);
|
||||
void Offload_Timer_Print(void);
|
||||
|
||||
#ifndef TARGET_WINNT
|
||||
#define OFFLOAD_DEBUG_INCR_OFLD_NUM() \
|
||||
__sync_add_and_fetch(&offload_number, 1)
|
||||
#else
|
||||
#define OFFLOAD_DEBUG_INCR_OFLD_NUM() \
|
||||
_InterlockedIncrement(reinterpret_cast<long*>(&offload_number))
|
||||
#endif
|
||||
|
||||
#define OFFLOAD_DEBUG_PRINT_TAG_PREFIX() \
|
||||
printf("%s: ", prefix);
|
||||
|
||||
#define OFFLOAD_DEBUG_PRINT_PREFIX() \
|
||||
printf("%s: ", prefix);
|
||||
#else
|
||||
#define OFFLOAD_DEBUG_PRINT_PREFIX() \
|
||||
printf("%s%d: ", prefix, mic_index);
|
||||
#endif // HOST_LIBRARY
|
||||
|
||||
#define OFFLOAD_TRACE(trace_level, ...) \
|
||||
if (console_enabled >= trace_level) { \
|
||||
OFFLOAD_DEBUG_PRINT_PREFIX(); \
|
||||
printf(__VA_ARGS__); \
|
||||
fflush(NULL); \
|
||||
}
|
||||
|
||||
#if OFFLOAD_DEBUG > 0
|
||||
|
||||
#define OFFLOAD_DEBUG_TRACE(level, ...) \
|
||||
OFFLOAD_TRACE(level, __VA_ARGS__)
|
||||
|
||||
#define OFFLOAD_REPORT(level, offload_number, stage, ...) \
|
||||
if (OFFLOAD_DO_TRACE) { \
|
||||
offload_stage_print(stage, offload_number, __VA_ARGS__); \
|
||||
fflush(NULL); \
|
||||
}
|
||||
|
||||
#define OFFLOAD_DEBUG_TRACE_1(level, offload_number, stage, ...) \
|
||||
if (OFFLOAD_DO_TRACE) { \
|
||||
offload_stage_print(stage, offload_number, __VA_ARGS__); \
|
||||
fflush(NULL); \
|
||||
} \
|
||||
if (!OFFLOAD_DO_TRACE) { \
|
||||
OFFLOAD_TRACE(level, __VA_ARGS__) \
|
||||
}
|
||||
|
||||
#define OFFLOAD_DEBUG_DUMP_BYTES(level, a, b) \
|
||||
__dump_bytes(level, a, b)
|
||||
|
||||
extern void __dump_bytes(
|
||||
int level,
|
||||
const void *data,
|
||||
int len
|
||||
);
|
||||
|
||||
#else
|
||||
|
||||
#define OFFLOAD_DEBUG_LOG(level, ...)
|
||||
#define OFFLOAD_DEBUG_DUMP_BYTES(level, a, b)
|
||||
|
||||
#endif
|
||||
|
||||
// Runtime interface
|
||||
|
||||
#define OFFLOAD_PREFIX(a) __offload_##a
|
||||
|
||||
#define OFFLOAD_MALLOC OFFLOAD_PREFIX(malloc)
|
||||
#define OFFLOAD_FREE(a) _mm_free(a)
|
||||
|
||||
// Forward functions
|
||||
|
||||
extern void *OFFLOAD_MALLOC(size_t size, size_t align);
|
||||
|
||||
// The Marshaller
|
||||
|
||||
//! \enum Indicator for the type of entry on an offload item list.
|
||||
enum OffloadItemType {
|
||||
c_data = 1, //!< Plain data
|
||||
c_data_ptr, //!< Pointer data
|
||||
c_func_ptr, //!< Function pointer
|
||||
c_void_ptr, //!< void*
|
||||
c_string_ptr, //!< C string
|
||||
c_dv, //!< Dope vector variable
|
||||
c_dv_data, //!< Dope-vector data
|
||||
c_dv_data_slice, //!< Dope-vector data's slice
|
||||
c_dv_ptr, //!< Dope-vector variable pointer
|
||||
c_dv_ptr_data, //!< Dope-vector pointer data
|
||||
c_dv_ptr_data_slice,//!< Dope-vector pointer data's slice
|
||||
c_cean_var, //!< CEAN variable
|
||||
c_cean_var_ptr, //!< Pointer to CEAN variable
|
||||
c_data_ptr_array, //!< Pointer to data pointer array
|
||||
c_func_ptr_array, //!< Pointer to function pointer array
|
||||
c_void_ptr_array, //!< Pointer to void* pointer array
|
||||
c_string_ptr_array //!< Pointer to char* pointer array
|
||||
};
|
||||
|
||||
#define VAR_TYPE_IS_PTR(t) ((t) == c_string_ptr || \
|
||||
(t) == c_data_ptr || \
|
||||
(t) == c_cean_var_ptr || \
|
||||
(t) == c_dv_ptr)
|
||||
|
||||
#define VAR_TYPE_IS_SCALAR(t) ((t) == c_data || \
|
||||
(t) == c_void_ptr || \
|
||||
(t) == c_cean_var || \
|
||||
(t) == c_dv)
|
||||
|
||||
#define VAR_TYPE_IS_DV_DATA(t) ((t) == c_dv_data || \
|
||||
(t) == c_dv_ptr_data)
|
||||
|
||||
#define VAR_TYPE_IS_DV_DATA_SLICE(t) ((t) == c_dv_data_slice || \
|
||||
(t) == c_dv_ptr_data_slice)
|
||||
|
||||
|
||||
//! \enum Specify direction to copy offloaded variable.
|
||||
enum OffloadParameterType {
|
||||
c_parameter_unknown = -1, //!< Unknown clause
|
||||
c_parameter_nocopy, //!< Variable listed in "nocopy" clause
|
||||
c_parameter_in, //!< Variable listed in "in" clause
|
||||
c_parameter_out, //!< Variable listed in "out" clause
|
||||
c_parameter_inout //!< Variable listed in "inout" clause
|
||||
};
|
||||
|
||||
//! An Offload Variable descriptor
|
||||
struct VarDesc {
|
||||
//! OffloadItemTypes of source and destination
|
||||
union {
|
||||
struct {
|
||||
uint8_t dst : 4; //!< OffloadItemType of destination
|
||||
uint8_t src : 4; //!< OffloadItemType of source
|
||||
};
|
||||
uint8_t bits;
|
||||
} type;
|
||||
|
||||
//! OffloadParameterType that describes direction of data transfer
|
||||
union {
|
||||
struct {
|
||||
uint8_t in : 1; //!< Set if IN or INOUT
|
||||
uint8_t out : 1; //!< Set if OUT or INOUT
|
||||
};
|
||||
uint8_t bits;
|
||||
} direction;
|
||||
|
||||
uint8_t alloc_if; //!< alloc_if modifier value
|
||||
uint8_t free_if; //!< free_if modifier value
|
||||
uint32_t align; //!< MIC alignment requested for pointer data
|
||||
//! Not used by compiler; set to 0
|
||||
/*! Used by runtime as offset to data from start of MIC buffer */
|
||||
uint32_t mic_offset;
|
||||
//! Flags describing this variable
|
||||
union {
|
||||
struct {
|
||||
//! source variable has persistent storage
|
||||
uint32_t is_static : 1;
|
||||
//! destination variable has persistent storage
|
||||
uint32_t is_static_dstn : 1;
|
||||
//! has length for c_dv && c_dv_ptr
|
||||
uint32_t has_length : 1;
|
||||
//! persisted local scalar is in stack buffer
|
||||
uint32_t is_stack_buf : 1;
|
||||
//! buffer address is sent in data
|
||||
uint32_t sink_addr : 1;
|
||||
//! alloc displacement is sent in data
|
||||
uint32_t alloc_disp : 1;
|
||||
//! source data is noncontiguous
|
||||
uint32_t is_noncont_src : 1;
|
||||
//! destination data is noncontiguous
|
||||
uint32_t is_noncont_dst : 1;
|
||||
};
|
||||
uint32_t bits;
|
||||
} flags;
|
||||
//! Not used by compiler; set to 0
|
||||
/*! Used by runtime as offset to base from data stored in a buffer */
|
||||
int64_t offset;
|
||||
//! Element byte-size of data to be transferred
|
||||
/*! For dope-vector, the size of the dope-vector */
|
||||
int64_t size;
|
||||
union {
|
||||
//! Set to 0 for array expressions and dope-vectors
|
||||
/*! Set to 1 for scalars */
|
||||
/*! Set to value of length modifier for pointers */
|
||||
int64_t count;
|
||||
//! Displacement not used by compiler
|
||||
int64_t disp;
|
||||
};
|
||||
|
||||
//! This field not used by OpenMP 4.0
|
||||
/*! The alloc section expression in #pragma offload */
|
||||
union {
|
||||
void *alloc;
|
||||
int64_t ptr_arr_offset;
|
||||
};
|
||||
|
||||
//! This field not used by OpenMP 4.0
|
||||
/*! The into section expression in #pragma offload */
|
||||
/*! For c_data_ptr_array this is the into ptr array */
|
||||
void *into;
|
||||
|
||||
//! For an ordinary variable, address of the variable
|
||||
/*! For c_cean_var (C/C++ array expression),
|
||||
pointer to arr_desc, which is an array descriptor. */
|
||||
/*! For c_data_ptr_array (array of data pointers),
|
||||
pointer to ptr_array_descriptor,
|
||||
which is a descriptor for pointer array transfers. */
|
||||
void *ptr;
|
||||
};
|
||||
|
||||
//! Auxiliary struct used when -g is enabled that holds variable names
|
||||
struct VarDesc2 {
|
||||
const char *sname; //!< Source name
|
||||
const char *dname; //!< Destination name (when "into" is used)
|
||||
};
|
||||
|
||||
/*! When the OffloadItemType is c_data_ptr_array
|
||||
the ptr field of the main descriptor points to this struct. */
|
||||
/*! The type in VarDesc1 merely says c_cean_data_ptr, but the pointer
|
||||
type can be c_data_ptr, c_func_ptr, c_void_ptr, or c_string_ptr.
|
||||
Therefore the actual pointer type is in the flags field of VarDesc3. */
|
||||
/*! If flag_align_is_array/flag_alloc_if_is_array/flag_free_if_is_array
|
||||
is 0 then alignment/alloc_if/free_if are specified in VarDesc1. */
|
||||
/*! If flag_align_is_array/flag_alloc_if_is_array/flag_free_if_is_array
|
||||
is 1 then align_array/alloc_if_array/free_if_array specify
|
||||
the set of alignment/alloc_if/free_if values. */
|
||||
/*! For the other fields, if neither the scalar nor the array flag
|
||||
is set, then that modifier was not specified. If the bits are set
|
||||
they specify which modifier was set and whether it was a
|
||||
scalar or an array expression. */
|
||||
struct VarDesc3
|
||||
{
|
||||
void *ptr_array; //!< Pointer to arr_desc of array of pointers
|
||||
void *align_array; //!< Scalar value or pointer to arr_desc
|
||||
void *alloc_if_array; //!< Scalar value or pointer to arr_desc
|
||||
void *free_if_array; //!< Scalar value or pointer to arr_desc
|
||||
void *extent_start; //!< Scalar value or pointer to arr_desc
|
||||
void *extent_elements; //!< Scalar value or pointer to arr_desc
|
||||
void *into_start; //!< Scalar value or pointer to arr_desc
|
||||
void *into_elements; //!< Scalar value or pointer to arr_desc
|
||||
void *alloc_start; //!< Scalar value or pointer to arr_desc
|
||||
void *alloc_elements; //!< Scalar value or pointer to arr_desc
|
||||
/*! Flags that describe the pointer type and whether each field
|
||||
is a scalar value or an array expression. */
|
||||
/*! First 6 bits are pointer array element type:
|
||||
c_data_ptr, c_func_ptr, c_void_ptr, c_string_ptr */
|
||||
/*! Then single bits specify: */
|
||||
/*! align_array is an array */
|
||||
/*! alloc_if_array is an array */
|
||||
/*! free_if_array is an array */
|
||||
/*! extent_start is a scalar expression */
|
||||
/*! extent_start is an array expression */
|
||||
/*! extent_elements is a scalar expression */
|
||||
/*! extent_elements is an array expression */
|
||||
/*! into_start is a scalar expression */
|
||||
/*! into_start is an array expression */
|
||||
/*! into_elements is a scalar expression */
|
||||
/*! into_elements is an array expression */
|
||||
/*! alloc_start is a scalar expression */
|
||||
/*! alloc_start is an array expression */
|
||||
/*! alloc_elements is a scalar expression */
|
||||
/*! alloc_elements is an array expression */
|
||||
uint32_t array_fields;
|
||||
};
|
||||
const int flag_align_is_array = 6;
|
||||
const int flag_alloc_if_is_array = 7;
|
||||
const int flag_free_if_is_array = 8;
|
||||
const int flag_extent_start_is_scalar = 9;
|
||||
const int flag_extent_start_is_array = 10;
|
||||
const int flag_extent_elements_is_scalar = 11;
|
||||
const int flag_extent_elements_is_array = 12;
|
||||
const int flag_into_start_is_scalar = 13;
|
||||
const int flag_into_start_is_array = 14;
|
||||
const int flag_into_elements_is_scalar = 15;
|
||||
const int flag_into_elements_is_array = 16;
|
||||
const int flag_alloc_start_is_scalar = 17;
|
||||
const int flag_alloc_start_is_array = 18;
|
||||
const int flag_alloc_elements_is_scalar = 19;
|
||||
const int flag_alloc_elements_is_array = 20;
|
||||
|
||||
// The Marshaller
|
||||
class Marshaller
|
||||
{
|
||||
private:
|
||||
// Start address of buffer
|
||||
char *buffer_start;
|
||||
|
||||
// Current pointer within buffer
|
||||
char *buffer_ptr;
|
||||
|
||||
// Physical size of data sent (including flags)
|
||||
long long buffer_size;
|
||||
|
||||
// User data sent/received
|
||||
long long tfr_size;
|
||||
|
||||
public:
|
||||
// Constructor
|
||||
Marshaller() :
|
||||
buffer_start(0), buffer_ptr(0),
|
||||
buffer_size(0), tfr_size(0)
|
||||
{
|
||||
}
|
||||
|
||||
// Return count of user data sent/received
|
||||
long long get_tfr_size() const
|
||||
{
|
||||
return tfr_size;
|
||||
}
|
||||
|
||||
// Return pointer to buffer
|
||||
char *get_buffer_start() const
|
||||
{
|
||||
return buffer_start;
|
||||
}
|
||||
|
||||
// Return current size of data in buffer
|
||||
long long get_buffer_size() const
|
||||
{
|
||||
return buffer_size;
|
||||
}
|
||||
|
||||
// Set buffer pointer
|
||||
void init_buffer(
|
||||
char *d,
|
||||
long long s
|
||||
)
|
||||
{
|
||||
buffer_start = buffer_ptr = d;
|
||||
buffer_size = s;
|
||||
}
|
||||
|
||||
// Send data
|
||||
void send_data(
|
||||
const void *data,
|
||||
int64_t length
|
||||
);
|
||||
|
||||
// Receive data
|
||||
void receive_data(
|
||||
void *data,
|
||||
int64_t length
|
||||
);
|
||||
|
||||
// Send function pointer
|
||||
void send_func_ptr(
|
||||
const void* data
|
||||
);
|
||||
|
||||
// Receive function pointer
|
||||
void receive_func_ptr(
|
||||
const void** data
|
||||
);
|
||||
};
|
||||
|
||||
// End of the Marshaller
|
||||
|
||||
// The offloaded function descriptor.
|
||||
// Sent from host to target to specify which function to run.
|
||||
// Also, sets console and file tracing levels.
|
||||
struct FunctionDescriptor
|
||||
{
|
||||
// Input data size.
|
||||
long long in_datalen;
|
||||
|
||||
// Output data size.
|
||||
long long out_datalen;
|
||||
|
||||
// Whether trace is requested on console.
|
||||
// A value of 1 produces only function name and data sent/received.
|
||||
// Values > 1 produce copious trace information.
|
||||
uint8_t console_enabled;
|
||||
|
||||
// Flag controlling timing on the target side.
|
||||
// Values > 0 enable timing on sink.
|
||||
uint8_t timer_enabled;
|
||||
|
||||
int offload_report_level;
|
||||
int offload_number;
|
||||
|
||||
// number of variable descriptors
|
||||
int vars_num;
|
||||
|
||||
// inout data offset if data is passed as misc/return data
|
||||
// otherwise it should be zero.
|
||||
int data_offset;
|
||||
|
||||
// The name of the offloaded function
|
||||
char data[];
|
||||
};
|
||||
|
||||
// typedef OFFLOAD.
|
||||
// Pointer to OffloadDescriptor.
|
||||
typedef struct OffloadDescriptor *OFFLOAD;
|
||||
|
||||
#endif // OFFLOAD_COMMON_H_INCLUDED
|
||||
@@ -0,0 +1,531 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 "offload_engine.h"
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#include "offload_host.h"
|
||||
#include "offload_table.h"
|
||||
|
||||
const char* Engine::m_func_names[Engine::c_funcs_total] =
|
||||
{
|
||||
"server_compute",
|
||||
#ifdef MYO_SUPPORT
|
||||
"server_myoinit",
|
||||
"server_myofini",
|
||||
#endif // MYO_SUPPORT
|
||||
"server_init",
|
||||
"server_var_table_size",
|
||||
"server_var_table_copy"
|
||||
};
|
||||
|
||||
// Symbolic representation of system signals. Fix for CQ233593
|
||||
const char* Engine::c_signal_names[Engine::c_signal_max] =
|
||||
{
|
||||
"Unknown SIGNAL",
|
||||
"SIGHUP", /* 1, Hangup (POSIX). */
|
||||
"SIGINT", /* 2, Interrupt (ANSI). */
|
||||
"SIGQUIT", /* 3, Quit (POSIX). */
|
||||
"SIGILL", /* 4, Illegal instruction (ANSI). */
|
||||
"SIGTRAP", /* 5, Trace trap (POSIX). */
|
||||
"SIGABRT", /* 6, Abort (ANSI). */
|
||||
"SIGBUS", /* 7, BUS error (4.2 BSD). */
|
||||
"SIGFPE", /* 8, Floating-point exception (ANSI). */
|
||||
"SIGKILL", /* 9, Kill, unblockable (POSIX). */
|
||||
"SIGUSR1", /* 10, User-defined signal 1 (POSIX). */
|
||||
"SIGSEGV", /* 11, Segmentation violation (ANSI). */
|
||||
"SIGUSR2", /* 12, User-defined signal 2 (POSIX). */
|
||||
"SIGPIPE", /* 13, Broken pipe (POSIX). */
|
||||
"SIGALRM", /* 14, Alarm clock (POSIX). */
|
||||
"SIGTERM", /* 15, Termination (ANSI). */
|
||||
"SIGSTKFLT", /* 16, Stack fault. */
|
||||
"SIGCHLD", /* 17, Child status has changed (POSIX). */
|
||||
"SIGCONT", /* 18, Continue (POSIX). */
|
||||
"SIGSTOP", /* 19, Stop, unblockable (POSIX). */
|
||||
"SIGTSTP", /* 20, Keyboard stop (POSIX). */
|
||||
"SIGTTIN", /* 21, Background read from tty (POSIX). */
|
||||
"SIGTTOU", /* 22, Background write to tty (POSIX). */
|
||||
"SIGURG", /* 23, Urgent condition on socket (4.2 BSD). */
|
||||
"SIGXCPU", /* 24, CPU limit exceeded (4.2 BSD). */
|
||||
"SIGXFSZ", /* 25, File size limit exceeded (4.2 BSD). */
|
||||
"SIGVTALRM", /* 26, Virtual alarm clock (4.2 BSD). */
|
||||
"SIGPROF", /* 27, Profiling alarm clock (4.2 BSD). */
|
||||
"SIGWINCH", /* 28, Window size change (4.3 BSD, Sun). */
|
||||
"SIGIO", /* 29, I/O now possible (4.2 BSD). */
|
||||
"SIGPWR", /* 30, Power failure restart (System V). */
|
||||
"SIGSYS" /* 31, Bad system call. */
|
||||
};
|
||||
|
||||
void Engine::init(void)
|
||||
{
|
||||
if (!m_ready) {
|
||||
mutex_locker_t locker(m_lock);
|
||||
|
||||
if (!m_ready) {
|
||||
// start process if not done yet
|
||||
if (m_process == 0) {
|
||||
init_process();
|
||||
}
|
||||
|
||||
// load penging images
|
||||
load_libraries();
|
||||
|
||||
// and (re)build pointer table
|
||||
init_ptr_data();
|
||||
|
||||
// it is ready now
|
||||
m_ready = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Engine::init_process(void)
|
||||
{
|
||||
COIENGINE engine;
|
||||
COIRESULT res;
|
||||
const char **environ;
|
||||
|
||||
// create environment for the target process
|
||||
environ = (const char**) mic_env_vars.create_environ_for_card(m_index);
|
||||
if (environ != 0) {
|
||||
for (const char **p = environ; *p != 0; p++) {
|
||||
OFFLOAD_DEBUG_TRACE(3, "Env Var for card %d: %s\n", m_index, *p);
|
||||
}
|
||||
}
|
||||
|
||||
// Create execution context in the specified device
|
||||
OFFLOAD_DEBUG_TRACE(2, "Getting device %d (engine %d) handle\n", m_index,
|
||||
m_physical_index);
|
||||
res = COI::EngineGetHandle(COI_ISA_KNC, m_physical_index, &engine);
|
||||
check_result(res, c_get_engine_handle, m_index, res);
|
||||
|
||||
// Target executable should be available by the time when we
|
||||
// attempt to initialize the device
|
||||
if (__target_exe == 0) {
|
||||
LIBOFFLOAD_ERROR(c_no_target_exe);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
OFFLOAD_DEBUG_TRACE(2,
|
||||
"Loading target executable \"%s\" from %p, size %lld\n",
|
||||
__target_exe->name, __target_exe->data, __target_exe->size);
|
||||
|
||||
res = COI::ProcessCreateFromMemory(
|
||||
engine, // in_Engine
|
||||
__target_exe->name, // in_pBinaryName
|
||||
__target_exe->data, // in_pBinaryBuffer
|
||||
__target_exe->size, // in_BinaryBufferLength,
|
||||
0, // in_Argc
|
||||
0, // in_ppArgv
|
||||
environ == 0, // in_DupEnv
|
||||
environ, // in_ppAdditionalEnv
|
||||
mic_proxy_io, // in_ProxyActive
|
||||
mic_proxy_fs_root, // in_ProxyfsRoot
|
||||
mic_buffer_size, // in_BufferSpace
|
||||
mic_library_path, // in_LibrarySearchPath
|
||||
__target_exe->origin, // in_FileOfOrigin
|
||||
__target_exe->offset, // in_FileOfOriginOffset
|
||||
&m_process // out_pProcess
|
||||
);
|
||||
check_result(res, c_process_create, m_index, res);
|
||||
|
||||
// get function handles
|
||||
res = COI::ProcessGetFunctionHandles(m_process, c_funcs_total,
|
||||
m_func_names, m_funcs);
|
||||
check_result(res, c_process_get_func_handles, m_index, res);
|
||||
|
||||
// initialize device side
|
||||
pid_t pid = init_device();
|
||||
|
||||
// For IDB
|
||||
if (__dbg_is_attached) {
|
||||
// TODO: we have in-memory executable now.
|
||||
// Check with IDB team what should we provide them now?
|
||||
if (strlen(__target_exe->name) < MAX_TARGET_NAME) {
|
||||
strcpy(__dbg_target_exe_name, __target_exe->name);
|
||||
}
|
||||
__dbg_target_so_pid = pid;
|
||||
__dbg_target_id = m_physical_index;
|
||||
__dbg_target_so_loaded();
|
||||
}
|
||||
}
|
||||
|
||||
void Engine::fini_process(bool verbose)
|
||||
{
|
||||
if (m_process != 0) {
|
||||
uint32_t sig;
|
||||
int8_t ret;
|
||||
|
||||
// destroy target process
|
||||
OFFLOAD_DEBUG_TRACE(2, "Destroying process on the device %d\n",
|
||||
m_index);
|
||||
|
||||
COIRESULT res = COI::ProcessDestroy(m_process, -1, 0, &ret, &sig);
|
||||
m_process = 0;
|
||||
|
||||
if (res == COI_SUCCESS) {
|
||||
OFFLOAD_DEBUG_TRACE(3, "Device process: signal %d, exit code %d\n",
|
||||
sig, ret);
|
||||
if (verbose) {
|
||||
if (sig != 0) {
|
||||
LIBOFFLOAD_ERROR(
|
||||
c_mic_process_exit_sig, m_index, sig,
|
||||
c_signal_names[sig >= c_signal_max ? 0 : sig]);
|
||||
}
|
||||
else {
|
||||
LIBOFFLOAD_ERROR(c_mic_process_exit_ret, m_index, ret);
|
||||
}
|
||||
}
|
||||
|
||||
// for idb
|
||||
if (__dbg_is_attached) {
|
||||
__dbg_target_so_unloaded();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (verbose) {
|
||||
LIBOFFLOAD_ERROR(c_mic_process_exit, m_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Engine::load_libraries()
|
||||
{
|
||||
// load libraries collected so far
|
||||
for (TargetImageList::iterator it = m_images.begin();
|
||||
it != m_images.end(); it++) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "Loading library \"%s\" from %p, size %llu\n",
|
||||
it->name, it->data, it->size);
|
||||
|
||||
// load library to the device
|
||||
COILIBRARY lib;
|
||||
COIRESULT res;
|
||||
res = COI::ProcessLoadLibraryFromMemory(m_process,
|
||||
it->data,
|
||||
it->size,
|
||||
it->name,
|
||||
mic_library_path,
|
||||
it->origin,
|
||||
it->offset,
|
||||
COI_LOADLIBRARY_V1_FLAGS,
|
||||
&lib);
|
||||
|
||||
if (res != COI_SUCCESS && res != COI_ALREADY_EXISTS) {
|
||||
check_result(res, c_load_library, m_index, res);
|
||||
}
|
||||
}
|
||||
m_images.clear();
|
||||
}
|
||||
|
||||
static bool target_entry_cmp(
|
||||
const VarList::BufEntry &l,
|
||||
const VarList::BufEntry &r
|
||||
)
|
||||
{
|
||||
const char *l_name = reinterpret_cast<const char*>(l.name);
|
||||
const char *r_name = reinterpret_cast<const char*>(r.name);
|
||||
return strcmp(l_name, r_name) < 0;
|
||||
}
|
||||
|
||||
static bool host_entry_cmp(
|
||||
const VarTable::Entry *l,
|
||||
const VarTable::Entry *r
|
||||
)
|
||||
{
|
||||
return strcmp(l->name, r->name) < 0;
|
||||
}
|
||||
|
||||
void Engine::init_ptr_data(void)
|
||||
{
|
||||
COIRESULT res;
|
||||
COIEVENT event;
|
||||
|
||||
// Prepare table of host entries
|
||||
std::vector<const VarTable::Entry*> host_table(__offload_vars.begin(),
|
||||
__offload_vars.end());
|
||||
|
||||
// no need to do anything further is host table is empty
|
||||
if (host_table.size() <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get var table entries from the target.
|
||||
// First we need to get size for the buffer to copy data
|
||||
struct {
|
||||
int64_t nelems;
|
||||
int64_t length;
|
||||
} params;
|
||||
|
||||
res = COI::PipelineRunFunction(get_pipeline(),
|
||||
m_funcs[c_func_var_table_size],
|
||||
0, 0, 0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
¶ms, sizeof(params),
|
||||
&event);
|
||||
check_result(res, c_pipeline_run_func, m_index, res);
|
||||
|
||||
res = COI::EventWait(1, &event, -1, 1, 0, 0);
|
||||
check_result(res, c_event_wait, res);
|
||||
|
||||
if (params.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// create buffer for target entries and copy data to host
|
||||
COIBUFFER buffer;
|
||||
res = COI::BufferCreate(params.length, COI_BUFFER_NORMAL, 0, 0, 1,
|
||||
&m_process, &buffer);
|
||||
check_result(res, c_buf_create, m_index, res);
|
||||
|
||||
COI_ACCESS_FLAGS flags = COI_SINK_WRITE;
|
||||
res = COI::PipelineRunFunction(get_pipeline(),
|
||||
m_funcs[c_func_var_table_copy],
|
||||
1, &buffer, &flags,
|
||||
0, 0,
|
||||
¶ms.nelems, sizeof(params.nelems),
|
||||
0, 0,
|
||||
&event);
|
||||
check_result(res, c_pipeline_run_func, m_index, res);
|
||||
|
||||
res = COI::EventWait(1, &event, -1, 1, 0, 0);
|
||||
check_result(res, c_event_wait, res);
|
||||
|
||||
// patch names in target data
|
||||
VarList::BufEntry *target_table;
|
||||
COIMAPINSTANCE map_inst;
|
||||
res = COI::BufferMap(buffer, 0, params.length, COI_MAP_READ_ONLY, 0, 0,
|
||||
0, &map_inst,
|
||||
reinterpret_cast<void**>(&target_table));
|
||||
check_result(res, c_buf_map, res);
|
||||
|
||||
VarList::table_patch_names(target_table, params.nelems);
|
||||
|
||||
// and sort entries
|
||||
std::sort(target_table, target_table + params.nelems, target_entry_cmp);
|
||||
std::sort(host_table.begin(), host_table.end(), host_entry_cmp);
|
||||
|
||||
// merge host and target entries and enter matching vars map
|
||||
std::vector<const VarTable::Entry*>::const_iterator hi =
|
||||
host_table.begin();
|
||||
std::vector<const VarTable::Entry*>::const_iterator he =
|
||||
host_table.end();
|
||||
const VarList::BufEntry *ti = target_table;
|
||||
const VarList::BufEntry *te = target_table + params.nelems;
|
||||
|
||||
while (hi != he && ti != te) {
|
||||
int res = strcmp((*hi)->name, reinterpret_cast<const char*>(ti->name));
|
||||
if (res == 0) {
|
||||
// add matching entry to var map
|
||||
std::pair<PtrSet::iterator, bool> res =
|
||||
m_ptr_set.insert(PtrData((*hi)->addr, (*hi)->size));
|
||||
|
||||
// store address for new entries
|
||||
if (res.second) {
|
||||
PtrData *ptr = const_cast<PtrData*>(res.first.operator->());
|
||||
ptr->mic_addr = ti->addr;
|
||||
ptr->is_static = true;
|
||||
}
|
||||
|
||||
hi++;
|
||||
ti++;
|
||||
}
|
||||
else if (res < 0) {
|
||||
hi++;
|
||||
}
|
||||
else {
|
||||
ti++;
|
||||
}
|
||||
}
|
||||
|
||||
// cleanup
|
||||
res = COI::BufferUnmap(map_inst, 0, 0, 0);
|
||||
check_result(res, c_buf_unmap, res);
|
||||
|
||||
res = COI::BufferDestroy(buffer);
|
||||
check_result(res, c_buf_destroy, res);
|
||||
}
|
||||
|
||||
COIRESULT Engine::compute(
|
||||
const std::list<COIBUFFER> &buffers,
|
||||
const void* data,
|
||||
uint16_t data_size,
|
||||
void* ret,
|
||||
uint16_t ret_size,
|
||||
uint32_t num_deps,
|
||||
const COIEVENT* deps,
|
||||
COIEVENT* event
|
||||
) /* const */
|
||||
{
|
||||
COIBUFFER *bufs;
|
||||
COI_ACCESS_FLAGS *flags;
|
||||
COIRESULT res;
|
||||
|
||||
// convert buffers list to array
|
||||
int num_bufs = buffers.size();
|
||||
if (num_bufs > 0) {
|
||||
bufs = (COIBUFFER*) alloca(num_bufs * sizeof(COIBUFFER));
|
||||
flags = (COI_ACCESS_FLAGS*) alloca(num_bufs *
|
||||
sizeof(COI_ACCESS_FLAGS));
|
||||
|
||||
int i = 0;
|
||||
for (std::list<COIBUFFER>::const_iterator it = buffers.begin();
|
||||
it != buffers.end(); it++) {
|
||||
bufs[i] = *it;
|
||||
|
||||
// TODO: this should be fixed
|
||||
flags[i++] = COI_SINK_WRITE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
bufs = 0;
|
||||
flags = 0;
|
||||
}
|
||||
|
||||
// start computation
|
||||
res = COI::PipelineRunFunction(get_pipeline(),
|
||||
m_funcs[c_func_compute],
|
||||
num_bufs, bufs, flags,
|
||||
num_deps, deps,
|
||||
data, data_size,
|
||||
ret, ret_size,
|
||||
event);
|
||||
return res;
|
||||
}
|
||||
|
||||
pid_t Engine::init_device(void)
|
||||
{
|
||||
struct init_data {
|
||||
int device_index;
|
||||
int devices_total;
|
||||
int console_level;
|
||||
int offload_report_level;
|
||||
} data;
|
||||
COIRESULT res;
|
||||
COIEVENT event;
|
||||
pid_t pid;
|
||||
|
||||
OFFLOAD_DEBUG_TRACE_1(2, 0, c_offload_init,
|
||||
"Initializing device with logical index %d "
|
||||
"and physical index %d\n",
|
||||
m_index, m_physical_index);
|
||||
|
||||
// setup misc data
|
||||
data.device_index = m_index;
|
||||
data.devices_total = mic_engines_total;
|
||||
data.console_level = console_enabled;
|
||||
data.offload_report_level = offload_report_level;
|
||||
|
||||
res = COI::PipelineRunFunction(get_pipeline(),
|
||||
m_funcs[c_func_init],
|
||||
0, 0, 0, 0, 0,
|
||||
&data, sizeof(data),
|
||||
&pid, sizeof(pid),
|
||||
&event);
|
||||
check_result(res, c_pipeline_run_func, m_index, res);
|
||||
|
||||
res = COI::EventWait(1, &event, -1, 1, 0, 0);
|
||||
check_result(res, c_event_wait, res);
|
||||
|
||||
OFFLOAD_DEBUG_TRACE(2, "Device process pid is %d\n", pid);
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
// data associated with each thread
|
||||
struct Thread {
|
||||
Thread(long* addr_coipipe_counter) {
|
||||
m_addr_coipipe_counter = addr_coipipe_counter;
|
||||
memset(m_pipelines, 0, sizeof(m_pipelines));
|
||||
}
|
||||
|
||||
~Thread() {
|
||||
#ifndef TARGET_WINNT
|
||||
__sync_sub_and_fetch(m_addr_coipipe_counter, 1);
|
||||
#else // TARGET_WINNT
|
||||
_InterlockedDecrement(m_addr_coipipe_counter);
|
||||
#endif // TARGET_WINNT
|
||||
for (int i = 0; i < mic_engines_total; i++) {
|
||||
if (m_pipelines[i] != 0) {
|
||||
COI::PipelineDestroy(m_pipelines[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
COIPIPELINE get_pipeline(int index) const {
|
||||
return m_pipelines[index];
|
||||
}
|
||||
|
||||
void set_pipeline(int index, COIPIPELINE pipeline) {
|
||||
m_pipelines[index] = pipeline;
|
||||
}
|
||||
|
||||
AutoSet& get_auto_vars() {
|
||||
return m_auto_vars;
|
||||
}
|
||||
|
||||
private:
|
||||
long* m_addr_coipipe_counter;
|
||||
AutoSet m_auto_vars;
|
||||
COIPIPELINE m_pipelines[MIC_ENGINES_MAX];
|
||||
};
|
||||
|
||||
COIPIPELINE Engine::get_pipeline(void)
|
||||
{
|
||||
Thread* thread = (Thread*) thread_getspecific(mic_thread_key);
|
||||
if (thread == 0) {
|
||||
thread = new Thread(&m_proc_number);
|
||||
thread_setspecific(mic_thread_key, thread);
|
||||
}
|
||||
|
||||
COIPIPELINE pipeline = thread->get_pipeline(m_index);
|
||||
if (pipeline == 0) {
|
||||
COIRESULT res;
|
||||
int proc_num;
|
||||
|
||||
#ifndef TARGET_WINNT
|
||||
proc_num = __sync_fetch_and_add(&m_proc_number, 1);
|
||||
#else // TARGET_WINNT
|
||||
proc_num = _InterlockedIncrement(&m_proc_number);
|
||||
#endif // TARGET_WINNT
|
||||
|
||||
if (proc_num > COI_PIPELINE_MAX_PIPELINES) {
|
||||
LIBOFFLOAD_ERROR(c_coipipe_max_number, COI_PIPELINE_MAX_PIPELINES);
|
||||
LIBOFFLOAD_ABORT;
|
||||
}
|
||||
// create pipeline for this thread
|
||||
res = COI::PipelineCreate(m_process, 0, mic_stack_size, &pipeline);
|
||||
check_result(res, c_pipeline_create, m_index, res);
|
||||
|
||||
thread->set_pipeline(m_index, pipeline);
|
||||
}
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
AutoSet& Engine::get_auto_vars(void)
|
||||
{
|
||||
Thread* thread = (Thread*) thread_getspecific(mic_thread_key);
|
||||
if (thread == 0) {
|
||||
thread = new Thread(&m_proc_number);
|
||||
thread_setspecific(mic_thread_key, thread);
|
||||
}
|
||||
|
||||
return thread->get_auto_vars();
|
||||
}
|
||||
|
||||
void Engine::destroy_thread_data(void *data)
|
||||
{
|
||||
delete static_cast<Thread*>(data);
|
||||
}
|
||||
@@ -0,0 +1,482 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 OFFLOAD_ENGINE_H_INCLUDED
|
||||
#define OFFLOAD_ENGINE_H_INCLUDED
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include "offload_common.h"
|
||||
#include "coi/coi_client.h"
|
||||
|
||||
// Address range
|
||||
class MemRange {
|
||||
public:
|
||||
MemRange() : m_start(0), m_length(0) {}
|
||||
MemRange(const void *addr, uint64_t len) : m_start(addr), m_length(len) {}
|
||||
|
||||
const void* start() const {
|
||||
return m_start;
|
||||
}
|
||||
|
||||
const void* end() const {
|
||||
return static_cast<const char*>(m_start) + m_length;
|
||||
}
|
||||
|
||||
uint64_t length() const {
|
||||
return m_length;
|
||||
}
|
||||
|
||||
// returns true if given range overlaps with another one
|
||||
bool overlaps(const MemRange &o) const {
|
||||
// Two address ranges A[start, end) and B[start,end) overlap
|
||||
// if A.start < B.end and A.end > B.start.
|
||||
return start() < o.end() && end() > o.start();
|
||||
}
|
||||
|
||||
// returns true if given range contains the other range
|
||||
bool contains(const MemRange &o) const {
|
||||
return start() <= o.start() && o.end() <= end();
|
||||
}
|
||||
|
||||
private:
|
||||
const void* m_start;
|
||||
uint64_t m_length;
|
||||
};
|
||||
|
||||
// Data associated with a pointer variable
|
||||
class PtrData {
|
||||
public:
|
||||
PtrData(const void *addr, uint64_t len) :
|
||||
cpu_addr(addr, len), cpu_buf(0),
|
||||
mic_addr(0), alloc_disp(0), mic_buf(0), mic_offset(0),
|
||||
ref_count(0), is_static(false)
|
||||
{}
|
||||
|
||||
//
|
||||
// Copy constructor
|
||||
//
|
||||
PtrData(const PtrData& ptr):
|
||||
cpu_addr(ptr.cpu_addr), cpu_buf(ptr.cpu_buf),
|
||||
mic_addr(ptr.mic_addr), alloc_disp(ptr.alloc_disp),
|
||||
mic_buf(ptr.mic_buf), mic_offset(ptr.mic_offset),
|
||||
ref_count(ptr.ref_count), is_static(ptr.is_static)
|
||||
{}
|
||||
|
||||
bool operator<(const PtrData &o) const {
|
||||
// Variables are sorted by the CPU start address.
|
||||
// Overlapping memory ranges are considered equal.
|
||||
return (cpu_addr.start() < o.cpu_addr.start()) &&
|
||||
!cpu_addr.overlaps(o.cpu_addr);
|
||||
}
|
||||
|
||||
long add_reference() {
|
||||
if (is_static) {
|
||||
return LONG_MAX;
|
||||
}
|
||||
#ifndef TARGET_WINNT
|
||||
return __sync_fetch_and_add(&ref_count, 1);
|
||||
#else // TARGET_WINNT
|
||||
return _InterlockedIncrement(&ref_count) - 1;
|
||||
#endif // TARGET_WINNT
|
||||
}
|
||||
|
||||
long remove_reference() {
|
||||
if (is_static) {
|
||||
return LONG_MAX;
|
||||
}
|
||||
#ifndef TARGET_WINNT
|
||||
return __sync_sub_and_fetch(&ref_count, 1);
|
||||
#else // TARGET_WINNT
|
||||
return _InterlockedDecrement(&ref_count);
|
||||
#endif // TARGET_WINNT
|
||||
}
|
||||
|
||||
long get_reference() const {
|
||||
if (is_static) {
|
||||
return LONG_MAX;
|
||||
}
|
||||
return ref_count;
|
||||
}
|
||||
|
||||
public:
|
||||
// CPU address range
|
||||
const MemRange cpu_addr;
|
||||
|
||||
// CPU and MIC buffers
|
||||
COIBUFFER cpu_buf;
|
||||
COIBUFFER mic_buf;
|
||||
|
||||
// placeholder for buffer address on mic
|
||||
uint64_t mic_addr;
|
||||
|
||||
uint64_t alloc_disp;
|
||||
|
||||
// additional offset to pointer data on MIC for improving bandwidth for
|
||||
// data which is not 4K aligned
|
||||
uint32_t mic_offset;
|
||||
|
||||
// if true buffers are created from static memory
|
||||
bool is_static;
|
||||
mutex_t alloc_ptr_data_lock;
|
||||
|
||||
private:
|
||||
// reference count for the entry
|
||||
long ref_count;
|
||||
};
|
||||
|
||||
typedef std::list<PtrData*> PtrDataList;
|
||||
|
||||
// Data associated with automatic variable
|
||||
class AutoData {
|
||||
public:
|
||||
AutoData(const void *addr, uint64_t len) :
|
||||
cpu_addr(addr, len), ref_count(0)
|
||||
{}
|
||||
|
||||
bool operator<(const AutoData &o) const {
|
||||
// Variables are sorted by the CPU start address.
|
||||
// Overlapping memory ranges are considered equal.
|
||||
return (cpu_addr.start() < o.cpu_addr.start()) &&
|
||||
!cpu_addr.overlaps(o.cpu_addr);
|
||||
}
|
||||
|
||||
long add_reference() {
|
||||
#ifndef TARGET_WINNT
|
||||
return __sync_fetch_and_add(&ref_count, 1);
|
||||
#else // TARGET_WINNT
|
||||
return _InterlockedIncrement(&ref_count) - 1;
|
||||
#endif // TARGET_WINNT
|
||||
}
|
||||
|
||||
long remove_reference() {
|
||||
#ifndef TARGET_WINNT
|
||||
return __sync_sub_and_fetch(&ref_count, 1);
|
||||
#else // TARGET_WINNT
|
||||
return _InterlockedDecrement(&ref_count);
|
||||
#endif // TARGET_WINNT
|
||||
}
|
||||
|
||||
long get_reference() const {
|
||||
return ref_count;
|
||||
}
|
||||
|
||||
public:
|
||||
// CPU address range
|
||||
const MemRange cpu_addr;
|
||||
|
||||
private:
|
||||
// reference count for the entry
|
||||
long ref_count;
|
||||
};
|
||||
|
||||
// Set of autimatic variables
|
||||
typedef std::set<AutoData> AutoSet;
|
||||
|
||||
// Target image data
|
||||
struct TargetImage
|
||||
{
|
||||
TargetImage(const char *_name, const void *_data, uint64_t _size,
|
||||
const char *_origin, uint64_t _offset) :
|
||||
name(_name), data(_data), size(_size),
|
||||
origin(_origin), offset(_offset)
|
||||
{}
|
||||
|
||||
// library name
|
||||
const char* name;
|
||||
|
||||
// contents and size
|
||||
const void* data;
|
||||
uint64_t size;
|
||||
|
||||
// file of origin and offset within that file
|
||||
const char* origin;
|
||||
uint64_t offset;
|
||||
};
|
||||
|
||||
typedef std::list<TargetImage> TargetImageList;
|
||||
|
||||
// Data associated with persistent auto objects
|
||||
struct PersistData
|
||||
{
|
||||
PersistData(const void *addr, uint64_t routine_num, uint64_t size) :
|
||||
stack_cpu_addr(addr), routine_id(routine_num)
|
||||
{
|
||||
stack_ptr_data = new PtrData(0, size);
|
||||
}
|
||||
// 1-st key value - beginning of the stack at CPU
|
||||
const void * stack_cpu_addr;
|
||||
// 2-nd key value - identifier of routine invocation at CPU
|
||||
uint64_t routine_id;
|
||||
// corresponded PtrData; only stack_ptr_data->mic_buf is used
|
||||
PtrData * stack_ptr_data;
|
||||
// used to get offset of the variable in stack buffer
|
||||
char * cpu_stack_addr;
|
||||
};
|
||||
|
||||
typedef std::list<PersistData> PersistDataList;
|
||||
|
||||
// class representing a single engine
|
||||
struct Engine {
|
||||
friend void __offload_init_library_once(void);
|
||||
friend void __offload_fini_library(void);
|
||||
|
||||
#define check_result(res, tag, ...) \
|
||||
{ \
|
||||
if (res == COI_PROCESS_DIED) { \
|
||||
fini_process(true); \
|
||||
exit(1); \
|
||||
} \
|
||||
if (res != COI_SUCCESS) { \
|
||||
__liboffload_error_support(tag, __VA_ARGS__); \
|
||||
exit(1); \
|
||||
} \
|
||||
}
|
||||
|
||||
int get_logical_index() const {
|
||||
return m_index;
|
||||
}
|
||||
|
||||
int get_physical_index() const {
|
||||
return m_physical_index;
|
||||
}
|
||||
|
||||
const COIPROCESS& get_process() const {
|
||||
return m_process;
|
||||
}
|
||||
|
||||
// initialize device
|
||||
void init(void);
|
||||
|
||||
// add new library
|
||||
void add_lib(const TargetImage &lib)
|
||||
{
|
||||
m_lock.lock();
|
||||
m_ready = false;
|
||||
m_images.push_back(lib);
|
||||
m_lock.unlock();
|
||||
}
|
||||
|
||||
COIRESULT compute(
|
||||
const std::list<COIBUFFER> &buffers,
|
||||
const void* data,
|
||||
uint16_t data_size,
|
||||
void* ret,
|
||||
uint16_t ret_size,
|
||||
uint32_t num_deps,
|
||||
const COIEVENT* deps,
|
||||
COIEVENT* event
|
||||
);
|
||||
|
||||
#ifdef MYO_SUPPORT
|
||||
// temporary workaround for blocking behavior for myoiLibInit/Fini calls
|
||||
void init_myo(COIEVENT *event) {
|
||||
COIRESULT res;
|
||||
res = COI::PipelineRunFunction(get_pipeline(),
|
||||
m_funcs[c_func_myo_init],
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
event);
|
||||
check_result(res, c_pipeline_run_func, m_index, res);
|
||||
}
|
||||
|
||||
void fini_myo(COIEVENT *event) {
|
||||
COIRESULT res;
|
||||
res = COI::PipelineRunFunction(get_pipeline(),
|
||||
m_funcs[c_func_myo_fini],
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
event);
|
||||
check_result(res, c_pipeline_run_func, m_index, res);
|
||||
}
|
||||
#endif // MYO_SUPPORT
|
||||
|
||||
//
|
||||
// Memory association table
|
||||
//
|
||||
PtrData* find_ptr_data(const void *ptr) {
|
||||
m_ptr_lock.lock();
|
||||
PtrSet::iterator res = m_ptr_set.find(PtrData(ptr, 0));
|
||||
m_ptr_lock.unlock();
|
||||
if (res == m_ptr_set.end()) {
|
||||
return 0;
|
||||
}
|
||||
return const_cast<PtrData*>(res.operator->());
|
||||
}
|
||||
|
||||
PtrData* insert_ptr_data(const void *ptr, uint64_t len, bool &is_new) {
|
||||
m_ptr_lock.lock();
|
||||
std::pair<PtrSet::iterator, bool> res =
|
||||
m_ptr_set.insert(PtrData(ptr, len));
|
||||
PtrData* ptr_data = const_cast<PtrData*>(res.first.operator->());
|
||||
m_ptr_lock.unlock();
|
||||
|
||||
is_new = res.second;
|
||||
if (is_new) {
|
||||
// It's necessary to lock as soon as possible.
|
||||
// unlock must be done at call site of insert_ptr_data at
|
||||
// branch for is_new
|
||||
ptr_data->alloc_ptr_data_lock.lock();
|
||||
}
|
||||
return ptr_data;
|
||||
}
|
||||
|
||||
void remove_ptr_data(const void *ptr) {
|
||||
m_ptr_lock.lock();
|
||||
m_ptr_set.erase(PtrData(ptr, 0));
|
||||
m_ptr_lock.unlock();
|
||||
}
|
||||
|
||||
//
|
||||
// Automatic variables
|
||||
//
|
||||
AutoData* find_auto_data(const void *ptr) {
|
||||
AutoSet &auto_vars = get_auto_vars();
|
||||
AutoSet::iterator res = auto_vars.find(AutoData(ptr, 0));
|
||||
if (res == auto_vars.end()) {
|
||||
return 0;
|
||||
}
|
||||
return const_cast<AutoData*>(res.operator->());
|
||||
}
|
||||
|
||||
AutoData* insert_auto_data(const void *ptr, uint64_t len) {
|
||||
AutoSet &auto_vars = get_auto_vars();
|
||||
std::pair<AutoSet::iterator, bool> res =
|
||||
auto_vars.insert(AutoData(ptr, len));
|
||||
return const_cast<AutoData*>(res.first.operator->());
|
||||
}
|
||||
|
||||
void remove_auto_data(const void *ptr) {
|
||||
get_auto_vars().erase(AutoData(ptr, 0));
|
||||
}
|
||||
|
||||
//
|
||||
// Signals
|
||||
//
|
||||
void add_signal(const void *signal, OffloadDescriptor *desc) {
|
||||
m_signal_lock.lock();
|
||||
m_signal_map[signal] = desc;
|
||||
m_signal_lock.unlock();
|
||||
}
|
||||
|
||||
OffloadDescriptor* find_signal(const void *signal, bool remove) {
|
||||
OffloadDescriptor *desc = 0;
|
||||
|
||||
m_signal_lock.lock();
|
||||
{
|
||||
SignalMap::iterator it = m_signal_map.find(signal);
|
||||
if (it != m_signal_map.end()) {
|
||||
desc = it->second;
|
||||
if (remove) {
|
||||
m_signal_map.erase(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
m_signal_lock.unlock();
|
||||
|
||||
return desc;
|
||||
}
|
||||
|
||||
// stop device process
|
||||
void fini_process(bool verbose);
|
||||
|
||||
// list of stacks active at the engine
|
||||
PersistDataList m_persist_list;
|
||||
|
||||
private:
|
||||
Engine() : m_index(-1), m_physical_index(-1), m_process(0), m_ready(false),
|
||||
m_proc_number(0)
|
||||
{}
|
||||
|
||||
~Engine() {
|
||||
if (m_process != 0) {
|
||||
fini_process(false);
|
||||
}
|
||||
}
|
||||
|
||||
// set indexes
|
||||
void set_indexes(int logical_index, int physical_index) {
|
||||
m_index = logical_index;
|
||||
m_physical_index = physical_index;
|
||||
}
|
||||
|
||||
// start process on device
|
||||
void init_process();
|
||||
|
||||
void load_libraries(void);
|
||||
void init_ptr_data(void);
|
||||
|
||||
// performs library intialization on the device side
|
||||
pid_t init_device(void);
|
||||
|
||||
private:
|
||||
// get pipeline associated with a calling thread
|
||||
COIPIPELINE get_pipeline(void);
|
||||
|
||||
// get automatic vars set associated with the calling thread
|
||||
AutoSet& get_auto_vars(void);
|
||||
|
||||
// destructor for thread data
|
||||
static void destroy_thread_data(void *data);
|
||||
|
||||
private:
|
||||
typedef std::set<PtrData> PtrSet;
|
||||
typedef std::map<const void*, OffloadDescriptor*> SignalMap;
|
||||
|
||||
// device indexes
|
||||
int m_index;
|
||||
int m_physical_index;
|
||||
|
||||
// number of COI pipes created for the engine
|
||||
long m_proc_number;
|
||||
|
||||
// process handle
|
||||
COIPROCESS m_process;
|
||||
|
||||
// If false, device either has not been initialized or new libraries
|
||||
// have been added.
|
||||
bool m_ready;
|
||||
mutex_t m_lock;
|
||||
|
||||
// List of libraries to be loaded
|
||||
TargetImageList m_images;
|
||||
|
||||
// var table
|
||||
PtrSet m_ptr_set;
|
||||
mutex_t m_ptr_lock;
|
||||
|
||||
// signals
|
||||
SignalMap m_signal_map;
|
||||
mutex_t m_signal_lock;
|
||||
|
||||
// constants for accessing device function handles
|
||||
enum {
|
||||
c_func_compute = 0,
|
||||
#ifdef MYO_SUPPORT
|
||||
c_func_myo_init,
|
||||
c_func_myo_fini,
|
||||
#endif // MYO_SUPPORT
|
||||
c_func_init,
|
||||
c_func_var_table_size,
|
||||
c_func_var_table_copy,
|
||||
c_funcs_total
|
||||
};
|
||||
static const char* m_func_names[c_funcs_total];
|
||||
|
||||
// device function handles
|
||||
COIFUNCTION m_funcs[c_funcs_total];
|
||||
|
||||
// int -> name mapping for device signals
|
||||
static const int c_signal_max = 32;
|
||||
static const char* c_signal_names[c_signal_max];
|
||||
};
|
||||
|
||||
#endif // OFFLOAD_ENGINE_H_INCLUDED
|
||||
@@ -0,0 +1,354 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 "offload_env.h"
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "offload_util.h"
|
||||
#include "liboffload_error_codes.h"
|
||||
|
||||
// for environment variables valid on all cards
|
||||
const int MicEnvVar::any_card = -1;
|
||||
|
||||
MicEnvVar::~MicEnvVar()
|
||||
{
|
||||
for (std::list<MicEnvVar::CardEnvVars*>::const_iterator
|
||||
it = card_spec_list.begin();
|
||||
it != card_spec_list.end(); it++) {
|
||||
CardEnvVars *card_data = *it;
|
||||
delete card_data;
|
||||
}
|
||||
}
|
||||
|
||||
MicEnvVar::VarValue::~VarValue()
|
||||
{
|
||||
free(env_var_value);
|
||||
}
|
||||
|
||||
MicEnvVar::CardEnvVars::~CardEnvVars()
|
||||
{
|
||||
for (std::list<MicEnvVar::VarValue*>::const_iterator it = env_vars.begin();
|
||||
it != env_vars.end(); it++) {
|
||||
VarValue *var_value = *it;
|
||||
delete var_value;
|
||||
}
|
||||
}
|
||||
|
||||
// Searching for card in "card_spec_list" list with the same "number"
|
||||
|
||||
MicEnvVar::CardEnvVars* MicEnvVar::get_card(int number)
|
||||
{
|
||||
if (number == any_card) {
|
||||
return &common_vars;
|
||||
}
|
||||
for (std::list<MicEnvVar::CardEnvVars*>::const_iterator
|
||||
it = card_spec_list.begin();
|
||||
it != card_spec_list.end(); it++) {
|
||||
CardEnvVars *card_data = *it;
|
||||
if (card_data->card_number == number) {
|
||||
return card_data;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Searching for environment variable in "env_var" list with the same name
|
||||
|
||||
MicEnvVar::VarValue* MicEnvVar::CardEnvVars::find_var(
|
||||
char* env_var_name,
|
||||
int env_var_name_length
|
||||
)
|
||||
{
|
||||
for (std::list<MicEnvVar::VarValue*>::const_iterator it = env_vars.begin();
|
||||
it != env_vars.end(); it++) {
|
||||
VarValue *var_value = *it;
|
||||
if (var_value->length == env_var_name_length &&
|
||||
!strncmp(var_value->env_var, env_var_name,
|
||||
env_var_name_length)) {
|
||||
return var_value;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void MicEnvVar::analyze_env_var(char *env_var_string)
|
||||
{
|
||||
char *env_var_name;
|
||||
char *env_var_def;
|
||||
int card_number;
|
||||
int env_var_name_length;
|
||||
MicEnvVarKind env_var_kind;
|
||||
|
||||
env_var_kind = get_env_var_kind(env_var_string,
|
||||
&card_number,
|
||||
&env_var_name,
|
||||
&env_var_name_length,
|
||||
&env_var_def);
|
||||
switch (env_var_kind) {
|
||||
case c_mic_var:
|
||||
case c_mic_card_var:
|
||||
add_env_var(card_number,
|
||||
env_var_name,
|
||||
env_var_name_length,
|
||||
env_var_def);
|
||||
break;
|
||||
case c_mic_card_env:
|
||||
mic_parse_env_var_list(card_number, env_var_def);
|
||||
break;
|
||||
case c_no_mic:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MicEnvVar::add_env_var(
|
||||
int card_number,
|
||||
char *env_var_name,
|
||||
int env_var_name_length,
|
||||
char *env_var_def
|
||||
)
|
||||
{
|
||||
VarValue *var;
|
||||
CardEnvVars *card;
|
||||
|
||||
// The case corresponds to common env var definition of kind
|
||||
// <mic-prefix>_<var>
|
||||
if (card_number == any_card) {
|
||||
card = &common_vars;
|
||||
}
|
||||
else {
|
||||
card = get_card(card_number);
|
||||
if (!card) {
|
||||
// definition for new card occurred
|
||||
card = new CardEnvVars(card_number);
|
||||
card_spec_list.push_back(card);
|
||||
}
|
||||
|
||||
}
|
||||
var = card->find_var(env_var_name, env_var_name_length);
|
||||
if (!var) {
|
||||
// put new env var definition in "env_var" list
|
||||
var = new VarValue(env_var_name, env_var_name_length, env_var_def);
|
||||
card->env_vars.push_back(var);
|
||||
}
|
||||
}
|
||||
|
||||
// The routine analyses string pointed by "env_var_string" argument
|
||||
// according to the following syntax:
|
||||
//
|
||||
// Specification of prefix for MIC environment variables
|
||||
// MIC_ENV_PREFIX=<mic-prefix>
|
||||
//
|
||||
// Setting single MIC environment variable
|
||||
// <mic-prefix>_<var>=<value>
|
||||
// <mic-prefix>_<card-number>_<var>=<value>
|
||||
|
||||
// Setting multiple MIC environment variables
|
||||
// <mic-prefix>_<card-number>_ENV=<env-vars>
|
||||
|
||||
MicEnvVarKind MicEnvVar::get_env_var_kind(
|
||||
char *env_var_string,
|
||||
int *card_number,
|
||||
char **env_var_name,
|
||||
int *env_var_name_length,
|
||||
char **env_var_def
|
||||
)
|
||||
{
|
||||
int len = strlen(prefix);
|
||||
char *c = env_var_string;
|
||||
int num = 0;
|
||||
bool card_is_set = false;
|
||||
|
||||
if (strncmp(c, prefix, len) != 0 || c[len] != '_') {
|
||||
return c_no_mic;
|
||||
}
|
||||
c += len + 1;
|
||||
|
||||
*card_number = any_card;
|
||||
if (isdigit(*c)) {
|
||||
while (isdigit (*c)) {
|
||||
num = (*c++ - '0') + (num * 10);
|
||||
}
|
||||
if (*c != '_') {
|
||||
return c_no_mic;
|
||||
}
|
||||
c++;
|
||||
*card_number = num;
|
||||
card_is_set = true;
|
||||
}
|
||||
if (!isalpha(*c)) {
|
||||
return c_no_mic;
|
||||
}
|
||||
*env_var_name = *env_var_def = c;
|
||||
if (strncmp(c, "ENV=", 4) == 0) {
|
||||
if (!card_is_set) {
|
||||
*env_var_name_length = 3;
|
||||
*env_var_name = *env_var_def = c;
|
||||
*env_var_def = strdup(*env_var_def);
|
||||
return c_mic_var;
|
||||
}
|
||||
*env_var_def = c + strlen("ENV=");
|
||||
*env_var_def = strdup(*env_var_def);
|
||||
return c_mic_card_env;
|
||||
}
|
||||
if (isalpha(*c)) {
|
||||
*env_var_name_length = 0;
|
||||
while (isalnum(*c) || *c == '_') {
|
||||
c++;
|
||||
(*env_var_name_length)++;
|
||||
}
|
||||
}
|
||||
if (*c != '=') {
|
||||
return c_no_mic;
|
||||
}
|
||||
*env_var_def = strdup(*env_var_def);
|
||||
return card_is_set? c_mic_card_var : c_mic_var;
|
||||
}
|
||||
|
||||
// analysing <env-vars> in form:
|
||||
// <mic-prefix>_<card-number>_ENV=<env-vars>
|
||||
// where:
|
||||
//
|
||||
// <env-vars>:
|
||||
// <env-var>
|
||||
// <env-vars> | <env-var>
|
||||
//
|
||||
// <env-var>:
|
||||
// variable=value
|
||||
// variable="value"
|
||||
// variable=
|
||||
|
||||
void MicEnvVar::mic_parse_env_var_list(
|
||||
int card_number, char *env_vars_def_list)
|
||||
{
|
||||
char *c = env_vars_def_list;
|
||||
char *env_var_name;
|
||||
int env_var_name_length;
|
||||
char *env_var_def;
|
||||
bool var_is_quoted;
|
||||
|
||||
if (*c == '"') {
|
||||
c++;
|
||||
}
|
||||
while (*c != 0) {
|
||||
var_is_quoted = false;
|
||||
env_var_name = c;
|
||||
env_var_name_length = 0;
|
||||
if (isalpha(*c)) {
|
||||
while (isalnum(*c) || *c == '_') {
|
||||
c++;
|
||||
env_var_name_length++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
LIBOFFLOAD_ERROR(c_mic_parse_env_var_list1);
|
||||
return;
|
||||
}
|
||||
if (*c != '=') {
|
||||
LIBOFFLOAD_ERROR(c_mic_parse_env_var_list2);
|
||||
return;
|
||||
}
|
||||
c++;
|
||||
|
||||
if (*c == '"') {
|
||||
var_is_quoted = true;
|
||||
c++;
|
||||
}
|
||||
// Environment variable values that contain | will need to be escaped.
|
||||
while (*c != 0 && *c != '|' &&
|
||||
(!var_is_quoted || *c != '"'))
|
||||
{
|
||||
// skip escaped symbol
|
||||
if (*c == '\\') {
|
||||
c++;
|
||||
}
|
||||
c++;
|
||||
}
|
||||
if (var_is_quoted) {
|
||||
c++; // for "
|
||||
while (*c != 0 && *c != '|') {
|
||||
c++;
|
||||
}
|
||||
}
|
||||
|
||||
int sz = c - env_var_name;
|
||||
env_var_def = (char*)malloc(sz);
|
||||
memcpy(env_var_def, env_var_name, sz);
|
||||
env_var_def[sz] = 0;
|
||||
|
||||
if (*c == '|') {
|
||||
c++;
|
||||
while (*c != 0 && *c == ' ') {
|
||||
c++;
|
||||
}
|
||||
}
|
||||
add_env_var(card_number,
|
||||
env_var_name,
|
||||
env_var_name_length,
|
||||
env_var_def);
|
||||
}
|
||||
}
|
||||
|
||||
// Collect all definitions for the card with number "card_num".
|
||||
// The returned result is vector of string pointers defining one
|
||||
// environment variable. The vector is terminated by NULL pointer.
|
||||
// In the beginning of the vector there are env vars defined as
|
||||
// <mic-prefix>_<card-number>_<var>=<value>
|
||||
// or
|
||||
// <mic-prefix>_<card-number>_ENV=<env-vars>
|
||||
// where <card-number> is equal to "card_num"
|
||||
// They are followed by definitions valid for any card
|
||||
// and absent in previous definitions.
|
||||
|
||||
char** MicEnvVar::create_environ_for_card(int card_num)
|
||||
{
|
||||
VarValue *var_value;
|
||||
VarValue *var_value_find;
|
||||
CardEnvVars *card_data = get_card(card_num);
|
||||
CardEnvVars *card_data_common;
|
||||
std::list<char*> new_env;
|
||||
char **rez;
|
||||
|
||||
if (!prefix) {
|
||||
return NULL;
|
||||
}
|
||||
// There is no personel env var definitions for the card with
|
||||
// number "card_num"
|
||||
if (!card_data) {
|
||||
return create_environ_for_card(any_card);
|
||||
}
|
||||
|
||||
for (std::list<MicEnvVar::VarValue*>::const_iterator
|
||||
it = card_data->env_vars.begin();
|
||||
it != card_data->env_vars.end(); it++) {
|
||||
var_value = *it;
|
||||
new_env.push_back(var_value->env_var_value);
|
||||
}
|
||||
|
||||
if (card_num != any_card) {
|
||||
card_data_common = get_card(any_card);
|
||||
for (std::list<MicEnvVar::VarValue*>::const_iterator
|
||||
it = card_data_common->env_vars.begin();
|
||||
it != card_data_common->env_vars.end(); it++) {
|
||||
var_value = *it;
|
||||
var_value_find = card_data->find_var(var_value->env_var,
|
||||
var_value->length);
|
||||
if (!var_value_find) {
|
||||
new_env.push_back(var_value->env_var_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int new_env_size = new_env.size();
|
||||
rez = (char**) malloc((new_env_size + 1) * sizeof(char*));
|
||||
std::copy(new_env.begin(), new_env.end(), rez);
|
||||
rez[new_env_size] = 0;
|
||||
return rez;
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 OFFLOAD_ENV_H_INCLUDED
|
||||
#define OFFLOAD_ENV_H_INCLUDED
|
||||
|
||||
#include <list>
|
||||
|
||||
// data structure and routines to parse MIC user environment and pass to MIC
|
||||
|
||||
enum MicEnvVarKind
|
||||
{
|
||||
c_no_mic, // not MIC env var
|
||||
c_mic_var, // for <mic-prefix>_<var>
|
||||
c_mic_card_var, // for <mic-prefix>_<card-number>_<var>
|
||||
c_mic_card_env // for <mic-prefix>_<card-number>_ENV
|
||||
};
|
||||
|
||||
struct MicEnvVar {
|
||||
public:
|
||||
MicEnvVar() : prefix(0) {}
|
||||
~MicEnvVar();
|
||||
|
||||
void analyze_env_var(char *env_var_string);
|
||||
char** create_environ_for_card(int card_num);
|
||||
MicEnvVarKind get_env_var_kind(
|
||||
char *env_var_string,
|
||||
int *card_number,
|
||||
char **env_var_name,
|
||||
int *env_var_name_length,
|
||||
char **env_var_def
|
||||
);
|
||||
void add_env_var(
|
||||
int card_number,
|
||||
char *env_var_name,
|
||||
int env_var_name_length,
|
||||
char *env_var_def
|
||||
);
|
||||
|
||||
void set_prefix(const char *pref) {
|
||||
prefix = (pref && *pref != '\0') ? pref : 0;
|
||||
}
|
||||
|
||||
struct VarValue {
|
||||
public:
|
||||
char* env_var;
|
||||
int length;
|
||||
char* env_var_value;
|
||||
|
||||
VarValue(char* var, int ln, char* value)
|
||||
{
|
||||
env_var = var;
|
||||
length = ln;
|
||||
env_var_value = value;
|
||||
}
|
||||
~VarValue();
|
||||
};
|
||||
|
||||
struct CardEnvVars {
|
||||
public:
|
||||
|
||||
int card_number;
|
||||
std::list<struct VarValue*> env_vars;
|
||||
|
||||
CardEnvVars() { card_number = any_card; }
|
||||
CardEnvVars(int num) { card_number = num; }
|
||||
~CardEnvVars();
|
||||
|
||||
void add_new_env_var(int number, char *env_var, int length,
|
||||
char *env_var_value);
|
||||
VarValue* find_var(char* env_var_name, int env_var_name_length);
|
||||
};
|
||||
static const int any_card;
|
||||
|
||||
private:
|
||||
void mic_parse_env_var_list(int card_number, char *env_var_def);
|
||||
CardEnvVars* get_card(int number);
|
||||
|
||||
const char *prefix;
|
||||
std::list<struct CardEnvVars *> card_spec_list;
|
||||
CardEnvVars common_vars;
|
||||
};
|
||||
|
||||
#endif // OFFLOAD_ENV_H_INCLUDED
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,343 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
/*! \file
|
||||
\brief The parts of the runtime library used only on the host
|
||||
*/
|
||||
|
||||
#ifndef OFFLOAD_HOST_H_INCLUDED
|
||||
#define OFFLOAD_HOST_H_INCLUDED
|
||||
|
||||
#ifndef TARGET_WINNT
|
||||
#include <unistd.h>
|
||||
#endif // TARGET_WINNT
|
||||
#include "offload_common.h"
|
||||
#include "offload_util.h"
|
||||
#include "offload_engine.h"
|
||||
#include "offload_env.h"
|
||||
#include "offload_orsl.h"
|
||||
#include "coi/coi_client.h"
|
||||
|
||||
// MIC engines.
|
||||
extern Engine* mic_engines;
|
||||
extern uint32_t mic_engines_total;
|
||||
|
||||
//! The target image is packed as follows.
|
||||
/*! 1. 8 bytes containing the size of the target binary */
|
||||
/*! 2. a null-terminated string which is the binary name */
|
||||
/*! 3. <size> number of bytes that are the contents of the image */
|
||||
/*! The address of symbol __offload_target_image
|
||||
is the address of this structure. */
|
||||
struct Image {
|
||||
int64_t size; //!< Size in bytes of the target binary name and contents
|
||||
char data[]; //!< The name and contents of the target image
|
||||
};
|
||||
|
||||
// The offload descriptor.
|
||||
class OffloadDescriptor
|
||||
{
|
||||
public:
|
||||
OffloadDescriptor(
|
||||
int index,
|
||||
_Offload_status *status,
|
||||
bool is_mandatory,
|
||||
bool is_openmp,
|
||||
OffloadHostTimerData * timer_data
|
||||
) :
|
||||
m_device(mic_engines[index % mic_engines_total]),
|
||||
m_is_mandatory(is_mandatory),
|
||||
m_is_openmp(is_openmp),
|
||||
m_inout_buf(0),
|
||||
m_func_desc(0),
|
||||
m_func_desc_size(0),
|
||||
m_in_deps(0),
|
||||
m_in_deps_total(0),
|
||||
m_out_deps(0),
|
||||
m_out_deps_total(0),
|
||||
m_vars(0),
|
||||
m_vars_extra(0),
|
||||
m_status(status),
|
||||
m_timer_data(timer_data)
|
||||
{}
|
||||
|
||||
~OffloadDescriptor()
|
||||
{
|
||||
if (m_in_deps != 0) {
|
||||
free(m_in_deps);
|
||||
}
|
||||
if (m_out_deps != 0) {
|
||||
free(m_out_deps);
|
||||
}
|
||||
if (m_func_desc != 0) {
|
||||
free(m_func_desc);
|
||||
}
|
||||
if (m_vars != 0) {
|
||||
free(m_vars);
|
||||
free(m_vars_extra);
|
||||
}
|
||||
}
|
||||
|
||||
bool offload(const char *name, bool is_empty,
|
||||
VarDesc *vars, VarDesc2 *vars2, int vars_total,
|
||||
const void **waits, int num_waits, const void **signal,
|
||||
int entry_id, const void *stack_addr);
|
||||
bool offload_finish();
|
||||
|
||||
bool is_signaled();
|
||||
|
||||
OffloadHostTimerData* get_timer_data() const {
|
||||
return m_timer_data;
|
||||
}
|
||||
|
||||
private:
|
||||
bool wait_dependencies(const void **waits, int num_waits);
|
||||
bool setup_descriptors(VarDesc *vars, VarDesc2 *vars2, int vars_total,
|
||||
int entry_id, const void *stack_addr);
|
||||
bool setup_misc_data(const char *name);
|
||||
bool send_pointer_data(bool is_async);
|
||||
bool send_noncontiguous_pointer_data(
|
||||
int i,
|
||||
PtrData* src_buf,
|
||||
PtrData* dst_buf,
|
||||
COIEVENT *event);
|
||||
bool receive_noncontiguous_pointer_data(
|
||||
int i,
|
||||
char* src_data,
|
||||
COIBUFFER dst_buf,
|
||||
COIEVENT *event);
|
||||
|
||||
bool gather_copyin_data();
|
||||
|
||||
bool compute();
|
||||
|
||||
bool receive_pointer_data(bool is_async);
|
||||
bool scatter_copyout_data();
|
||||
|
||||
void cleanup();
|
||||
|
||||
bool find_ptr_data(PtrData* &ptr_data, void *base, int64_t disp,
|
||||
int64_t length, bool error_does_not_exist = true);
|
||||
bool alloc_ptr_data(PtrData* &ptr_data, void *base, int64_t disp,
|
||||
int64_t length, int64_t alloc_disp, int align);
|
||||
bool init_static_ptr_data(PtrData *ptr_data);
|
||||
bool init_mic_address(PtrData *ptr_data);
|
||||
bool offload_stack_memory_manager(const void * stack_begin, int routine_id,
|
||||
int buf_size, int align, bool *is_new);
|
||||
bool nullify_target_stack(COIBUFFER targ_buf, uint64_t size);
|
||||
|
||||
bool gen_var_descs_for_pointer_array(int i);
|
||||
|
||||
void report_coi_error(error_types msg, COIRESULT res);
|
||||
_Offload_result translate_coi_error(COIRESULT res) const;
|
||||
|
||||
private:
|
||||
typedef std::list<COIBUFFER> BufferList;
|
||||
|
||||
// extra data associated with each variable descriptor
|
||||
struct VarExtra {
|
||||
PtrData* src_data;
|
||||
PtrData* dst_data;
|
||||
AutoData* auto_data;
|
||||
int64_t cpu_disp;
|
||||
int64_t cpu_offset;
|
||||
CeanReadRanges *read_rng_src;
|
||||
CeanReadRanges *read_rng_dst;
|
||||
int64_t ptr_arr_offset;
|
||||
bool is_arr_ptr_el;
|
||||
};
|
||||
|
||||
template<typename T> class ReadArrElements {
|
||||
public:
|
||||
ReadArrElements():
|
||||
ranges(NULL),
|
||||
el_size(sizeof(T)),
|
||||
offset(0),
|
||||
count(0),
|
||||
is_empty(true),
|
||||
base(NULL)
|
||||
{}
|
||||
|
||||
bool read_next(bool flag)
|
||||
{
|
||||
if (flag != 0) {
|
||||
if (is_empty) {
|
||||
if (ranges) {
|
||||
if (!get_next_range(ranges, &offset)) {
|
||||
// ranges are over
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// all contiguous elements are over
|
||||
else if (count != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
length_cur = size;
|
||||
}
|
||||
else {
|
||||
offset += el_size;
|
||||
}
|
||||
val = (T)get_el_value(base, offset, el_size);
|
||||
length_cur -= el_size;
|
||||
count++;
|
||||
is_empty = length_cur == 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public:
|
||||
CeanReadRanges * ranges;
|
||||
T val;
|
||||
int el_size;
|
||||
int64_t size,
|
||||
offset,
|
||||
length_cur;
|
||||
bool is_empty;
|
||||
int count;
|
||||
char *base;
|
||||
};
|
||||
|
||||
// ptr_data for persistent auto objects
|
||||
PtrData* m_stack_ptr_data;
|
||||
PtrDataList m_destroy_stack;
|
||||
|
||||
// Engine
|
||||
Engine& m_device;
|
||||
|
||||
// if true offload is mandatory
|
||||
bool m_is_mandatory;
|
||||
|
||||
// if true offload has openmp origin
|
||||
const bool m_is_openmp;
|
||||
|
||||
// The Marshaller for the inputs of the offloaded region.
|
||||
Marshaller m_in;
|
||||
|
||||
// The Marshaller for the outputs of the offloaded region.
|
||||
Marshaller m_out;
|
||||
|
||||
// List of buffers that are passed to dispatch call
|
||||
BufferList m_compute_buffers;
|
||||
|
||||
// List of buffers that need to be destroyed at the end of offload
|
||||
BufferList m_destroy_buffers;
|
||||
|
||||
// Variable descriptors
|
||||
VarDesc* m_vars;
|
||||
VarExtra* m_vars_extra;
|
||||
int m_vars_total;
|
||||
|
||||
// Pointer to a user-specified status variable
|
||||
_Offload_status *m_status;
|
||||
|
||||
// Function descriptor
|
||||
FunctionDescriptor* m_func_desc;
|
||||
uint32_t m_func_desc_size;
|
||||
|
||||
// Buffer for transferring copyin/copyout data
|
||||
COIBUFFER m_inout_buf;
|
||||
|
||||
// Dependencies
|
||||
COIEVENT *m_in_deps;
|
||||
uint32_t m_in_deps_total;
|
||||
COIEVENT *m_out_deps;
|
||||
uint32_t m_out_deps_total;
|
||||
|
||||
// Timer data
|
||||
OffloadHostTimerData *m_timer_data;
|
||||
|
||||
// copyin/copyout data length
|
||||
uint64_t m_in_datalen;
|
||||
uint64_t m_out_datalen;
|
||||
|
||||
// a boolean value calculated in setup_descriptors. If true we need to do
|
||||
// a run function on the target. Otherwise it may be optimized away.
|
||||
bool m_need_runfunction;
|
||||
};
|
||||
|
||||
// Initialization types for MIC
|
||||
enum OffloadInitType {
|
||||
c_init_on_start, // all devices before entering main
|
||||
c_init_on_offload, // single device before starting the first offload
|
||||
c_init_on_offload_all // all devices before starting the first offload
|
||||
};
|
||||
|
||||
// Initializes library and registers specified offload image.
|
||||
extern "C" void __offload_register_image(const void* image);
|
||||
extern "C" void __offload_unregister_image(const void* image);
|
||||
|
||||
// Initializes offload runtime library.
|
||||
extern int __offload_init_library(void);
|
||||
|
||||
// thread data for associating pipelines with threads
|
||||
extern pthread_key_t mic_thread_key;
|
||||
|
||||
// Environment variables for devices
|
||||
extern MicEnvVar mic_env_vars;
|
||||
|
||||
// CPU frequency
|
||||
extern uint64_t cpu_frequency;
|
||||
|
||||
// LD_LIBRARY_PATH for MIC libraries
|
||||
extern char* mic_library_path;
|
||||
|
||||
// stack size for target
|
||||
extern uint32_t mic_stack_size;
|
||||
|
||||
// Preallocated memory size for buffers on MIC
|
||||
extern uint64_t mic_buffer_size;
|
||||
|
||||
// Setting controlling inout proxy
|
||||
extern bool mic_proxy_io;
|
||||
extern char* mic_proxy_fs_root;
|
||||
|
||||
// Threshold for creating buffers with large pages
|
||||
extern uint64_t __offload_use_2mb_buffers;
|
||||
|
||||
// offload initialization type
|
||||
extern OffloadInitType __offload_init_type;
|
||||
|
||||
// Device number to offload to when device is not explicitly specified.
|
||||
extern int __omp_device_num;
|
||||
|
||||
// target executable
|
||||
extern TargetImage* __target_exe;
|
||||
|
||||
// IDB support
|
||||
|
||||
// Called by the offload runtime after initialization of offload infrastructure
|
||||
// has been completed.
|
||||
extern "C" void __dbg_target_so_loaded();
|
||||
|
||||
// Called by the offload runtime when the offload infrastructure is about to be
|
||||
// shut down, currently at application exit.
|
||||
extern "C" void __dbg_target_so_unloaded();
|
||||
|
||||
// Null-terminated string containing path to the process image of the hosting
|
||||
// application (offload_main)
|
||||
#define MAX_TARGET_NAME 512
|
||||
extern "C" char __dbg_target_exe_name[MAX_TARGET_NAME];
|
||||
|
||||
// Integer specifying the process id
|
||||
extern "C" pid_t __dbg_target_so_pid;
|
||||
|
||||
// Integer specifying the 0-based device number
|
||||
extern "C" int __dbg_target_id;
|
||||
|
||||
// Set to non-zero by the host-side debugger to enable offload debugging
|
||||
// support
|
||||
extern "C" int __dbg_is_attached;
|
||||
|
||||
// Major version of the debugger support API
|
||||
extern "C" const int __dbg_api_major_version;
|
||||
|
||||
// Minor version of the debugger support API
|
||||
extern "C" const int __dbg_api_minor_version;
|
||||
|
||||
#endif // OFFLOAD_HOST_H_INCLUDED
|
||||
@@ -0,0 +1,805 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 "offload_myo_host.h"
|
||||
#include <errno.h>
|
||||
#include <malloc.h>
|
||||
#include "offload_host.h"
|
||||
|
||||
#if defined(LINUX) || defined(FREEBSD)
|
||||
#include <mm_malloc.h>
|
||||
#endif
|
||||
|
||||
#define MYO_VERSION1 "MYO_1.0"
|
||||
|
||||
extern "C" void __cilkrts_cilk_for_32(void*, void*, uint32_t, int32_t);
|
||||
extern "C" void __cilkrts_cilk_for_64(void*, void*, uint64_t, int32_t);
|
||||
|
||||
#ifndef TARGET_WINNT
|
||||
#pragma weak __cilkrts_cilk_for_32
|
||||
#pragma weak __cilkrts_cilk_for_64
|
||||
#endif // TARGET_WINNT
|
||||
|
||||
#ifdef TARGET_WINNT
|
||||
#define MYO_TABLE_END_MARKER() reinterpret_cast<const char*>(-1)
|
||||
#else // TARGET_WINNT
|
||||
#define MYO_TABLE_END_MARKER() reinterpret_cast<const char*>(0)
|
||||
#endif // TARGET_WINNT
|
||||
|
||||
class MyoWrapper {
|
||||
public:
|
||||
MyoWrapper() : m_lib_handle(0), m_is_available(false)
|
||||
{}
|
||||
|
||||
bool is_available() const {
|
||||
return m_is_available;
|
||||
}
|
||||
|
||||
bool LoadLibrary(void);
|
||||
|
||||
// unloads the library
|
||||
void UnloadLibrary(void) {
|
||||
// if (m_lib_handle != 0) {
|
||||
// DL_close(m_lib_handle);
|
||||
// m_lib_handle = 0;
|
||||
// }
|
||||
}
|
||||
|
||||
// Wrappers for MYO client functions
|
||||
void LibInit(void *arg, void *func) const {
|
||||
OFFLOAD_DEBUG_TRACE_1(4, 0, c_offload_myoinit,
|
||||
"%s(%p, %p)\n", __func__, arg, func);
|
||||
CheckResult(__func__, m_lib_init(arg, func));
|
||||
}
|
||||
|
||||
void LibFini(void) const {
|
||||
OFFLOAD_DEBUG_TRACE_1(4, 0, c_offload_myofini, "%s()\n", __func__);
|
||||
m_lib_fini();
|
||||
}
|
||||
|
||||
void* SharedMalloc(size_t size) const {
|
||||
OFFLOAD_DEBUG_TRACE_1(4, 0, c_offload_myosharedmalloc,
|
||||
"%s(%lld)\n", __func__, size);
|
||||
return m_shared_malloc(size);
|
||||
}
|
||||
|
||||
void SharedFree(void *ptr) const {
|
||||
OFFLOAD_DEBUG_TRACE_1(4, 0, c_offload_myosharedfree,
|
||||
"%s(%p)\n", __func__, ptr);
|
||||
m_shared_free(ptr);
|
||||
}
|
||||
|
||||
void* SharedAlignedMalloc(size_t size, size_t align) const {
|
||||
OFFLOAD_DEBUG_TRACE_1(4, 0, c_offload_myosharedalignedmalloc,
|
||||
"%s(%lld, %lld)\n", __func__, size, align);
|
||||
return m_shared_aligned_malloc(size, align);
|
||||
}
|
||||
|
||||
void SharedAlignedFree(void *ptr) const {
|
||||
OFFLOAD_DEBUG_TRACE_1(4, 0, c_offload_myosharedalignedfree,
|
||||
"%s(%p)\n", __func__, ptr);
|
||||
m_shared_aligned_free(ptr);
|
||||
}
|
||||
|
||||
void Acquire(void) const {
|
||||
OFFLOAD_DEBUG_TRACE_1(4, 0, c_offload_myoacquire,
|
||||
"%s()\n", __func__);
|
||||
CheckResult(__func__, m_acquire());
|
||||
}
|
||||
|
||||
void Release(void) const {
|
||||
OFFLOAD_DEBUG_TRACE_1(4, 0, c_offload_myorelease,
|
||||
"%s()\n", __func__);
|
||||
CheckResult(__func__, m_release());
|
||||
}
|
||||
|
||||
void HostVarTablePropagate(void *table, int num_entries) const {
|
||||
OFFLOAD_DEBUG_TRACE(4, "%s(%p, %d)\n", __func__, table, num_entries);
|
||||
CheckResult(__func__, m_host_var_table_propagate(table, num_entries));
|
||||
}
|
||||
|
||||
void HostFptrTableRegister(void *table, int num_entries,
|
||||
int ordered) const {
|
||||
OFFLOAD_DEBUG_TRACE_1(4, 0, c_offload_myoregister,
|
||||
"%s(%p, %d, %d)\n", __func__, table,
|
||||
num_entries, ordered);
|
||||
CheckResult(__func__,
|
||||
m_host_fptr_table_register(table, num_entries, ordered));
|
||||
}
|
||||
|
||||
void RemoteThunkCall(void *thunk, void *args, int device) {
|
||||
OFFLOAD_DEBUG_TRACE(4, "%s(%p, %p, %d)\n", __func__, thunk, args,
|
||||
device);
|
||||
CheckResult(__func__, m_remote_thunk_call(thunk, args, device));
|
||||
}
|
||||
|
||||
MyoiRFuncCallHandle RemoteCall(char *func, void *args, int device) const {
|
||||
OFFLOAD_DEBUG_TRACE(4, "%s(%s, %p, %d)\n", __func__, func, args,
|
||||
device);
|
||||
return m_remote_call(func, args, device);
|
||||
}
|
||||
|
||||
void GetResult(MyoiRFuncCallHandle handle) const {
|
||||
OFFLOAD_DEBUG_TRACE(4, "%s(%p)\n", __func__, handle);
|
||||
CheckResult(__func__, m_get_result(handle));
|
||||
}
|
||||
|
||||
private:
|
||||
void CheckResult(const char *func, MyoError error) const {
|
||||
if (error != MYO_SUCCESS) {
|
||||
LIBOFFLOAD_ERROR(c_myowrapper_checkresult, func, error);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void* m_lib_handle;
|
||||
bool m_is_available;
|
||||
|
||||
// pointers to functions from myo library
|
||||
MyoError (*m_lib_init)(void*, void*);
|
||||
void (*m_lib_fini)(void);
|
||||
void* (*m_shared_malloc)(size_t);
|
||||
void (*m_shared_free)(void*);
|
||||
void* (*m_shared_aligned_malloc)(size_t, size_t);
|
||||
void (*m_shared_aligned_free)(void*);
|
||||
MyoError (*m_acquire)(void);
|
||||
MyoError (*m_release)(void);
|
||||
MyoError (*m_host_var_table_propagate)(void*, int);
|
||||
MyoError (*m_host_fptr_table_register)(void*, int, int);
|
||||
MyoError (*m_remote_thunk_call)(void*, void*, int);
|
||||
MyoiRFuncCallHandle (*m_remote_call)(char*, void*, int);
|
||||
MyoError (*m_get_result)(MyoiRFuncCallHandle);
|
||||
};
|
||||
|
||||
bool MyoWrapper::LoadLibrary(void)
|
||||
{
|
||||
#ifndef TARGET_WINNT
|
||||
const char *lib_name = "libmyo-client.so";
|
||||
#else // TARGET_WINNT
|
||||
const char *lib_name = "myo-client.dll";
|
||||
#endif // TARGET_WINNT
|
||||
|
||||
OFFLOAD_DEBUG_TRACE(2, "Loading MYO library %s ...\n", lib_name);
|
||||
|
||||
m_lib_handle = DL_open(lib_name);
|
||||
if (m_lib_handle == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "Failed to load the library. errno = %d\n",
|
||||
errno);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_lib_init = (MyoError (*)(void*, void*))
|
||||
DL_sym(m_lib_handle, "myoiLibInit", MYO_VERSION1);
|
||||
if (m_lib_init == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in MYO library\n",
|
||||
"myoiLibInit");
|
||||
UnloadLibrary();
|
||||
return false;
|
||||
}
|
||||
|
||||
m_lib_fini = (void (*)(void))
|
||||
DL_sym(m_lib_handle, "myoiLibFini", MYO_VERSION1);
|
||||
if (m_lib_fini == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in MYO library\n",
|
||||
"myoiLibFini");
|
||||
UnloadLibrary();
|
||||
return false;
|
||||
}
|
||||
|
||||
m_shared_malloc = (void* (*)(size_t))
|
||||
DL_sym(m_lib_handle, "myoSharedMalloc", MYO_VERSION1);
|
||||
if (m_shared_malloc == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in MYO library\n",
|
||||
"myoSharedMalloc");
|
||||
UnloadLibrary();
|
||||
return false;
|
||||
}
|
||||
|
||||
m_shared_free = (void (*)(void*))
|
||||
DL_sym(m_lib_handle, "myoSharedFree", MYO_VERSION1);
|
||||
if (m_shared_free == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in MYO library\n",
|
||||
"myoSharedFree");
|
||||
UnloadLibrary();
|
||||
return false;
|
||||
}
|
||||
|
||||
m_shared_aligned_malloc = (void* (*)(size_t, size_t))
|
||||
DL_sym(m_lib_handle, "myoSharedAlignedMalloc", MYO_VERSION1);
|
||||
if (m_shared_aligned_malloc == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in MYO library\n",
|
||||
"myoSharedAlignedMalloc");
|
||||
UnloadLibrary();
|
||||
return false;
|
||||
}
|
||||
|
||||
m_shared_aligned_free = (void (*)(void*))
|
||||
DL_sym(m_lib_handle, "myoSharedAlignedFree", MYO_VERSION1);
|
||||
if (m_shared_aligned_free == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in MYO library\n",
|
||||
"myoSharedAlignedFree");
|
||||
UnloadLibrary();
|
||||
return false;
|
||||
}
|
||||
|
||||
m_acquire = (MyoError (*)(void))
|
||||
DL_sym(m_lib_handle, "myoAcquire", MYO_VERSION1);
|
||||
if (m_acquire == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in MYO library\n",
|
||||
"myoAcquire");
|
||||
UnloadLibrary();
|
||||
return false;
|
||||
}
|
||||
|
||||
m_release = (MyoError (*)(void))
|
||||
DL_sym(m_lib_handle, "myoRelease", MYO_VERSION1);
|
||||
if (m_release == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in MYO library\n",
|
||||
"myoRelease");
|
||||
UnloadLibrary();
|
||||
return false;
|
||||
}
|
||||
|
||||
m_host_var_table_propagate = (MyoError (*)(void*, int))
|
||||
DL_sym(m_lib_handle, "myoiHostVarTablePropagate", MYO_VERSION1);
|
||||
if (m_host_var_table_propagate == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in MYO library\n",
|
||||
"myoiHostVarTablePropagate");
|
||||
UnloadLibrary();
|
||||
return false;
|
||||
}
|
||||
|
||||
m_host_fptr_table_register = (MyoError (*)(void*, int, int))
|
||||
DL_sym(m_lib_handle, "myoiHostFptrTableRegister", MYO_VERSION1);
|
||||
if (m_host_fptr_table_register == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in MYO library\n",
|
||||
"myoiHostFptrTableRegister");
|
||||
UnloadLibrary();
|
||||
return false;
|
||||
}
|
||||
|
||||
m_remote_thunk_call = (MyoError (*)(void*, void*, int))
|
||||
DL_sym(m_lib_handle, "myoiRemoteThunkCall", MYO_VERSION1);
|
||||
if (m_remote_thunk_call == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in MYO library\n",
|
||||
"myoiRemoteThunkCall");
|
||||
UnloadLibrary();
|
||||
return false;
|
||||
}
|
||||
|
||||
m_remote_call = (MyoiRFuncCallHandle (*)(char*, void*, int))
|
||||
DL_sym(m_lib_handle, "myoiRemoteCall", MYO_VERSION1);
|
||||
if (m_remote_call == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in MYO library\n",
|
||||
"myoiRemoteCall");
|
||||
UnloadLibrary();
|
||||
return false;
|
||||
}
|
||||
|
||||
m_get_result = (MyoError (*)(MyoiRFuncCallHandle))
|
||||
DL_sym(m_lib_handle, "myoiGetResult", MYO_VERSION1);
|
||||
if (m_get_result == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "Failed to find %s in MYO library\n",
|
||||
"myoiGetResult");
|
||||
UnloadLibrary();
|
||||
return false;
|
||||
}
|
||||
|
||||
OFFLOAD_DEBUG_TRACE(2, "The library was successfully loaded\n");
|
||||
|
||||
m_is_available = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool myo_is_available;
|
||||
static MyoWrapper myo_wrapper;
|
||||
|
||||
struct MyoTable
|
||||
{
|
||||
MyoTable(SharedTableEntry *tab, int len) : var_tab(tab), var_tab_len(len)
|
||||
{}
|
||||
|
||||
SharedTableEntry* var_tab;
|
||||
int var_tab_len;
|
||||
};
|
||||
|
||||
typedef std::list<MyoTable> MyoTableList;
|
||||
static MyoTableList __myo_table_list;
|
||||
static mutex_t __myo_table_lock;
|
||||
static bool __myo_tables = false;
|
||||
|
||||
static void __offload_myo_shared_table_register(SharedTableEntry *entry);
|
||||
static void __offload_myo_shared_init_table_register(InitTableEntry* entry);
|
||||
static void __offload_myo_fptr_table_register(FptrTableEntry *entry);
|
||||
|
||||
static void __offload_myoLoadLibrary_once(void)
|
||||
{
|
||||
if (__offload_init_library()) {
|
||||
myo_wrapper.LoadLibrary();
|
||||
}
|
||||
}
|
||||
|
||||
static bool __offload_myoLoadLibrary(void)
|
||||
{
|
||||
static OffloadOnceControl ctrl = OFFLOAD_ONCE_CONTROL_INIT;
|
||||
__offload_run_once(&ctrl, __offload_myoLoadLibrary_once);
|
||||
|
||||
return myo_wrapper.is_available();
|
||||
}
|
||||
|
||||
static void __offload_myoInit_once(void)
|
||||
{
|
||||
if (!__offload_myoLoadLibrary()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// initialize all devices
|
||||
for (int i = 0; i < mic_engines_total; i++) {
|
||||
mic_engines[i].init();
|
||||
}
|
||||
|
||||
// load and initialize MYO library
|
||||
OFFLOAD_DEBUG_TRACE(2, "Initializing MYO library ...\n");
|
||||
|
||||
COIEVENT events[MIC_ENGINES_MAX];
|
||||
MyoiUserParams params[MIC_ENGINES_MAX+1];
|
||||
|
||||
// load target library to all devices
|
||||
for (int i = 0; i < mic_engines_total; i++) {
|
||||
mic_engines[i].init_myo(&events[i]);
|
||||
|
||||
params[i].type = MYOI_USERPARAMS_DEVID;
|
||||
params[i].nodeid = mic_engines[i].get_physical_index() + 1;
|
||||
}
|
||||
|
||||
params[mic_engines_total].type = MYOI_USERPARAMS_LAST_MSG;
|
||||
|
||||
// initialize myo runtime on host
|
||||
myo_wrapper.LibInit(params, 0);
|
||||
|
||||
// wait for the target init calls to finish
|
||||
COIRESULT res;
|
||||
res = COI::EventWait(mic_engines_total, events, -1, 1, 0, 0);
|
||||
if (res != COI_SUCCESS) {
|
||||
LIBOFFLOAD_ERROR(c_event_wait, res);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
myo_is_available = true;
|
||||
|
||||
OFFLOAD_DEBUG_TRACE(2, "Initializing MYO library ... done\n");
|
||||
}
|
||||
|
||||
static bool __offload_myoInit(void)
|
||||
{
|
||||
static OffloadOnceControl ctrl = OFFLOAD_ONCE_CONTROL_INIT;
|
||||
__offload_run_once(&ctrl, __offload_myoInit_once);
|
||||
|
||||
// register pending shared var tables
|
||||
if (myo_is_available && __myo_tables) {
|
||||
mutex_locker_t locker(__myo_table_lock);
|
||||
|
||||
if (__myo_tables) {
|
||||
// Register tables with MYO so it can propagate to target.
|
||||
for(MyoTableList::const_iterator it = __myo_table_list.begin();
|
||||
it != __myo_table_list.end(); ++it) {
|
||||
#ifdef TARGET_WINNT
|
||||
for (SharedTableEntry *entry = it->var_tab;
|
||||
entry->varName != MYO_TABLE_END_MARKER(); entry++) {
|
||||
if (entry->varName == 0) {
|
||||
continue;
|
||||
}
|
||||
myo_wrapper.HostVarTablePropagate(entry, 1);
|
||||
}
|
||||
#else // TARGET_WINNT
|
||||
myo_wrapper.HostVarTablePropagate(it->var_tab,
|
||||
it->var_tab_len);
|
||||
#endif // TARGET_WINNT
|
||||
}
|
||||
|
||||
__myo_table_list.clear();
|
||||
__myo_tables = false;
|
||||
}
|
||||
}
|
||||
|
||||
return myo_is_available;
|
||||
}
|
||||
|
||||
static bool shared_table_entries(
|
||||
SharedTableEntry *entry
|
||||
)
|
||||
{
|
||||
OFFLOAD_DEBUG_TRACE(3, "%s(%p)\n", __func__, entry);
|
||||
|
||||
for (; entry->varName != MYO_TABLE_END_MARKER(); entry++) {
|
||||
#ifdef TARGET_WINNT
|
||||
if (entry->varName == 0) {
|
||||
continue;
|
||||
}
|
||||
#endif // TARGET_WINNT
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool fptr_table_entries(
|
||||
FptrTableEntry *entry
|
||||
)
|
||||
{
|
||||
OFFLOAD_DEBUG_TRACE(3, "%s(%p)\n", __func__, entry);
|
||||
|
||||
for (; entry->funcName != MYO_TABLE_END_MARKER(); entry++) {
|
||||
#ifdef TARGET_WINNT
|
||||
if (entry->funcName == 0) {
|
||||
continue;
|
||||
}
|
||||
#endif // TARGET_WINNT
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
extern "C" void __offload_myoRegisterTables(
|
||||
InitTableEntry* init_table,
|
||||
SharedTableEntry *shared_table,
|
||||
FptrTableEntry *fptr_table
|
||||
)
|
||||
{
|
||||
// check whether we need to initialize MYO library. It is
|
||||
// initialized only if at least one myo table is not empty
|
||||
if (shared_table_entries(shared_table) || fptr_table_entries(fptr_table)) {
|
||||
// make sure myo library is loaded
|
||||
__offload_myoLoadLibrary();
|
||||
|
||||
// register tables
|
||||
__offload_myo_shared_table_register(shared_table);
|
||||
__offload_myo_fptr_table_register(fptr_table);
|
||||
__offload_myo_shared_init_table_register(init_table);
|
||||
}
|
||||
}
|
||||
|
||||
void __offload_myoFini(void)
|
||||
{
|
||||
if (myo_is_available) {
|
||||
OFFLOAD_DEBUG_TRACE(3, "%s\n", __func__);
|
||||
|
||||
COIEVENT events[MIC_ENGINES_MAX];
|
||||
|
||||
// kick off myoiLibFini calls on all devices
|
||||
for (int i = 0; i < mic_engines_total; i++) {
|
||||
mic_engines[i].fini_myo(&events[i]);
|
||||
}
|
||||
|
||||
// cleanup myo runtime on host
|
||||
myo_wrapper.LibFini();
|
||||
|
||||
// wait for the target fini calls to finish
|
||||
COIRESULT res;
|
||||
res = COI::EventWait(mic_engines_total, events, -1, 1, 0, 0);
|
||||
if (res != COI_SUCCESS) {
|
||||
LIBOFFLOAD_ERROR(c_event_wait, res);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void __offload_myo_shared_table_register(
|
||||
SharedTableEntry *entry
|
||||
)
|
||||
{
|
||||
OFFLOAD_DEBUG_TRACE(3, "%s(%p)\n", __func__, entry);
|
||||
|
||||
SharedTableEntry *start = entry;
|
||||
int entries = 0;
|
||||
|
||||
// allocate shared memory for vars
|
||||
for (; entry->varName != MYO_TABLE_END_MARKER(); entry++) {
|
||||
#ifdef TARGET_WINNT
|
||||
if (entry->varName == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(4, "skip registering a NULL MyoSharedTable entry\n");
|
||||
continue;
|
||||
}
|
||||
#endif // TARGET_WINNT
|
||||
|
||||
OFFLOAD_DEBUG_TRACE(4, "registering MyoSharedTable entry for %s @%p\n",
|
||||
entry->varName, entry);
|
||||
|
||||
// Invoke the function to create shared memory
|
||||
reinterpret_cast<void(*)(void)>(entry->sharedAddr)();
|
||||
entries++;
|
||||
}
|
||||
|
||||
// and table to the list if it is not empty
|
||||
if (entries > 0) {
|
||||
mutex_locker_t locker(__myo_table_lock);
|
||||
__myo_table_list.push_back(MyoTable(start, entries));
|
||||
__myo_tables = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void __offload_myo_shared_init_table_register(InitTableEntry* entry)
|
||||
{
|
||||
OFFLOAD_DEBUG_TRACE(3, "%s(%p)\n", __func__, entry);
|
||||
|
||||
#ifdef TARGET_WINNT
|
||||
for (; entry->funcName != MYO_TABLE_END_MARKER(); entry++) {
|
||||
if (entry->funcName == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(4, "skip registering a NULL MyoSharedInit entry\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
// Invoke the function to init the shared memory
|
||||
entry->func();
|
||||
}
|
||||
#else // TARGET_WINNT
|
||||
for (; entry->func != 0; entry++) {
|
||||
// Invoke the function to init the shared memory
|
||||
entry->func();
|
||||
}
|
||||
#endif // TARGET_WINNT
|
||||
}
|
||||
|
||||
static void __offload_myo_fptr_table_register(
|
||||
FptrTableEntry *entry
|
||||
)
|
||||
{
|
||||
OFFLOAD_DEBUG_TRACE(3, "%s(%p)\n", __func__, entry);
|
||||
|
||||
FptrTableEntry *start = entry;
|
||||
int entries = 0;
|
||||
|
||||
for (; entry->funcName != MYO_TABLE_END_MARKER(); entry++) {
|
||||
#ifdef TARGET_WINNT
|
||||
if (entry->funcName == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(4, "skip registering a NULL MyoFptrTable entry\n");
|
||||
continue;
|
||||
}
|
||||
#endif // TARGET_WINNT
|
||||
|
||||
if (!myo_wrapper.is_available()) {
|
||||
*(static_cast<void**>(entry->localThunkAddr)) = entry->funcAddr;
|
||||
}
|
||||
|
||||
OFFLOAD_DEBUG_TRACE(4, "registering MyoFptrTable entry for %s @%p\n",
|
||||
entry->funcName, entry);
|
||||
|
||||
#ifdef TARGET_WINNT
|
||||
if (myo_wrapper.is_available()) {
|
||||
myo_wrapper.HostFptrTableRegister(entry, 1, false);
|
||||
}
|
||||
#endif // TARGET_WINNT
|
||||
|
||||
entries++;
|
||||
}
|
||||
|
||||
#ifndef TARGET_WINNT
|
||||
if (myo_wrapper.is_available() && entries > 0) {
|
||||
myo_wrapper.HostFptrTableRegister(start, entries, false);
|
||||
}
|
||||
#endif // TARGET_WINNT
|
||||
}
|
||||
|
||||
extern "C" int __offload_myoIsAvailable(int target_number)
|
||||
{
|
||||
OFFLOAD_DEBUG_TRACE(3, "%s(%d)\n", __func__, target_number);
|
||||
|
||||
if (target_number >= -2) {
|
||||
bool is_default_number = (target_number == -2);
|
||||
|
||||
if (__offload_myoInit()) {
|
||||
if (target_number >= 0) {
|
||||
// User provided the device number
|
||||
int num = target_number % mic_engines_total;
|
||||
|
||||
// reserve device in ORSL
|
||||
target_number = ORSL::reserve(num) ? num : -1;
|
||||
}
|
||||
else {
|
||||
// try to use device 0
|
||||
target_number = ORSL::reserve(0) ? 0 : -1;
|
||||
}
|
||||
|
||||
// make sure device is initialized
|
||||
if (target_number >= 0) {
|
||||
mic_engines[target_number].init();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// fallback to CPU
|
||||
target_number = -1;
|
||||
}
|
||||
|
||||
if (target_number < 0 && !is_default_number) {
|
||||
LIBOFFLOAD_ERROR(c_device_is_not_available);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
LIBOFFLOAD_ERROR(c_invalid_device_number);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return target_number;
|
||||
}
|
||||
|
||||
extern "C" void __offload_myoiRemoteIThunkCall(
|
||||
void *thunk,
|
||||
void *arg,
|
||||
int target_number
|
||||
)
|
||||
{
|
||||
OFFLOAD_DEBUG_TRACE(3, "%s(%p, %p, %d)\n", __func__, thunk, arg,
|
||||
target_number);
|
||||
|
||||
myo_wrapper.Release();
|
||||
myo_wrapper.RemoteThunkCall(thunk, arg, target_number);
|
||||
myo_wrapper.Acquire();
|
||||
|
||||
ORSL::release(target_number);
|
||||
}
|
||||
|
||||
extern "C" void* _Offload_shared_malloc(size_t size)
|
||||
{
|
||||
OFFLOAD_DEBUG_TRACE(3, "%s(%lld)\n", __func__, size);
|
||||
|
||||
if (__offload_myoLoadLibrary()) {
|
||||
return myo_wrapper.SharedMalloc(size);
|
||||
}
|
||||
else {
|
||||
return malloc(size);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void _Offload_shared_free(void *ptr)
|
||||
{
|
||||
OFFLOAD_DEBUG_TRACE(3, "%s(%p)\n", __func__, ptr);
|
||||
|
||||
if (__offload_myoLoadLibrary()) {
|
||||
myo_wrapper.SharedFree(ptr);
|
||||
}
|
||||
else {
|
||||
free(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void* _Offload_shared_aligned_malloc(size_t size, size_t align)
|
||||
{
|
||||
OFFLOAD_DEBUG_TRACE(3, "%s(%lld, %lld)\n", __func__, size, align);
|
||||
|
||||
if (__offload_myoLoadLibrary()) {
|
||||
return myo_wrapper.SharedAlignedMalloc(size, align);
|
||||
}
|
||||
else {
|
||||
if (align < sizeof(void*)) {
|
||||
align = sizeof(void*);
|
||||
}
|
||||
return _mm_malloc(size, align);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void _Offload_shared_aligned_free(void *ptr)
|
||||
{
|
||||
OFFLOAD_DEBUG_TRACE(3, "%s(%p)\n", __func__, ptr);
|
||||
|
||||
if (__offload_myoLoadLibrary()) {
|
||||
myo_wrapper.SharedAlignedFree(ptr);
|
||||
}
|
||||
else {
|
||||
_mm_free(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void __intel_cilk_for_32_offload(
|
||||
int size,
|
||||
void (*copy_constructor)(void*, void*),
|
||||
int target_number,
|
||||
void *raddr,
|
||||
void *closure_object,
|
||||
unsigned int iters,
|
||||
unsigned int grain_size)
|
||||
{
|
||||
OFFLOAD_DEBUG_TRACE(3, "%s\n", __func__);
|
||||
|
||||
target_number = __offload_myoIsAvailable(target_number);
|
||||
if (target_number >= 0) {
|
||||
struct S {
|
||||
void *M1;
|
||||
unsigned int M2;
|
||||
unsigned int M3;
|
||||
char closure[];
|
||||
} *args;
|
||||
|
||||
args = (struct S*) _Offload_shared_malloc(sizeof(struct S) + size);
|
||||
args->M1 = raddr;
|
||||
args->M2 = iters;
|
||||
args->M3 = grain_size;
|
||||
|
||||
if (copy_constructor == 0) {
|
||||
memcpy(args->closure, closure_object, size);
|
||||
}
|
||||
else {
|
||||
copy_constructor(args->closure, closure_object);
|
||||
}
|
||||
|
||||
myo_wrapper.Release();
|
||||
myo_wrapper.GetResult(
|
||||
myo_wrapper.RemoteCall("__intel_cilk_for_32_offload",
|
||||
args, target_number)
|
||||
);
|
||||
myo_wrapper.Acquire();
|
||||
|
||||
_Offload_shared_free(args);
|
||||
|
||||
ORSL::release(target_number);
|
||||
}
|
||||
else {
|
||||
__cilkrts_cilk_for_32(raddr,
|
||||
closure_object,
|
||||
iters,
|
||||
grain_size);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void __intel_cilk_for_64_offload(
|
||||
int size,
|
||||
void (*copy_constructor)(void*, void*),
|
||||
int target_number,
|
||||
void *raddr,
|
||||
void *closure_object,
|
||||
uint64_t iters,
|
||||
uint64_t grain_size)
|
||||
{
|
||||
OFFLOAD_DEBUG_TRACE(3, "%s\n", __func__);
|
||||
|
||||
target_number = __offload_myoIsAvailable(target_number);
|
||||
if (target_number >= 0) {
|
||||
struct S {
|
||||
void *M1;
|
||||
uint64_t M2;
|
||||
uint64_t M3;
|
||||
char closure[];
|
||||
} *args;
|
||||
|
||||
args = (struct S*) _Offload_shared_malloc(sizeof(struct S) + size);
|
||||
args->M1 = raddr;
|
||||
args->M2 = iters;
|
||||
args->M3 = grain_size;
|
||||
|
||||
if (copy_constructor == 0) {
|
||||
memcpy(args->closure, closure_object, size);
|
||||
}
|
||||
else {
|
||||
copy_constructor(args->closure, closure_object);
|
||||
}
|
||||
|
||||
myo_wrapper.Release();
|
||||
myo_wrapper.GetResult(
|
||||
myo_wrapper.RemoteCall("__intel_cilk_for_64_offload", args,
|
||||
target_number)
|
||||
);
|
||||
myo_wrapper.Acquire();
|
||||
|
||||
_Offload_shared_free(args);
|
||||
|
||||
ORSL::release(target_number);
|
||||
}
|
||||
else {
|
||||
__cilkrts_cilk_for_64(raddr,
|
||||
closure_object,
|
||||
iters,
|
||||
grain_size);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 OFFLOAD_MYO_HOST_H_INCLUDED
|
||||
#define OFFLOAD_MYO_HOST_H_INCLUDED
|
||||
|
||||
#include <myotypes.h>
|
||||
#include <myoimpl.h>
|
||||
#include <myo.h>
|
||||
#include "offload.h"
|
||||
|
||||
typedef MyoiSharedVarEntry SharedTableEntry;
|
||||
//typedef MyoiHostSharedFptrEntry FptrTableEntry;
|
||||
typedef struct {
|
||||
//! Function Name
|
||||
const char *funcName;
|
||||
//! Function Address
|
||||
void *funcAddr;
|
||||
//! Local Thunk Address
|
||||
void *localThunkAddr;
|
||||
#ifdef TARGET_WINNT
|
||||
// Dummy to pad up to 32 bytes
|
||||
void *dummy;
|
||||
#endif // TARGET_WINNT
|
||||
} FptrTableEntry;
|
||||
|
||||
struct InitTableEntry {
|
||||
#ifdef TARGET_WINNT
|
||||
// Dummy to pad up to 16 bytes
|
||||
// Function Name
|
||||
const char *funcName;
|
||||
#endif // TARGET_WINNT
|
||||
void (*func)(void);
|
||||
};
|
||||
|
||||
#ifdef TARGET_WINNT
|
||||
#define OFFLOAD_MYO_SHARED_TABLE_SECTION_START ".MyoSharedTable$a"
|
||||
#define OFFLOAD_MYO_SHARED_TABLE_SECTION_END ".MyoSharedTable$z"
|
||||
|
||||
#define OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_START ".MyoSharedInitTable$a"
|
||||
#define OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_END ".MyoSharedInitTable$z"
|
||||
|
||||
#define OFFLOAD_MYO_FPTR_TABLE_SECTION_START ".MyoFptrTable$a"
|
||||
#define OFFLOAD_MYO_FPTR_TABLE_SECTION_END ".MyoFptrTable$z"
|
||||
#else // TARGET_WINNT
|
||||
#define OFFLOAD_MYO_SHARED_TABLE_SECTION_START ".MyoSharedTable."
|
||||
#define OFFLOAD_MYO_SHARED_TABLE_SECTION_END ".MyoSharedTable."
|
||||
|
||||
#define OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_START ".MyoSharedInitTable."
|
||||
#define OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_END ".MyoSharedInitTable."
|
||||
|
||||
#define OFFLOAD_MYO_FPTR_TABLE_SECTION_START ".MyoFptrTable."
|
||||
#define OFFLOAD_MYO_FPTR_TABLE_SECTION_END ".MyoFptrTable."
|
||||
#endif // TARGET_WINNT
|
||||
|
||||
#pragma section(OFFLOAD_MYO_SHARED_TABLE_SECTION_START, read, write)
|
||||
#pragma section(OFFLOAD_MYO_SHARED_TABLE_SECTION_END, read, write)
|
||||
|
||||
#pragma section(OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_START, read, write)
|
||||
#pragma section(OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_END, read, write)
|
||||
|
||||
#pragma section(OFFLOAD_MYO_FPTR_TABLE_SECTION_START, read, write)
|
||||
#pragma section(OFFLOAD_MYO_FPTR_TABLE_SECTION_END, read, write)
|
||||
|
||||
extern "C" void __offload_myoRegisterTables(
|
||||
InitTableEntry *init_table,
|
||||
SharedTableEntry *shared_table,
|
||||
FptrTableEntry *fptr_table
|
||||
);
|
||||
|
||||
extern void __offload_myoFini(void);
|
||||
|
||||
#endif // OFFLOAD_MYO_HOST_H_INCLUDED
|
||||
@@ -0,0 +1,184 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 "offload_myo_target.h"
|
||||
#include "offload_target.h"
|
||||
|
||||
extern "C" void __cilkrts_cilk_for_32(void*, void*, uint32_t, int32_t);
|
||||
extern "C" void __cilkrts_cilk_for_64(void*, void*, uint64_t, int32_t);
|
||||
|
||||
#pragma weak __cilkrts_cilk_for_32
|
||||
#pragma weak __cilkrts_cilk_for_64
|
||||
|
||||
static void CheckResult(const char *func, MyoError error) {
|
||||
if (error != MYO_SUCCESS) {
|
||||
LIBOFFLOAD_ERROR(c_myotarget_checkresult, func, error);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void __offload_myo_shared_table_register(SharedTableEntry *entry)
|
||||
{
|
||||
int entries = 0;
|
||||
SharedTableEntry *t_start;
|
||||
|
||||
OFFLOAD_DEBUG_TRACE(3, "%s(%p)\n", __func__, entry);
|
||||
|
||||
t_start = entry;
|
||||
while (t_start->varName != 0) {
|
||||
OFFLOAD_DEBUG_TRACE_1(4, 0, c_offload_mic_myo_shared,
|
||||
"myo shared entry name = \"%s\" addr = %p\n",
|
||||
t_start->varName, t_start->sharedAddr);
|
||||
t_start++;
|
||||
entries++;
|
||||
}
|
||||
|
||||
if (entries > 0) {
|
||||
OFFLOAD_DEBUG_TRACE(3, "myoiMicVarTableRegister(%p, %d)\n", entry,
|
||||
entries);
|
||||
CheckResult("myoiMicVarTableRegister",
|
||||
myoiMicVarTableRegister(entry, entries));
|
||||
}
|
||||
}
|
||||
|
||||
static void __offload_myo_fptr_table_register(
|
||||
FptrTableEntry *entry
|
||||
)
|
||||
{
|
||||
int entries = 0;
|
||||
FptrTableEntry *t_start;
|
||||
|
||||
OFFLOAD_DEBUG_TRACE(3, "%s(%p)\n", __func__, entry);
|
||||
|
||||
t_start = entry;
|
||||
while (t_start->funcName != 0) {
|
||||
OFFLOAD_DEBUG_TRACE_1(4, 0, c_offload_mic_myo_fptr,
|
||||
"myo fptr entry name = \"%s\" addr = %p\n",
|
||||
t_start->funcName, t_start->funcAddr);
|
||||
t_start++;
|
||||
entries++;
|
||||
}
|
||||
|
||||
if (entries > 0) {
|
||||
OFFLOAD_DEBUG_TRACE(3, "myoiTargetFptrTableRegister(%p, %d, 0)\n",
|
||||
entry, entries);
|
||||
CheckResult("myoiTargetFptrTableRegister",
|
||||
myoiTargetFptrTableRegister(entry, entries, 0));
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void __offload_myoAcquire(void)
|
||||
{
|
||||
OFFLOAD_DEBUG_TRACE(3, "%s\n", __func__);
|
||||
CheckResult("myoAcquire", myoAcquire());
|
||||
}
|
||||
|
||||
extern "C" void __offload_myoRelease(void)
|
||||
{
|
||||
OFFLOAD_DEBUG_TRACE(3, "%s\n", __func__);
|
||||
CheckResult("myoRelease", myoRelease());
|
||||
}
|
||||
|
||||
extern "C" void __intel_cilk_for_32_offload_wrapper(void *args_)
|
||||
{
|
||||
OFFLOAD_DEBUG_TRACE(3, "%s\n", __func__);
|
||||
|
||||
struct S {
|
||||
void *M1;
|
||||
unsigned int M2;
|
||||
unsigned int M3;
|
||||
char closure[];
|
||||
} *args = (struct S*) args_;
|
||||
|
||||
__cilkrts_cilk_for_32(args->M1, args->closure, args->M2, args->M3);
|
||||
}
|
||||
|
||||
extern "C" void __intel_cilk_for_64_offload_wrapper(void *args_)
|
||||
{
|
||||
OFFLOAD_DEBUG_TRACE(3, "%s\n", __func__);
|
||||
|
||||
struct S {
|
||||
void *M1;
|
||||
uint64_t M2;
|
||||
uint64_t M3;
|
||||
char closure[];
|
||||
} *args = (struct S*) args_;
|
||||
|
||||
__cilkrts_cilk_for_64(args->M1, args->closure, args->M2, args->M3);
|
||||
}
|
||||
|
||||
static void __offload_myo_once_init(void)
|
||||
{
|
||||
CheckResult("myoiRemoteFuncRegister",
|
||||
myoiRemoteFuncRegister(
|
||||
(MyoiRemoteFuncType) __intel_cilk_for_32_offload_wrapper,
|
||||
"__intel_cilk_for_32_offload"));
|
||||
CheckResult("myoiRemoteFuncRegister",
|
||||
myoiRemoteFuncRegister(
|
||||
(MyoiRemoteFuncType) __intel_cilk_for_64_offload_wrapper,
|
||||
"__intel_cilk_for_64_offload"));
|
||||
}
|
||||
|
||||
extern "C" void __offload_myoRegisterTables(
|
||||
SharedTableEntry *shared_table,
|
||||
FptrTableEntry *fptr_table
|
||||
)
|
||||
{
|
||||
OFFLOAD_DEBUG_TRACE(3, "%s\n", __func__);
|
||||
|
||||
// one time registration of Intel(R) Cilk(TM) language entries
|
||||
static pthread_once_t once_control = PTHREAD_ONCE_INIT;
|
||||
pthread_once(&once_control, __offload_myo_once_init);
|
||||
|
||||
// register module's tables
|
||||
if (shared_table->varName == 0 && fptr_table->funcName == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
__offload_myo_shared_table_register(shared_table);
|
||||
__offload_myo_fptr_table_register(fptr_table);
|
||||
}
|
||||
|
||||
extern "C" void* _Offload_shared_malloc(size_t size)
|
||||
{
|
||||
OFFLOAD_DEBUG_TRACE(3, "%s(%lld)\n", __func__, size);
|
||||
return myoSharedMalloc(size);
|
||||
}
|
||||
|
||||
extern "C" void _Offload_shared_free(void *ptr)
|
||||
{
|
||||
OFFLOAD_DEBUG_TRACE(3, "%s(%p)\n", __func__, ptr);
|
||||
myoSharedFree(ptr);
|
||||
}
|
||||
|
||||
extern "C" void* _Offload_shared_aligned_malloc(size_t size, size_t align)
|
||||
{
|
||||
OFFLOAD_DEBUG_TRACE(3, "%s(%lld, %lld)\n", __func__, size, align);
|
||||
return myoSharedAlignedMalloc(size, align);
|
||||
}
|
||||
|
||||
extern "C" void _Offload_shared_aligned_free(void *ptr)
|
||||
{
|
||||
OFFLOAD_DEBUG_TRACE(3, "%s(%p)\n", __func__, ptr);
|
||||
myoSharedAlignedFree(ptr);
|
||||
}
|
||||
|
||||
// temporary workaround for blocking behavior of myoiLibInit/Fini calls
|
||||
extern "C" void __offload_myoLibInit()
|
||||
{
|
||||
OFFLOAD_DEBUG_TRACE(3, "%s()\n", __func__);
|
||||
CheckResult("myoiLibInit", myoiLibInit(0, 0));
|
||||
}
|
||||
|
||||
extern "C" void __offload_myoLibFini()
|
||||
{
|
||||
OFFLOAD_DEBUG_TRACE(3, "%s()\n", __func__);
|
||||
myoiLibFini();
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 OFFLOAD_MYO_TARGET_H_INCLUDED
|
||||
#define OFFLOAD_MYO_TARGET_H_INCLUDED
|
||||
|
||||
#include <myotypes.h>
|
||||
#include <myoimpl.h>
|
||||
#include <myo.h>
|
||||
#include "offload.h"
|
||||
|
||||
typedef MyoiSharedVarEntry SharedTableEntry;
|
||||
typedef MyoiTargetSharedFptrEntry FptrTableEntry;
|
||||
|
||||
#ifdef TARGET_WINNT
|
||||
#define OFFLOAD_MYO_SHARED_TABLE_SECTION_START ".MyoSharedTable$a"
|
||||
#define OFFLOAD_MYO_SHARED_TABLE_SECTION_END ".MyoSharedTable$z"
|
||||
|
||||
#define OFFLOAD_MYO_FPTR_TABLE_SECTION_START ".MyoFptrTable$a"
|
||||
#define OFFLOAD_MYO_FPTR_TABLE_SECTION_END ".MyoFptrTable$z"
|
||||
#else // TARGET_WINNT
|
||||
#define OFFLOAD_MYO_SHARED_TABLE_SECTION_START ".MyoSharedTable."
|
||||
#define OFFLOAD_MYO_SHARED_TABLE_SECTION_END ".MyoSharedTable."
|
||||
|
||||
#define OFFLOAD_MYO_FPTR_TABLE_SECTION_START ".MyoFptrTable."
|
||||
#define OFFLOAD_MYO_FPTR_TABLE_SECTION_END ".MyoFptrTable."
|
||||
#endif // TARGET_WINNT
|
||||
|
||||
#pragma section(OFFLOAD_MYO_SHARED_TABLE_SECTION_START, read, write)
|
||||
#pragma section(OFFLOAD_MYO_SHARED_TABLE_SECTION_END, read, write)
|
||||
|
||||
#pragma section(OFFLOAD_MYO_FPTR_TABLE_SECTION_START, read, write)
|
||||
#pragma section(OFFLOAD_MYO_FPTR_TABLE_SECTION_END, read, write)
|
||||
|
||||
extern "C" void __offload_myoRegisterTables(
|
||||
SharedTableEntry *shared_table,
|
||||
FptrTableEntry *fptr_table
|
||||
);
|
||||
|
||||
extern "C" void __offload_myoAcquire(void);
|
||||
extern "C" void __offload_myoRelease(void);
|
||||
|
||||
// temporary workaround for blocking behavior for myoiLibInit/Fini calls
|
||||
extern "C" void __offload_myoLibInit();
|
||||
extern "C" void __offload_myoLibFini();
|
||||
|
||||
#endif // OFFLOAD_MYO_TARGET_H_INCLUDED
|
||||
@@ -0,0 +1,851 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 <omp.h>
|
||||
#include "offload.h"
|
||||
#include "compiler_if_host.h"
|
||||
|
||||
// OpenMP API
|
||||
|
||||
void omp_set_default_device(int num)
|
||||
{
|
||||
if (num >= 0) {
|
||||
__omp_device_num = num;
|
||||
}
|
||||
}
|
||||
|
||||
int omp_get_default_device(void)
|
||||
{
|
||||
return __omp_device_num;
|
||||
}
|
||||
|
||||
int omp_get_num_devices()
|
||||
{
|
||||
__offload_init_library();
|
||||
return mic_engines_total;
|
||||
}
|
||||
|
||||
// OpenMP API wrappers
|
||||
|
||||
static void omp_set_int_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
int setting,
|
||||
const char* f_name
|
||||
)
|
||||
{
|
||||
OFFLOAD ofld = OFFLOAD_TARGET_ACQUIRE(target_type, target_number, 0, NULL,
|
||||
f_name, 0);
|
||||
if (ofld) {
|
||||
VarDesc vars[1] = {0};
|
||||
|
||||
vars[0].type.src = c_data;
|
||||
vars[0].type.dst = c_data;
|
||||
vars[0].direction.bits = c_parameter_in;
|
||||
vars[0].size = sizeof(int);
|
||||
vars[0].count = 1;
|
||||
vars[0].ptr = &setting;
|
||||
|
||||
OFFLOAD_OFFLOAD(ofld, f_name, 0, 1, vars, NULL, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static int omp_get_int_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
const char * f_name
|
||||
)
|
||||
{
|
||||
int setting = 0;
|
||||
|
||||
OFFLOAD ofld = OFFLOAD_TARGET_ACQUIRE(target_type, target_number, 0, NULL,
|
||||
f_name, 0);
|
||||
if (ofld) {
|
||||
VarDesc vars[1] = {0};
|
||||
|
||||
vars[0].type.src = c_data;
|
||||
vars[0].type.dst = c_data;
|
||||
vars[0].direction.bits = c_parameter_out;
|
||||
vars[0].size = sizeof(int);
|
||||
vars[0].count = 1;
|
||||
vars[0].ptr = &setting;
|
||||
|
||||
OFFLOAD_OFFLOAD(ofld, f_name, 0, 1, vars, NULL, 0, 0, 0);
|
||||
}
|
||||
return setting;
|
||||
}
|
||||
|
||||
void omp_set_num_threads_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
int num_threads
|
||||
)
|
||||
{
|
||||
omp_set_int_target(target_type, target_number, num_threads,
|
||||
"omp_set_num_threads_target");
|
||||
}
|
||||
|
||||
int omp_get_max_threads_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number
|
||||
)
|
||||
{
|
||||
return omp_get_int_target(target_type, target_number,
|
||||
"omp_get_max_threads_target");
|
||||
}
|
||||
|
||||
int omp_get_num_procs_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number
|
||||
)
|
||||
{
|
||||
return omp_get_int_target(target_type, target_number,
|
||||
"omp_get_num_procs_target");
|
||||
}
|
||||
|
||||
void omp_set_dynamic_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
int num_threads
|
||||
)
|
||||
{
|
||||
omp_set_int_target(target_type, target_number, num_threads,
|
||||
"omp_set_dynamic_target");
|
||||
}
|
||||
|
||||
int omp_get_dynamic_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number
|
||||
)
|
||||
{
|
||||
return omp_get_int_target(target_type, target_number,
|
||||
"omp_get_dynamic_target");
|
||||
}
|
||||
|
||||
void omp_set_nested_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
int nested
|
||||
)
|
||||
{
|
||||
omp_set_int_target(target_type, target_number, nested,
|
||||
"omp_set_nested_target");
|
||||
}
|
||||
|
||||
int omp_get_nested_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number
|
||||
)
|
||||
{
|
||||
return omp_get_int_target(target_type, target_number,
|
||||
"omp_get_nested_target");
|
||||
}
|
||||
|
||||
void omp_set_schedule_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
omp_sched_t kind,
|
||||
int modifier
|
||||
)
|
||||
{
|
||||
OFFLOAD ofld = OFFLOAD_TARGET_ACQUIRE(target_type, target_number, 0, NULL,
|
||||
__func__, 0);
|
||||
if (ofld != 0) {
|
||||
VarDesc vars[2] = {0};
|
||||
|
||||
vars[0].type.src = c_data;
|
||||
vars[0].type.dst = c_data;
|
||||
vars[0].direction.bits = c_parameter_in;
|
||||
vars[0].size = sizeof(omp_sched_t);
|
||||
vars[0].count = 1;
|
||||
vars[0].ptr = &kind;
|
||||
|
||||
vars[1].type.src = c_data;
|
||||
vars[1].type.dst = c_data;
|
||||
vars[1].direction.bits = c_parameter_in;
|
||||
vars[1].size = sizeof(int);
|
||||
vars[1].count = 1;
|
||||
vars[1].ptr = &modifier;
|
||||
|
||||
OFFLOAD_OFFLOAD(ofld, "omp_set_schedule_target",
|
||||
0, 2, vars, NULL, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void omp_get_schedule_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
omp_sched_t *kind,
|
||||
int *modifier
|
||||
)
|
||||
{
|
||||
OFFLOAD ofld = OFFLOAD_TARGET_ACQUIRE(target_type, target_number, 0, NULL,
|
||||
__func__, 0);
|
||||
if (ofld != 0) {
|
||||
VarDesc vars[2] = {0};
|
||||
|
||||
vars[0].type.src = c_data;
|
||||
vars[0].type.dst = c_data;
|
||||
vars[0].direction.bits = c_parameter_out;
|
||||
vars[0].size = sizeof(omp_sched_t);
|
||||
vars[0].count = 1;
|
||||
vars[0].ptr = kind;
|
||||
|
||||
vars[1].type.src = c_data;
|
||||
vars[1].type.dst = c_data;
|
||||
vars[1].direction.bits = c_parameter_out;
|
||||
vars[1].size = sizeof(int);
|
||||
vars[1].count = 1;
|
||||
vars[1].ptr = modifier;
|
||||
|
||||
OFFLOAD_OFFLOAD(ofld, "omp_get_schedule_target",
|
||||
0, 2, vars, NULL, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// lock API functions
|
||||
|
||||
void omp_init_lock_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
omp_lock_target_t *lock
|
||||
)
|
||||
{
|
||||
OFFLOAD ofld = OFFLOAD_TARGET_ACQUIRE(target_type, target_number, 0, NULL,
|
||||
__func__, 0);
|
||||
if (ofld != 0) {
|
||||
VarDesc vars[1] = {0};
|
||||
|
||||
vars[0].type.src = c_data;
|
||||
vars[0].type.dst = c_data;
|
||||
vars[0].direction.bits = c_parameter_out;
|
||||
vars[0].size = sizeof(omp_lock_target_t);
|
||||
vars[0].count = 1;
|
||||
vars[0].ptr = lock;
|
||||
|
||||
OFFLOAD_OFFLOAD(ofld, "omp_init_lock_target",
|
||||
0, 1, vars, NULL, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void omp_destroy_lock_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
omp_lock_target_t *lock
|
||||
)
|
||||
{
|
||||
OFFLOAD ofld = OFFLOAD_TARGET_ACQUIRE(target_type, target_number, 0, NULL,
|
||||
__func__, 0);
|
||||
if (ofld != 0) {
|
||||
VarDesc vars[1] = {0};
|
||||
|
||||
vars[0].type.src = c_data;
|
||||
vars[0].type.dst = c_data;
|
||||
vars[0].direction.bits = c_parameter_in;
|
||||
vars[0].size = sizeof(omp_lock_target_t);
|
||||
vars[0].count = 1;
|
||||
vars[0].ptr = lock;
|
||||
|
||||
OFFLOAD_OFFLOAD(ofld, "omp_destroy_lock_target",
|
||||
0, 1, vars, NULL, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void omp_set_lock_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
omp_lock_target_t *lock
|
||||
)
|
||||
{
|
||||
OFFLOAD ofld = OFFLOAD_TARGET_ACQUIRE(target_type, target_number, 0, NULL,
|
||||
__func__, 0);
|
||||
if (ofld != 0) {
|
||||
VarDesc vars[1] = {0};
|
||||
|
||||
vars[0].type.src = c_data;
|
||||
vars[0].type.dst = c_data;
|
||||
vars[0].direction.bits = c_parameter_inout;
|
||||
vars[0].size = sizeof(omp_lock_target_t);
|
||||
vars[0].count = 1;
|
||||
vars[0].ptr = lock;
|
||||
|
||||
OFFLOAD_OFFLOAD(ofld, "omp_set_lock_target",
|
||||
0, 1, vars, NULL, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void omp_unset_lock_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
omp_lock_target_t *lock
|
||||
)
|
||||
{
|
||||
OFFLOAD ofld = OFFLOAD_TARGET_ACQUIRE(target_type, target_number, 0, NULL,
|
||||
__func__, 0);
|
||||
if (ofld != 0) {
|
||||
VarDesc vars[1] = {0};
|
||||
|
||||
vars[0].type.src = c_data;
|
||||
vars[0].type.dst = c_data;
|
||||
vars[0].direction.bits = c_parameter_inout;
|
||||
vars[0].size = sizeof(omp_lock_target_t);
|
||||
vars[0].count = 1;
|
||||
vars[0].ptr = lock;
|
||||
|
||||
OFFLOAD_OFFLOAD(ofld, "omp_unset_lock_target",
|
||||
0, 1, vars, NULL, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
int omp_test_lock_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
omp_lock_target_t *lock
|
||||
)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
OFFLOAD ofld = OFFLOAD_TARGET_ACQUIRE(target_type, target_number, 0, NULL,
|
||||
__func__, 0);
|
||||
if (ofld != 0) {
|
||||
VarDesc vars[2] = {0};
|
||||
|
||||
vars[0].type.src = c_data;
|
||||
vars[0].type.dst = c_data;
|
||||
vars[0].direction.bits = c_parameter_inout;
|
||||
vars[0].size = sizeof(omp_lock_target_t);
|
||||
vars[0].count = 1;
|
||||
vars[0].ptr = lock;
|
||||
|
||||
vars[1].type.src = c_data;
|
||||
vars[1].type.dst = c_data;
|
||||
vars[1].direction.bits = c_parameter_out;
|
||||
vars[1].size = sizeof(int);
|
||||
vars[1].count = 1;
|
||||
vars[1].ptr = &result;
|
||||
|
||||
OFFLOAD_OFFLOAD(ofld, "omp_test_lock_target",
|
||||
0, 2, vars, NULL, 0, 0, 0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// nested lock API functions
|
||||
|
||||
void omp_init_nest_lock_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
omp_nest_lock_target_t *lock
|
||||
)
|
||||
{
|
||||
OFFLOAD ofld = OFFLOAD_TARGET_ACQUIRE(target_type, target_number, 0, NULL,
|
||||
__func__, 0);
|
||||
if (ofld != 0) {
|
||||
VarDesc vars[1] = {0};
|
||||
|
||||
vars[0].type.src = c_data;
|
||||
vars[0].type.dst = c_data;
|
||||
vars[0].direction.bits = c_parameter_out;
|
||||
vars[0].size = sizeof(omp_nest_lock_target_t);
|
||||
vars[0].count = 1;
|
||||
vars[0].ptr = lock;
|
||||
|
||||
OFFLOAD_OFFLOAD(ofld, "omp_init_nest_lock_target",
|
||||
0, 1, vars, NULL, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void omp_destroy_nest_lock_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
omp_nest_lock_target_t *lock
|
||||
)
|
||||
{
|
||||
OFFLOAD ofld = OFFLOAD_TARGET_ACQUIRE(target_type, target_number, 0, NULL,
|
||||
__func__, 0);
|
||||
if (ofld != 0) {
|
||||
VarDesc vars[1] = {0};
|
||||
|
||||
vars[0].type.src = c_data;
|
||||
vars[0].type.dst = c_data;
|
||||
vars[0].direction.bits = c_parameter_in;
|
||||
vars[0].size = sizeof(omp_nest_lock_target_t);
|
||||
vars[0].count = 1;
|
||||
vars[0].ptr = lock;
|
||||
|
||||
OFFLOAD_OFFLOAD(ofld, "omp_destroy_nest_lock_target",
|
||||
0, 1, vars, NULL, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void omp_set_nest_lock_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
omp_nest_lock_target_t *lock
|
||||
)
|
||||
{
|
||||
OFFLOAD ofld = OFFLOAD_TARGET_ACQUIRE(target_type, target_number, 0, NULL,
|
||||
__func__, 0);
|
||||
if (ofld != 0) {
|
||||
VarDesc vars[1] = {0};
|
||||
|
||||
vars[0].type.src = c_data;
|
||||
vars[0].type.dst = c_data;
|
||||
vars[0].direction.bits = c_parameter_inout;
|
||||
vars[0].size = sizeof(omp_nest_lock_target_t);
|
||||
vars[0].count = 1;
|
||||
vars[0].ptr = lock;
|
||||
|
||||
OFFLOAD_OFFLOAD(ofld, "omp_set_nest_lock_target",
|
||||
0, 1, vars, NULL, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void omp_unset_nest_lock_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
omp_nest_lock_target_t *lock
|
||||
)
|
||||
{
|
||||
OFFLOAD ofld = OFFLOAD_TARGET_ACQUIRE(target_type, target_number, 0, NULL,
|
||||
__func__, 0);
|
||||
if (ofld != 0) {
|
||||
VarDesc vars[1] = {0};
|
||||
|
||||
vars[0].type.src = c_data;
|
||||
vars[0].type.dst = c_data;
|
||||
vars[0].direction.bits = c_parameter_inout;
|
||||
vars[0].size = sizeof(omp_nest_lock_target_t);
|
||||
vars[0].count = 1;
|
||||
vars[0].ptr = lock;
|
||||
|
||||
OFFLOAD_OFFLOAD(ofld, "omp_unset_nest_lock_target",
|
||||
0, 1, vars, NULL, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
int omp_test_nest_lock_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
omp_nest_lock_target_t *lock
|
||||
)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
OFFLOAD ofld = OFFLOAD_TARGET_ACQUIRE(target_type, target_number, 0, NULL,
|
||||
__func__, 0);
|
||||
if (ofld != 0) {
|
||||
VarDesc vars[2] = {0};
|
||||
|
||||
vars[0].type.src = c_data;
|
||||
vars[0].type.dst = c_data;
|
||||
vars[0].direction.bits = c_parameter_inout;
|
||||
vars[0].size = sizeof(omp_nest_lock_target_t);
|
||||
vars[0].count = 1;
|
||||
vars[0].ptr = lock;
|
||||
|
||||
vars[1].type.src = c_data;
|
||||
vars[1].type.dst = c_data;
|
||||
vars[1].direction.bits = c_parameter_out;
|
||||
vars[1].size = sizeof(int);
|
||||
vars[1].count = 1;
|
||||
vars[1].ptr = &result;
|
||||
|
||||
OFFLOAD_OFFLOAD(ofld, "omp_test_nest_lock_target",
|
||||
0, 2, vars, NULL, 0, 0, 0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// kmp API functions
|
||||
|
||||
void kmp_set_stacksize_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
int size
|
||||
)
|
||||
{
|
||||
omp_set_int_target(target_type, target_number, size,
|
||||
"kmp_set_stacksize_target");
|
||||
}
|
||||
|
||||
int kmp_get_stacksize_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number
|
||||
)
|
||||
{
|
||||
return omp_get_int_target(target_type, target_number,
|
||||
"kmp_get_stacksize_target");
|
||||
}
|
||||
|
||||
void kmp_set_stacksize_s_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
size_t size
|
||||
)
|
||||
{
|
||||
omp_set_int_target(target_type, target_number, size,
|
||||
"kmp_set_stacksize_s_target");
|
||||
}
|
||||
|
||||
size_t kmp_get_stacksize_s_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number
|
||||
)
|
||||
{
|
||||
return omp_get_int_target(target_type, target_number,
|
||||
"kmp_get_stacksize_s_target");
|
||||
}
|
||||
|
||||
void kmp_set_blocktime_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
int time
|
||||
)
|
||||
{
|
||||
omp_set_int_target(target_type, target_number, time,
|
||||
"kmp_set_blocktime_target");
|
||||
}
|
||||
|
||||
int kmp_get_blocktime_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number
|
||||
)
|
||||
{
|
||||
return omp_get_int_target(target_type, target_number,
|
||||
"kmp_get_blocktime_target");
|
||||
}
|
||||
|
||||
void kmp_set_library_serial_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number
|
||||
)
|
||||
{
|
||||
OFFLOAD ofld = OFFLOAD_TARGET_ACQUIRE(target_type, target_number, 0, NULL,
|
||||
__func__, 0);
|
||||
if (ofld != 0) {
|
||||
OFFLOAD_OFFLOAD(ofld, "kmp_set_library_serial_target",
|
||||
0, 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void kmp_set_library_turnaround_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number
|
||||
)
|
||||
{
|
||||
OFFLOAD ofld = OFFLOAD_TARGET_ACQUIRE(target_type, target_number, 0, NULL,
|
||||
__func__, 0);
|
||||
if (ofld != 0) {
|
||||
OFFLOAD_OFFLOAD(ofld, "kmp_set_library_turnaround_target",
|
||||
0, 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void kmp_set_library_throughput_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number
|
||||
)
|
||||
{
|
||||
OFFLOAD ofld = OFFLOAD_TARGET_ACQUIRE(target_type, target_number, 0, NULL,
|
||||
__func__, 0);
|
||||
if (ofld != 0) {
|
||||
OFFLOAD_OFFLOAD(ofld, "kmp_set_library_throughput_target",
|
||||
0, 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void kmp_set_library_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
int mode
|
||||
)
|
||||
{
|
||||
omp_set_int_target(target_type, target_number, mode,
|
||||
"kmp_set_library_target");
|
||||
}
|
||||
|
||||
int kmp_get_library_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number
|
||||
)
|
||||
{
|
||||
return omp_get_int_target(target_type, target_number,
|
||||
"kmp_get_library_target");
|
||||
}
|
||||
|
||||
void kmp_set_defaults_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
char const *defaults
|
||||
)
|
||||
{
|
||||
OFFLOAD ofld = OFFLOAD_TARGET_ACQUIRE(target_type, target_number, 0, NULL,
|
||||
__func__, 0);
|
||||
if (ofld != 0) {
|
||||
VarDesc vars[1] = {0};
|
||||
|
||||
vars[0].type.src = c_string_ptr;
|
||||
vars[0].type.dst = c_string_ptr;
|
||||
vars[0].direction.bits = c_parameter_in;
|
||||
vars[0].alloc_if = 1;
|
||||
vars[0].free_if = 1;
|
||||
vars[0].ptr = &defaults;
|
||||
|
||||
OFFLOAD_OFFLOAD(ofld, "kmp_set_defaults_target",
|
||||
0, 1, vars, NULL, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// affinity API functions
|
||||
|
||||
void kmp_create_affinity_mask_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
kmp_affinity_mask_target_t *mask
|
||||
)
|
||||
{
|
||||
OFFLOAD ofld = OFFLOAD_TARGET_ACQUIRE(target_type, target_number, 0, NULL,
|
||||
__func__, 0);
|
||||
if (ofld != 0) {
|
||||
VarDesc vars[1] = {0};
|
||||
|
||||
vars[0].type.src = c_data;
|
||||
vars[0].type.dst = c_data;
|
||||
vars[0].direction.bits = c_parameter_out;
|
||||
vars[0].size = sizeof(kmp_affinity_mask_target_t);
|
||||
vars[0].count = 1;
|
||||
vars[0].ptr = mask;
|
||||
|
||||
OFFLOAD_OFFLOAD(ofld, "kmp_create_affinity_mask_target",
|
||||
0, 1, vars, NULL, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void kmp_destroy_affinity_mask_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
kmp_affinity_mask_target_t *mask
|
||||
)
|
||||
{
|
||||
OFFLOAD ofld = OFFLOAD_TARGET_ACQUIRE(target_type, target_number, 0, NULL,
|
||||
__func__, 0);
|
||||
if (ofld != 0) {
|
||||
VarDesc vars[1] = {0};
|
||||
|
||||
vars[0].type.src = c_data;
|
||||
vars[0].type.dst = c_data;
|
||||
vars[0].direction.bits = c_parameter_in;
|
||||
vars[0].size = sizeof(kmp_affinity_mask_target_t);
|
||||
vars[0].count = 1;
|
||||
vars[0].ptr = mask;
|
||||
|
||||
OFFLOAD_OFFLOAD(ofld, "kmp_destroy_affinity_mask_target",
|
||||
0, 1, vars, NULL, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
int kmp_set_affinity_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
kmp_affinity_mask_target_t *mask
|
||||
)
|
||||
{
|
||||
int result = 1;
|
||||
|
||||
OFFLOAD ofld = OFFLOAD_TARGET_ACQUIRE(target_type, target_number, 0, NULL,
|
||||
__func__, 0);
|
||||
if (ofld != 0) {
|
||||
VarDesc vars[2] = {0};
|
||||
|
||||
vars[0].type.src = c_data;
|
||||
vars[0].type.dst = c_data;
|
||||
vars[0].direction.bits = c_parameter_in;
|
||||
vars[0].size = sizeof(kmp_affinity_mask_target_t);
|
||||
vars[0].count = 1;
|
||||
vars[0].ptr = mask;
|
||||
|
||||
vars[1].type.src = c_data;
|
||||
vars[1].type.dst = c_data;
|
||||
vars[1].direction.bits = c_parameter_out;
|
||||
vars[1].size = sizeof(int);
|
||||
vars[1].count = 1;
|
||||
vars[1].ptr = &result;
|
||||
|
||||
OFFLOAD_OFFLOAD(ofld, "kmp_set_affinity_target",
|
||||
0, 2, vars, NULL, 0, 0, 0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int kmp_get_affinity_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
kmp_affinity_mask_target_t *mask
|
||||
)
|
||||
{
|
||||
int result = 1;
|
||||
|
||||
OFFLOAD ofld = OFFLOAD_TARGET_ACQUIRE(target_type, target_number, 0, NULL,
|
||||
__func__, 0);
|
||||
if (ofld != 0) {
|
||||
VarDesc vars[2] = {0};
|
||||
|
||||
vars[0].type.src = c_data;
|
||||
vars[0].type.dst = c_data;
|
||||
vars[0].direction.bits = c_parameter_inout;
|
||||
vars[0].size = sizeof(kmp_affinity_mask_target_t);
|
||||
vars[0].count = 1;
|
||||
vars[0].ptr = mask;
|
||||
|
||||
vars[1].type.src = c_data;
|
||||
vars[1].type.dst = c_data;
|
||||
vars[1].direction.bits = c_parameter_out;
|
||||
vars[1].size = sizeof(int);
|
||||
vars[1].count = 1;
|
||||
vars[1].ptr = &result;
|
||||
|
||||
OFFLOAD_OFFLOAD(ofld, "kmp_get_affinity_target",
|
||||
0, 2, vars, NULL, 0, 0, 0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int kmp_get_affinity_max_proc_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number
|
||||
)
|
||||
{
|
||||
return omp_get_int_target(target_type, target_number,
|
||||
"kmp_get_affinity_max_proc_target");
|
||||
}
|
||||
|
||||
int kmp_set_affinity_mask_proc_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
int proc,
|
||||
kmp_affinity_mask_target_t *mask
|
||||
)
|
||||
{
|
||||
int result = 1;
|
||||
|
||||
OFFLOAD ofld = OFFLOAD_TARGET_ACQUIRE(target_type, target_number, 0, NULL,
|
||||
__func__, 0);
|
||||
if (ofld != 0) {
|
||||
VarDesc vars[3] = {0};
|
||||
|
||||
vars[0].type.src = c_data;
|
||||
vars[0].type.dst = c_data;
|
||||
vars[0].direction.bits = c_parameter_in;
|
||||
vars[0].size = sizeof(int);
|
||||
vars[0].count = 1;
|
||||
vars[0].ptr = &proc;
|
||||
|
||||
vars[1].type.src = c_data;
|
||||
vars[1].type.dst = c_data;
|
||||
vars[1].direction.bits = c_parameter_inout;
|
||||
vars[1].size = sizeof(kmp_affinity_mask_target_t);
|
||||
vars[1].count = 1;
|
||||
vars[1].ptr = mask;
|
||||
|
||||
vars[2].type.src = c_data;
|
||||
vars[2].type.dst = c_data;
|
||||
vars[2].direction.bits = c_parameter_out;
|
||||
vars[2].size = sizeof(int);
|
||||
vars[2].count = 1;
|
||||
vars[2].ptr = &result;
|
||||
|
||||
OFFLOAD_OFFLOAD(ofld, "kmp_set_affinity_mask_proc_target",
|
||||
0, 3, vars, NULL, 0, 0, 0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int kmp_unset_affinity_mask_proc_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
int proc,
|
||||
kmp_affinity_mask_target_t *mask
|
||||
)
|
||||
{
|
||||
int result = 1;
|
||||
|
||||
OFFLOAD ofld = OFFLOAD_TARGET_ACQUIRE(target_type, target_number, 0, NULL,
|
||||
__func__, 0);
|
||||
if (ofld != 0) {
|
||||
VarDesc vars[3] = {0};
|
||||
|
||||
vars[0].type.src = c_data;
|
||||
vars[0].type.dst = c_data;
|
||||
vars[0].direction.bits = c_parameter_in;
|
||||
vars[0].size = sizeof(int);
|
||||
vars[0].count = 1;
|
||||
vars[0].ptr = &proc;
|
||||
|
||||
vars[1].type.src = c_data;
|
||||
vars[1].type.dst = c_data;
|
||||
vars[1].direction.bits = c_parameter_inout;
|
||||
vars[1].size = sizeof(kmp_affinity_mask_target_t);
|
||||
vars[1].count = 1;
|
||||
vars[1].ptr = mask;
|
||||
|
||||
vars[2].type.src = c_data;
|
||||
vars[2].type.dst = c_data;
|
||||
vars[2].direction.bits = c_parameter_out;
|
||||
vars[2].size = sizeof(int);
|
||||
vars[2].count = 1;
|
||||
vars[2].ptr = &result;
|
||||
|
||||
OFFLOAD_OFFLOAD(ofld, "kmp_unset_affinity_mask_proc_target",
|
||||
0, 3, vars, NULL, 0, 0, 0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int kmp_get_affinity_mask_proc_target(
|
||||
TARGET_TYPE target_type,
|
||||
int target_number,
|
||||
int proc,
|
||||
kmp_affinity_mask_target_t *mask
|
||||
)
|
||||
{
|
||||
int result = 1;
|
||||
|
||||
OFFLOAD ofld = OFFLOAD_TARGET_ACQUIRE(target_type, target_number, 0, NULL,
|
||||
__func__, 0);
|
||||
if (ofld != 0) {
|
||||
VarDesc vars[3] = {0};
|
||||
|
||||
vars[0].type.src = c_data;
|
||||
vars[0].type.dst = c_data;
|
||||
vars[0].direction.bits = c_parameter_in;
|
||||
vars[0].size = sizeof(int);
|
||||
vars[0].count = 1;
|
||||
vars[0].ptr = &proc;
|
||||
|
||||
vars[1].type.src = c_data;
|
||||
vars[1].type.dst = c_data;
|
||||
vars[1].direction.bits = c_parameter_in;
|
||||
vars[1].size = sizeof(kmp_affinity_mask_target_t);
|
||||
vars[1].count = 1;
|
||||
vars[1].ptr = mask;
|
||||
|
||||
vars[2].type.src = c_data;
|
||||
vars[2].type.dst = c_data;
|
||||
vars[2].direction.bits = c_parameter_out;
|
||||
vars[2].size = sizeof(int);
|
||||
vars[2].count = 1;
|
||||
vars[2].ptr = &result;
|
||||
|
||||
OFFLOAD_OFFLOAD(ofld, "kmp_get_affinity_mask_proc_target",
|
||||
0, 3, vars, NULL, 0, 0, 0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,84 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 "offload_orsl.h"
|
||||
#include <stdlib.h>
|
||||
#include "offload_host.h"
|
||||
#include "orsl-lite/include/orsl-lite.h"
|
||||
|
||||
namespace ORSL {
|
||||
|
||||
static bool is_enabled = false;
|
||||
static const ORSLTag my_tag = "Offload";
|
||||
|
||||
void init()
|
||||
{
|
||||
const char *env_var = getenv("OFFLOAD_ENABLE_ORSL");
|
||||
if (env_var != 0 && *env_var != '\0') {
|
||||
int64_t new_val;
|
||||
if (__offload_parse_int_string(env_var, new_val)) {
|
||||
is_enabled = new_val;
|
||||
}
|
||||
else {
|
||||
LIBOFFLOAD_ERROR(c_invalid_env_var_int_value,
|
||||
"OFFLOAD_ENABLE_ORSL");
|
||||
}
|
||||
}
|
||||
|
||||
if (is_enabled) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "ORSL is enabled\n");
|
||||
}
|
||||
else {
|
||||
OFFLOAD_DEBUG_TRACE(2, "ORSL is disabled\n");
|
||||
}
|
||||
}
|
||||
|
||||
bool reserve(int device)
|
||||
{
|
||||
if (is_enabled) {
|
||||
int pnum = mic_engines[device].get_physical_index();
|
||||
ORSLBusySet bset;
|
||||
|
||||
bset.type = BUSY_SET_FULL;
|
||||
if (ORSLReserve(1, &pnum, &bset, my_tag) != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool try_reserve(int device)
|
||||
{
|
||||
if (is_enabled) {
|
||||
int pnum = mic_engines[device].get_physical_index();
|
||||
ORSLBusySet bset;
|
||||
|
||||
bset.type = BUSY_SET_FULL;
|
||||
if (ORSLTryReserve(1, &pnum, &bset, my_tag) != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void release(int device)
|
||||
{
|
||||
if (is_enabled) {
|
||||
int pnum = mic_engines[device].get_physical_index();
|
||||
ORSLBusySet bset;
|
||||
|
||||
bset.type = BUSY_SET_FULL;
|
||||
if (ORSLRelease(1, &pnum, &bset, my_tag) != 0) {
|
||||
// should never get here
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ORSL
|
||||
@@ -0,0 +1,25 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 OFFLOAD_ORSL_H_INCLUDED
|
||||
#define OFFLOAD_ORSL_H_INCLUDED
|
||||
|
||||
// ORSL interface
|
||||
namespace ORSL {
|
||||
|
||||
extern void init();
|
||||
|
||||
extern bool reserve(int device);
|
||||
extern bool try_reserve(int device);
|
||||
extern void release(int device);
|
||||
|
||||
} // namespace ORSL
|
||||
|
||||
#endif // OFFLOAD_ORSL_H_INCLUDED
|
||||
@@ -0,0 +1,375 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 "offload_table.h"
|
||||
#include "offload_common.h"
|
||||
|
||||
#if !HOST_LIBRARY
|
||||
// Predefined offload entries
|
||||
extern void omp_set_num_threads_lrb(void*);
|
||||
extern void omp_get_max_threads_lrb(void*);
|
||||
extern void omp_get_num_procs_lrb(void*);
|
||||
extern void omp_set_dynamic_lrb(void*);
|
||||
extern void omp_get_dynamic_lrb(void*);
|
||||
extern void omp_set_nested_lrb(void*);
|
||||
extern void omp_get_nested_lrb(void*);
|
||||
extern void omp_set_schedule_lrb(void*);
|
||||
extern void omp_get_schedule_lrb(void*);
|
||||
|
||||
extern void omp_init_lock_lrb(void*);
|
||||
extern void omp_destroy_lock_lrb(void*);
|
||||
extern void omp_set_lock_lrb(void*);
|
||||
extern void omp_unset_lock_lrb(void*);
|
||||
extern void omp_test_lock_lrb(void*);
|
||||
|
||||
extern void omp_init_nest_lock_lrb(void*);
|
||||
extern void omp_destroy_nest_lock_lrb(void*);
|
||||
extern void omp_set_nest_lock_lrb(void*);
|
||||
extern void omp_unset_nest_lock_lrb(void*);
|
||||
extern void omp_test_nest_lock_lrb(void*);
|
||||
|
||||
extern void kmp_set_stacksize_lrb(void*);
|
||||
extern void kmp_get_stacksize_lrb(void*);
|
||||
extern void kmp_set_stacksize_s_lrb(void*);
|
||||
extern void kmp_get_stacksize_s_lrb(void*);
|
||||
extern void kmp_set_blocktime_lrb(void*);
|
||||
extern void kmp_get_blocktime_lrb(void*);
|
||||
extern void kmp_set_library_serial_lrb(void*);
|
||||
extern void kmp_set_library_turnaround_lrb(void*);
|
||||
extern void kmp_set_library_throughput_lrb(void*);
|
||||
extern void kmp_set_library_lrb(void*);
|
||||
extern void kmp_get_library_lrb(void*);
|
||||
extern void kmp_set_defaults_lrb(void*);
|
||||
|
||||
extern void kmp_create_affinity_mask_lrb(void*);
|
||||
extern void kmp_destroy_affinity_mask_lrb(void*);
|
||||
extern void kmp_set_affinity_lrb(void*);
|
||||
extern void kmp_get_affinity_lrb(void*);
|
||||
extern void kmp_get_affinity_max_proc_lrb(void*);
|
||||
extern void kmp_set_affinity_mask_proc_lrb(void*);
|
||||
extern void kmp_unset_affinity_mask_proc_lrb(void*);
|
||||
extern void kmp_get_affinity_mask_proc_lrb(void*);
|
||||
|
||||
// Predefined entries on the target side
|
||||
static FuncTable::Entry predefined_entries[] = {
|
||||
"omp_set_num_threads_target",
|
||||
(void*) &omp_set_num_threads_lrb,
|
||||
"omp_get_max_threads_target",
|
||||
(void*) &omp_get_max_threads_lrb,
|
||||
"omp_get_num_procs_target",
|
||||
(void*) &omp_get_num_procs_lrb,
|
||||
"omp_set_dynamic_target",
|
||||
(void*) &omp_set_dynamic_lrb,
|
||||
"omp_get_dynamic_target",
|
||||
(void*) &omp_get_dynamic_lrb,
|
||||
"omp_set_nested_target",
|
||||
(void*) &omp_set_nested_lrb,
|
||||
"omp_get_nested_target",
|
||||
(void*) &omp_get_nested_lrb,
|
||||
"omp_set_schedule_target",
|
||||
(void*) &omp_set_schedule_lrb,
|
||||
"omp_get_schedule_target",
|
||||
(void*) &omp_get_schedule_lrb,
|
||||
|
||||
"omp_init_lock_target",
|
||||
(void*) &omp_init_lock_lrb,
|
||||
"omp_destroy_lock_target",
|
||||
(void*) &omp_destroy_lock_lrb,
|
||||
"omp_set_lock_target",
|
||||
(void*) &omp_set_lock_lrb,
|
||||
"omp_unset_lock_target",
|
||||
(void*) &omp_unset_lock_lrb,
|
||||
"omp_test_lock_target",
|
||||
(void*) &omp_test_lock_lrb,
|
||||
|
||||
"omp_init_nest_lock_target",
|
||||
(void*) &omp_init_nest_lock_lrb,
|
||||
"omp_destroy_nest_lock_target",
|
||||
(void*) &omp_destroy_nest_lock_lrb,
|
||||
"omp_set_nest_lock_target",
|
||||
(void*) &omp_set_nest_lock_lrb,
|
||||
"omp_unset_nest_lock_target",
|
||||
(void*) &omp_unset_nest_lock_lrb,
|
||||
"omp_test_nest_lock_target",
|
||||
(void*) &omp_test_nest_lock_lrb,
|
||||
|
||||
"kmp_set_stacksize_target",
|
||||
(void*) &kmp_set_stacksize_lrb,
|
||||
"kmp_get_stacksize_target",
|
||||
(void*) &kmp_get_stacksize_lrb,
|
||||
"kmp_set_stacksize_s_target",
|
||||
(void*) &kmp_set_stacksize_s_lrb,
|
||||
"kmp_get_stacksize_s_target",
|
||||
(void*) &kmp_get_stacksize_s_lrb,
|
||||
"kmp_set_blocktime_target",
|
||||
(void*) &kmp_set_blocktime_lrb,
|
||||
"kmp_get_blocktime_target",
|
||||
(void*) &kmp_get_blocktime_lrb,
|
||||
"kmp_set_library_serial_target",
|
||||
(void*) &kmp_set_library_serial_lrb,
|
||||
"kmp_set_library_turnaround_target",
|
||||
(void*) &kmp_set_library_turnaround_lrb,
|
||||
"kmp_set_library_throughput_target",
|
||||
(void*) &kmp_set_library_throughput_lrb,
|
||||
"kmp_set_library_target",
|
||||
(void*) &kmp_set_library_lrb,
|
||||
"kmp_get_library_target",
|
||||
(void*) &kmp_get_library_lrb,
|
||||
"kmp_set_defaults_target",
|
||||
(void*) &kmp_set_defaults_lrb,
|
||||
|
||||
"kmp_create_affinity_mask_target",
|
||||
(void*) &kmp_create_affinity_mask_lrb,
|
||||
"kmp_destroy_affinity_mask_target",
|
||||
(void*) &kmp_destroy_affinity_mask_lrb,
|
||||
"kmp_set_affinity_target",
|
||||
(void*) &kmp_set_affinity_lrb,
|
||||
"kmp_get_affinity_target",
|
||||
(void*) &kmp_get_affinity_lrb,
|
||||
"kmp_get_affinity_max_proc_target",
|
||||
(void*) &kmp_get_affinity_max_proc_lrb,
|
||||
"kmp_set_affinity_mask_proc_target",
|
||||
(void*) &kmp_set_affinity_mask_proc_lrb,
|
||||
"kmp_unset_affinity_mask_proc_target",
|
||||
(void*) &kmp_unset_affinity_mask_proc_lrb,
|
||||
"kmp_get_affinity_mask_proc_target",
|
||||
(void*) &kmp_get_affinity_mask_proc_lrb,
|
||||
|
||||
(const char*) -1,
|
||||
(void*) -1
|
||||
};
|
||||
|
||||
static FuncList::Node predefined_table = {
|
||||
{ predefined_entries, -1 },
|
||||
0, 0
|
||||
};
|
||||
|
||||
// Entry table
|
||||
FuncList __offload_entries(&predefined_table);
|
||||
#else
|
||||
FuncList __offload_entries;
|
||||
#endif // !HOST_LIBRARY
|
||||
|
||||
// Function table. No predefined entries.
|
||||
FuncList __offload_funcs;
|
||||
|
||||
// Var table
|
||||
VarList __offload_vars;
|
||||
|
||||
// Given the function name returns the associtated function pointer
|
||||
const void* FuncList::find_addr(const char *name)
|
||||
{
|
||||
const void* func = 0;
|
||||
|
||||
m_lock.lock();
|
||||
|
||||
for (Node *n = m_head; n != 0; n = n->next) {
|
||||
for (const Table::Entry *e = n->table.entries;
|
||||
e->name != (const char*) -1; e++) {
|
||||
if (e->name != 0 && strcmp(e->name, name) == 0) {
|
||||
func = e->func;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_lock.unlock();
|
||||
|
||||
return func;
|
||||
}
|
||||
|
||||
// Given the function pointer returns the associtated function name
|
||||
const char* FuncList::find_name(const void *func)
|
||||
{
|
||||
const char* name = 0;
|
||||
|
||||
m_lock.lock();
|
||||
|
||||
for (Node *n = m_head; n != 0; n = n->next) {
|
||||
for (const Table::Entry *e = n->table.entries;
|
||||
e->name != (const char*) -1; e++) {
|
||||
if (e->func == func) {
|
||||
name = e->name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_lock.unlock();
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
// Returns max name length from all tables
|
||||
int64_t FuncList::max_name_length(void)
|
||||
{
|
||||
if (m_max_name_len < 0) {
|
||||
m_lock.lock();
|
||||
|
||||
m_max_name_len = 0;
|
||||
for (Node *n = m_head; n != 0; n = n->next) {
|
||||
if (n->table.max_name_len < 0) {
|
||||
n->table.max_name_len = 0;
|
||||
|
||||
// calculate max name length in a single table
|
||||
for (const Table::Entry *e = n->table.entries;
|
||||
e->name != (const char*) -1; e++) {
|
||||
if (e->name != 0) {
|
||||
size_t len = strlen(e->name) + 1;
|
||||
if (n->table.max_name_len < len) {
|
||||
n->table.max_name_len = len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// select max from all tables
|
||||
if (m_max_name_len < n->table.max_name_len) {
|
||||
m_max_name_len = n->table.max_name_len;
|
||||
}
|
||||
}
|
||||
|
||||
m_lock.unlock();
|
||||
}
|
||||
return m_max_name_len;
|
||||
}
|
||||
|
||||
// Debugging dump
|
||||
void FuncList::dump(void)
|
||||
{
|
||||
OFFLOAD_DEBUG_TRACE(2, "Function table:\n");
|
||||
|
||||
m_lock.lock();
|
||||
|
||||
for (Node *n = m_head; n != 0; n = n->next) {
|
||||
for (const Table::Entry *e = n->table.entries;
|
||||
e->name != (const char*) -1; e++) {
|
||||
if (e->name != 0) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "%p %s\n", e->func, e->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_lock.unlock();
|
||||
}
|
||||
|
||||
// Debugging dump
|
||||
void VarList::dump(void)
|
||||
{
|
||||
OFFLOAD_DEBUG_TRACE(2, "Var table:\n");
|
||||
|
||||
m_lock.lock();
|
||||
|
||||
for (Node *n = m_head; n != 0; n = n->next) {
|
||||
for (const Table::Entry *e = n->table.entries;
|
||||
e->name != (const char*) -1; e++) {
|
||||
if (e->name != 0) {
|
||||
#if HOST_LIBRARY
|
||||
OFFLOAD_DEBUG_TRACE(2, "%s %p %ld\n", e->name, e->addr,
|
||||
e->size);
|
||||
#else // HOST_LIBRARY
|
||||
OFFLOAD_DEBUG_TRACE(2, "%s %p\n", e->name, e->addr);
|
||||
#endif // HOST_LIBRARY
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_lock.unlock();
|
||||
}
|
||||
|
||||
//
|
||||
int64_t VarList::table_size(int64_t &nelems)
|
||||
{
|
||||
int64_t length = 0;
|
||||
|
||||
nelems = 0;
|
||||
|
||||
// calculate string table size and number of elements
|
||||
for (Node *n = m_head; n != 0; n = n->next) {
|
||||
for (const Table::Entry *e = n->table.entries;
|
||||
e->name != (const char*) -1; e++) {
|
||||
if (e->name != 0) {
|
||||
length += strlen(e->name) + 1;
|
||||
nelems++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nelems * sizeof(BufEntry) + length;
|
||||
}
|
||||
|
||||
// copy table to the gven buffer
|
||||
void VarList::table_copy(void *buf, int64_t nelems)
|
||||
{
|
||||
BufEntry* elems = static_cast<BufEntry*>(buf);
|
||||
char* names = reinterpret_cast<char*>(elems + nelems);
|
||||
|
||||
// copy entries to buffer
|
||||
for (Node *n = m_head; n != 0; n = n->next) {
|
||||
for (const Table::Entry *e = n->table.entries;
|
||||
e->name != (const char*) -1; e++) {
|
||||
if (e->name != 0) {
|
||||
// name field contains offset to the name from the beginning
|
||||
// of the buffer
|
||||
elems->name = names - static_cast<char*>(buf);
|
||||
elems->addr = reinterpret_cast<intptr_t>(e->addr);
|
||||
|
||||
// copy name to string table
|
||||
const char *name = e->name;
|
||||
while ((*names++ = *name++) != '\0');
|
||||
|
||||
elems++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// patch name offsets in a buffer
|
||||
void VarList::table_patch_names(void *buf, int64_t nelems)
|
||||
{
|
||||
BufEntry* elems = static_cast<BufEntry*>(buf);
|
||||
for (int i = 0; i < nelems; i++) {
|
||||
elems[i].name += reinterpret_cast<intptr_t>(buf);
|
||||
}
|
||||
}
|
||||
|
||||
// Adds given list element to the global lookup table list
|
||||
extern "C" void __offload_register_tables(
|
||||
FuncList::Node *entry_table,
|
||||
FuncList::Node *func_table,
|
||||
VarList::Node *var_table
|
||||
)
|
||||
{
|
||||
OFFLOAD_DEBUG_TRACE(2, "Registering offload function entry table %p\n",
|
||||
entry_table);
|
||||
__offload_entries.add_table(entry_table);
|
||||
|
||||
OFFLOAD_DEBUG_TRACE(2, "Registering function table %p\n", func_table);
|
||||
__offload_funcs.add_table(func_table);
|
||||
|
||||
OFFLOAD_DEBUG_TRACE(2, "Registering var table %p\n", var_table);
|
||||
__offload_vars.add_table(var_table);
|
||||
}
|
||||
|
||||
// Removes given list element from the global lookup table list
|
||||
extern "C" void __offload_unregister_tables(
|
||||
FuncList::Node *entry_table,
|
||||
FuncList::Node *func_table,
|
||||
VarList::Node *var_table
|
||||
)
|
||||
{
|
||||
__offload_entries.remove_table(entry_table);
|
||||
|
||||
OFFLOAD_DEBUG_TRACE(2, "Unregistering function table %p\n", func_table);
|
||||
__offload_funcs.remove_table(func_table);
|
||||
|
||||
OFFLOAD_DEBUG_TRACE(2, "Unregistering var table %p\n", var_table);
|
||||
__offload_vars.remove_table(var_table);
|
||||
}
|
||||
@@ -0,0 +1,301 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
/*! \file
|
||||
\brief Function and Variable tables used by the runtime library
|
||||
*/
|
||||
|
||||
#ifndef OFFLOAD_TABLE_H_INCLUDED
|
||||
#define OFFLOAD_TABLE_H_INCLUDED
|
||||
|
||||
#include <iterator>
|
||||
#include "offload_util.h"
|
||||
|
||||
// Template representing double linked list of tables
|
||||
template <typename T> class TableList {
|
||||
public:
|
||||
// table type
|
||||
typedef T Table;
|
||||
|
||||
// List node
|
||||
struct Node {
|
||||
Table table;
|
||||
Node* prev;
|
||||
Node* next;
|
||||
};
|
||||
|
||||
public:
|
||||
explicit TableList(Node *node = 0) : m_head(node) {}
|
||||
|
||||
void add_table(Node *node) {
|
||||
m_lock.lock();
|
||||
|
||||
if (m_head != 0) {
|
||||
node->next = m_head;
|
||||
m_head->prev = node;
|
||||
}
|
||||
m_head = node;
|
||||
|
||||
m_lock.unlock();
|
||||
}
|
||||
|
||||
void remove_table(Node *node) {
|
||||
m_lock.lock();
|
||||
|
||||
if (node->next != 0) {
|
||||
node->next->prev = node->prev;
|
||||
}
|
||||
if (node->prev != 0) {
|
||||
node->prev->next = node->next;
|
||||
}
|
||||
if (m_head == node) {
|
||||
m_head = node->next;
|
||||
}
|
||||
|
||||
m_lock.unlock();
|
||||
}
|
||||
|
||||
protected:
|
||||
Node* m_head;
|
||||
mutex_t m_lock;
|
||||
};
|
||||
|
||||
// Function lookup table.
|
||||
struct FuncTable {
|
||||
//! Function table entry
|
||||
/*! This table contains functions created from offload regions. */
|
||||
/*! Each entry consists of a pointer to the function's "key"
|
||||
and the function address. */
|
||||
/*! Each shared library or executable may contain one such table. */
|
||||
/*! The end of the table is marked with an entry whose name field
|
||||
has value -1. */
|
||||
struct Entry {
|
||||
const char* name; //!< Name of the function
|
||||
void* func; //!< Address of the function
|
||||
};
|
||||
|
||||
// entries
|
||||
const Entry *entries;
|
||||
|
||||
// max name length
|
||||
int64_t max_name_len;
|
||||
};
|
||||
|
||||
// Function table
|
||||
class FuncList : public TableList<FuncTable> {
|
||||
public:
|
||||
explicit FuncList(Node *node = 0) : TableList<Table>(node),
|
||||
m_max_name_len(-1)
|
||||
{}
|
||||
|
||||
// add table to the list
|
||||
void add_table(Node *node) {
|
||||
// recalculate max function name length
|
||||
m_max_name_len = -1;
|
||||
|
||||
// add table
|
||||
TableList<Table>::add_table(node);
|
||||
}
|
||||
|
||||
// find function address for the given name
|
||||
const void* find_addr(const char *name);
|
||||
|
||||
// find function name for the given address
|
||||
const char* find_name(const void *addr);
|
||||
|
||||
// max name length from all tables in the list
|
||||
int64_t max_name_length(void);
|
||||
|
||||
// debug dump
|
||||
void dump(void);
|
||||
|
||||
private:
|
||||
// max name length within from all tables
|
||||
int64_t m_max_name_len;
|
||||
};
|
||||
|
||||
// Table entry for static variables
|
||||
struct VarTable {
|
||||
//! Variable table entry
|
||||
/*! This table contains statically allocated variables marked with
|
||||
__declspec(target(mic) or #pragma omp declare target. */
|
||||
/*! Each entry consists of a pointer to the variable's "key",
|
||||
the variable address and its size in bytes. */
|
||||
/*! Because memory allocation is done from the host,
|
||||
the MIC table does not need the size of the variable. */
|
||||
/*! Padding to make the table entry size a power of 2 is necessary
|
||||
to avoid "holes" between table contributions from different object
|
||||
files on Windows when debug information is specified with /Zi. */
|
||||
struct Entry {
|
||||
const char* name; //!< Name of the variable
|
||||
void* addr; //!< Address of the variable
|
||||
|
||||
#if HOST_LIBRARY
|
||||
uint64_t size;
|
||||
|
||||
#ifdef TARGET_WINNT
|
||||
// padding to make entry size a power of 2
|
||||
uint64_t padding;
|
||||
#endif // TARGET_WINNT
|
||||
#endif
|
||||
};
|
||||
|
||||
// Table terminated by an entry with name == -1
|
||||
const Entry *entries;
|
||||
};
|
||||
|
||||
// List of var tables
|
||||
class VarList : public TableList<VarTable> {
|
||||
public:
|
||||
VarList() : TableList<Table>()
|
||||
{}
|
||||
|
||||
// debug dump
|
||||
void dump();
|
||||
|
||||
public:
|
||||
// var table list iterator
|
||||
class Iterator : public std::iterator<std::input_iterator_tag,
|
||||
Table::Entry> {
|
||||
public:
|
||||
Iterator() : m_node(0), m_entry(0) {}
|
||||
|
||||
explicit Iterator(Node *node) {
|
||||
new_node(node);
|
||||
}
|
||||
|
||||
Iterator& operator++() {
|
||||
if (m_entry != 0) {
|
||||
m_entry++;
|
||||
while (m_entry->name == 0) {
|
||||
m_entry++;
|
||||
}
|
||||
if (m_entry->name == reinterpret_cast<const char*>(-1)) {
|
||||
new_node(m_node->next);
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const Iterator &other) const {
|
||||
return m_entry == other.m_entry;
|
||||
}
|
||||
|
||||
bool operator!=(const Iterator &other) const {
|
||||
return m_entry != other.m_entry;
|
||||
}
|
||||
|
||||
const Table::Entry* operator*() const {
|
||||
return m_entry;
|
||||
}
|
||||
|
||||
private:
|
||||
void new_node(Node *node) {
|
||||
m_node = node;
|
||||
m_entry = 0;
|
||||
while (m_node != 0) {
|
||||
m_entry = m_node->table.entries;
|
||||
while (m_entry->name == 0) {
|
||||
m_entry++;
|
||||
}
|
||||
if (m_entry->name != reinterpret_cast<const char*>(-1)) {
|
||||
break;
|
||||
}
|
||||
m_node = m_node->next;
|
||||
m_entry = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Node *m_node;
|
||||
const Table::Entry *m_entry;
|
||||
};
|
||||
|
||||
Iterator begin() const {
|
||||
return Iterator(m_head);
|
||||
}
|
||||
|
||||
Iterator end() const {
|
||||
return Iterator();
|
||||
}
|
||||
|
||||
public:
|
||||
// Entry representation in a copy buffer
|
||||
struct BufEntry {
|
||||
intptr_t name;
|
||||
intptr_t addr;
|
||||
};
|
||||
|
||||
// Calculate the number of elements in the table and
|
||||
// returns the size of buffer for the table
|
||||
int64_t table_size(int64_t &nelems);
|
||||
|
||||
// Copy table contents to given buffer. It is supposed to be large
|
||||
// enough to hold all elements as string table.
|
||||
void table_copy(void *buf, int64_t nelems);
|
||||
|
||||
// Patch name offsets in a table after it's been copied to other side
|
||||
static void table_patch_names(void *buf, int64_t nelems);
|
||||
};
|
||||
|
||||
extern FuncList __offload_entries;
|
||||
extern FuncList __offload_funcs;
|
||||
extern VarList __offload_vars;
|
||||
|
||||
// Section names where the lookup tables are stored
|
||||
#ifdef TARGET_WINNT
|
||||
#define OFFLOAD_ENTRY_TABLE_SECTION_START ".OffloadEntryTable$a"
|
||||
#define OFFLOAD_ENTRY_TABLE_SECTION_END ".OffloadEntryTable$z"
|
||||
|
||||
#define OFFLOAD_FUNC_TABLE_SECTION_START ".OffloadFuncTable$a"
|
||||
#define OFFLOAD_FUNC_TABLE_SECTION_END ".OffloadFuncTable$z"
|
||||
|
||||
#define OFFLOAD_VAR_TABLE_SECTION_START ".OffloadVarTable$a"
|
||||
#define OFFLOAD_VAR_TABLE_SECTION_END ".OffloadVarTable$z"
|
||||
|
||||
#define OFFLOAD_CRTINIT_SECTION_START ".CRT$XCT"
|
||||
|
||||
#pragma section(OFFLOAD_CRTINIT_SECTION_START, read)
|
||||
|
||||
#else // TARGET_WINNT
|
||||
|
||||
#define OFFLOAD_ENTRY_TABLE_SECTION_START ".OffloadEntryTable."
|
||||
#define OFFLOAD_ENTRY_TABLE_SECTION_END ".OffloadEntryTable."
|
||||
|
||||
#define OFFLOAD_FUNC_TABLE_SECTION_START ".OffloadFuncTable."
|
||||
#define OFFLOAD_FUNC_TABLE_SECTION_END ".OffloadFuncTable."
|
||||
|
||||
#define OFFLOAD_VAR_TABLE_SECTION_START ".OffloadVarTable."
|
||||
#define OFFLOAD_VAR_TABLE_SECTION_END ".OffloadVarTable."
|
||||
#endif // TARGET_WINNT
|
||||
|
||||
#pragma section(OFFLOAD_ENTRY_TABLE_SECTION_START, read, write)
|
||||
#pragma section(OFFLOAD_ENTRY_TABLE_SECTION_END, read, write)
|
||||
|
||||
#pragma section(OFFLOAD_FUNC_TABLE_SECTION_START, read, write)
|
||||
#pragma section(OFFLOAD_FUNC_TABLE_SECTION_END, read, write)
|
||||
|
||||
#pragma section(OFFLOAD_VAR_TABLE_SECTION_START, read, write)
|
||||
#pragma section(OFFLOAD_VAR_TABLE_SECTION_END, read, write)
|
||||
|
||||
|
||||
// register/unregister given tables
|
||||
extern "C" void __offload_register_tables(
|
||||
FuncList::Node *entry_table,
|
||||
FuncList::Node *func_table,
|
||||
VarList::Node *var_table
|
||||
);
|
||||
|
||||
extern "C" void __offload_unregister_tables(
|
||||
FuncList::Node *entry_table,
|
||||
FuncList::Node *func_table,
|
||||
VarList::Node *var_table
|
||||
);
|
||||
#endif // OFFLOAD_TABLE_H_INCLUDED
|
||||
@@ -0,0 +1,754 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 "offload_target.h"
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#ifdef SEP_SUPPORT
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#endif // SEP_SUPPORT
|
||||
#include <omp.h>
|
||||
#include <map>
|
||||
|
||||
// typedef offload_func_with_parms.
|
||||
// Pointer to function that represents an offloaded entry point.
|
||||
// The parameters are a temporary fix for parameters on the stack.
|
||||
typedef void (*offload_func_with_parms)(void *);
|
||||
|
||||
// Target console and file logging
|
||||
const char *prefix;
|
||||
int console_enabled = 0;
|
||||
int offload_report_level = 0;
|
||||
|
||||
// Trace information
|
||||
static const char* vardesc_direction_as_string[] = {
|
||||
"NOCOPY",
|
||||
"IN",
|
||||
"OUT",
|
||||
"INOUT"
|
||||
};
|
||||
static const char* vardesc_type_as_string[] = {
|
||||
"unknown",
|
||||
"data",
|
||||
"data_ptr",
|
||||
"func_ptr",
|
||||
"void_ptr",
|
||||
"string_ptr",
|
||||
"dv",
|
||||
"dv_data",
|
||||
"dv_data_slice",
|
||||
"dv_ptr",
|
||||
"dv_ptr_data",
|
||||
"dv_ptr_data_slice",
|
||||
"cean_var",
|
||||
"cean_var_ptr",
|
||||
"c_data_ptr_array"
|
||||
};
|
||||
|
||||
int mic_index = -1;
|
||||
int mic_engines_total = -1;
|
||||
uint64_t mic_frequency = 0;
|
||||
int offload_number = 0;
|
||||
static std::map<void*, RefInfo*> ref_data;
|
||||
static mutex_t add_ref_lock;
|
||||
|
||||
#ifdef SEP_SUPPORT
|
||||
static const char* sep_monitor_env = "SEP_MONITOR";
|
||||
static bool sep_monitor = false;
|
||||
static const char* sep_device_env = "SEP_DEVICE";
|
||||
static const char* sep_device = "/dev/sep3.8/c";
|
||||
static int sep_counter = 0;
|
||||
|
||||
#define SEP_API_IOC_MAGIC 99
|
||||
#define SEP_IOCTL_PAUSE _IO (SEP_API_IOC_MAGIC, 31)
|
||||
#define SEP_IOCTL_RESUME _IO (SEP_API_IOC_MAGIC, 32)
|
||||
|
||||
static void add_ref_count(void * buf, bool created)
|
||||
{
|
||||
mutex_locker_t locker(add_ref_lock);
|
||||
RefInfo * info = ref_data[buf];
|
||||
|
||||
if (info) {
|
||||
info->count++;
|
||||
}
|
||||
else {
|
||||
info = new RefInfo((int)created,(long)1);
|
||||
}
|
||||
info->is_added |= created;
|
||||
ref_data[buf] = info;
|
||||
}
|
||||
|
||||
static void BufReleaseRef(void * buf)
|
||||
{
|
||||
mutex_locker_t locker(add_ref_lock);
|
||||
RefInfo * info = ref_data[buf];
|
||||
|
||||
if (info) {
|
||||
--info->count;
|
||||
if (info->count == 0 && info->is_added) {
|
||||
BufferReleaseRef(buf);
|
||||
info->is_added = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int VTPauseSampling(void)
|
||||
{
|
||||
int ret = -1;
|
||||
int handle = open(sep_device, O_RDWR);
|
||||
if (handle > 0) {
|
||||
ret = ioctl(handle, SEP_IOCTL_PAUSE);
|
||||
close(handle);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int VTResumeSampling(void)
|
||||
{
|
||||
int ret = -1;
|
||||
int handle = open(sep_device, O_RDWR);
|
||||
if (handle > 0) {
|
||||
ret = ioctl(handle, SEP_IOCTL_RESUME);
|
||||
close(handle);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif // SEP_SUPPORT
|
||||
|
||||
void OffloadDescriptor::offload(
|
||||
uint32_t buffer_count,
|
||||
void** buffers,
|
||||
void* misc_data,
|
||||
uint16_t misc_data_len,
|
||||
void* return_data,
|
||||
uint16_t return_data_len
|
||||
)
|
||||
{
|
||||
FunctionDescriptor *func = (FunctionDescriptor*) misc_data;
|
||||
const char *name = func->data;
|
||||
OffloadDescriptor ofld;
|
||||
char *in_data = 0;
|
||||
char *out_data = 0;
|
||||
char *timer_data = 0;
|
||||
|
||||
console_enabled = func->console_enabled;
|
||||
timer_enabled = func->timer_enabled;
|
||||
offload_report_level = func->offload_report_level;
|
||||
offload_number = func->offload_number;
|
||||
ofld.set_offload_number(func->offload_number);
|
||||
|
||||
#ifdef SEP_SUPPORT
|
||||
if (sep_monitor) {
|
||||
if (__sync_fetch_and_add(&sep_counter, 1) == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "VTResumeSampling\n");
|
||||
VTResumeSampling();
|
||||
}
|
||||
}
|
||||
#endif // SEP_SUPPORT
|
||||
|
||||
OFFLOAD_DEBUG_TRACE_1(2, ofld.get_offload_number(),
|
||||
c_offload_start_target_func,
|
||||
"Offload \"%s\" started\n", name);
|
||||
|
||||
// initialize timer data
|
||||
OFFLOAD_TIMER_INIT();
|
||||
|
||||
OFFLOAD_TIMER_START(c_offload_target_total_time);
|
||||
|
||||
OFFLOAD_TIMER_START(c_offload_target_descriptor_setup);
|
||||
|
||||
// get input/output buffer addresses
|
||||
if (func->in_datalen > 0 || func->out_datalen > 0) {
|
||||
if (func->data_offset != 0) {
|
||||
in_data = (char*) misc_data + func->data_offset;
|
||||
out_data = (char*) return_data;
|
||||
}
|
||||
else {
|
||||
char *inout_buf = (char*) buffers[--buffer_count];
|
||||
in_data = inout_buf;
|
||||
out_data = inout_buf;
|
||||
}
|
||||
}
|
||||
|
||||
// assign variable descriptors
|
||||
ofld.m_vars_total = func->vars_num;
|
||||
if (ofld.m_vars_total > 0) {
|
||||
uint64_t var_data_len = ofld.m_vars_total * sizeof(VarDesc);
|
||||
|
||||
ofld.m_vars = (VarDesc*) malloc(var_data_len);
|
||||
memcpy(ofld.m_vars, in_data, var_data_len);
|
||||
|
||||
in_data += var_data_len;
|
||||
func->in_datalen -= var_data_len;
|
||||
}
|
||||
|
||||
// timer data
|
||||
if (func->timer_enabled) {
|
||||
uint64_t timer_data_len = OFFLOAD_TIMER_DATALEN();
|
||||
|
||||
timer_data = out_data;
|
||||
out_data += timer_data_len;
|
||||
func->out_datalen -= timer_data_len;
|
||||
}
|
||||
|
||||
// init Marshallers
|
||||
ofld.m_in.init_buffer(in_data, func->in_datalen);
|
||||
ofld.m_out.init_buffer(out_data, func->out_datalen);
|
||||
|
||||
// copy buffers to offload descriptor
|
||||
std::copy(buffers, buffers + buffer_count,
|
||||
std::back_inserter(ofld.m_buffers));
|
||||
|
||||
OFFLOAD_TIMER_STOP(c_offload_target_descriptor_setup);
|
||||
|
||||
// find offload entry address
|
||||
OFFLOAD_TIMER_START(c_offload_target_func_lookup);
|
||||
|
||||
offload_func_with_parms entry = (offload_func_with_parms)
|
||||
__offload_entries.find_addr(name);
|
||||
|
||||
if (entry == NULL) {
|
||||
#if OFFLOAD_DEBUG > 0
|
||||
if (console_enabled > 2) {
|
||||
__offload_entries.dump();
|
||||
}
|
||||
#endif
|
||||
LIBOFFLOAD_ERROR(c_offload_descriptor_offload, name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
OFFLOAD_TIMER_STOP(c_offload_target_func_lookup);
|
||||
|
||||
OFFLOAD_TIMER_START(c_offload_target_func_time);
|
||||
|
||||
// execute offload entry
|
||||
entry(&ofld);
|
||||
|
||||
OFFLOAD_TIMER_STOP(c_offload_target_func_time);
|
||||
|
||||
OFFLOAD_TIMER_STOP(c_offload_target_total_time);
|
||||
|
||||
// copy timer data to the buffer
|
||||
OFFLOAD_TIMER_TARGET_DATA(timer_data);
|
||||
|
||||
OFFLOAD_DEBUG_TRACE(2, "Offload \"%s\" finished\n", name);
|
||||
|
||||
#ifdef SEP_SUPPORT
|
||||
if (sep_monitor) {
|
||||
if (__sync_sub_and_fetch(&sep_counter, 1) == 0) {
|
||||
OFFLOAD_DEBUG_TRACE(2, "VTPauseSampling\n");
|
||||
VTPauseSampling();
|
||||
}
|
||||
}
|
||||
#endif // SEP_SUPPORT
|
||||
}
|
||||
|
||||
void OffloadDescriptor::merge_var_descs(
|
||||
VarDesc *vars,
|
||||
VarDesc2 *vars2,
|
||||
int vars_total
|
||||
)
|
||||
{
|
||||
// number of variable descriptors received from host and generated
|
||||
// locally should match
|
||||
if (m_vars_total < vars_total) {
|
||||
LIBOFFLOAD_ERROR(c_merge_var_descs1);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_vars_total; i++) {
|
||||
if (i < vars_total) {
|
||||
// variable type must match
|
||||
if (m_vars[i].type.bits != vars[i].type.bits) {
|
||||
LIBOFFLOAD_ERROR(c_merge_var_descs2);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
m_vars[i].ptr = vars[i].ptr;
|
||||
m_vars[i].into = vars[i].into;
|
||||
|
||||
const char *var_sname = "";
|
||||
if (vars2 != NULL) {
|
||||
if (vars2[i].sname != NULL) {
|
||||
var_sname = vars2[i].sname;
|
||||
}
|
||||
}
|
||||
OFFLOAD_DEBUG_TRACE_1(2, get_offload_number(), c_offload_var,
|
||||
" VarDesc %d, var=%s, %s, %s\n",
|
||||
i, var_sname,
|
||||
vardesc_direction_as_string[m_vars[i].direction.bits],
|
||||
vardesc_type_as_string[m_vars[i].type.src]);
|
||||
if (vars2 != NULL && vars2[i].dname != NULL) {
|
||||
OFFLOAD_TRACE(2, " into=%s, %s\n", vars2[i].dname,
|
||||
vardesc_type_as_string[m_vars[i].type.dst]);
|
||||
}
|
||||
}
|
||||
OFFLOAD_TRACE(2,
|
||||
" type_src=%d, type_dstn=%d, direction=%d, "
|
||||
"alloc_if=%d, free_if=%d, align=%d, mic_offset=%d, flags=0x%x, "
|
||||
"offset=%lld, size=%lld, count/disp=%lld, ptr=%p into=%p\n",
|
||||
m_vars[i].type.src,
|
||||
m_vars[i].type.dst,
|
||||
m_vars[i].direction.bits,
|
||||
m_vars[i].alloc_if,
|
||||
m_vars[i].free_if,
|
||||
m_vars[i].align,
|
||||
m_vars[i].mic_offset,
|
||||
m_vars[i].flags.bits,
|
||||
m_vars[i].offset,
|
||||
m_vars[i].size,
|
||||
m_vars[i].count,
|
||||
m_vars[i].ptr,
|
||||
m_vars[i].into);
|
||||
}
|
||||
}
|
||||
|
||||
void OffloadDescriptor::scatter_copyin_data()
|
||||
{
|
||||
OFFLOAD_TIMER_START(c_offload_target_scatter_inputs);
|
||||
|
||||
OFFLOAD_DEBUG_TRACE(2, "IN buffer @ %p size %lld\n",
|
||||
m_in.get_buffer_start(),
|
||||
m_in.get_buffer_size());
|
||||
OFFLOAD_DEBUG_DUMP_BYTES(2, m_in.get_buffer_start(),
|
||||
m_in.get_buffer_size());
|
||||
|
||||
// receive data
|
||||
for (int i = 0; i < m_vars_total; i++) {
|
||||
bool src_is_for_mic = (m_vars[i].direction.out ||
|
||||
m_vars[i].into == NULL);
|
||||
void** ptr_addr = src_is_for_mic ?
|
||||
static_cast<void**>(m_vars[i].ptr) :
|
||||
static_cast<void**>(m_vars[i].into);
|
||||
int type = src_is_for_mic ? m_vars[i].type.src :
|
||||
m_vars[i].type.dst;
|
||||
bool is_static = src_is_for_mic ?
|
||||
m_vars[i].flags.is_static :
|
||||
m_vars[i].flags.is_static_dstn;
|
||||
void *ptr = NULL;
|
||||
|
||||
if (m_vars[i].flags.alloc_disp) {
|
||||
int64_t offset = 0;
|
||||
m_in.receive_data(&offset, sizeof(offset));
|
||||
m_vars[i].offset = -offset;
|
||||
}
|
||||
if (VAR_TYPE_IS_DV_DATA_SLICE(type) ||
|
||||
VAR_TYPE_IS_DV_DATA(type)) {
|
||||
ArrDesc *dvp = (type == c_dv_data_slice || type == c_dv_data)?
|
||||
reinterpret_cast<ArrDesc*>(ptr_addr) :
|
||||
*reinterpret_cast<ArrDesc**>(ptr_addr);
|
||||
ptr_addr = reinterpret_cast<void**>(&dvp->Base);
|
||||
}
|
||||
|
||||
// Set pointer values
|
||||
switch (type) {
|
||||
case c_data_ptr_array:
|
||||
{
|
||||
int j = m_vars[i].ptr_arr_offset;
|
||||
int max_el = j + m_vars[i].count;
|
||||
char *dst_arr_ptr = (src_is_for_mic)?
|
||||
*(reinterpret_cast<char**>(m_vars[i].ptr)) :
|
||||
reinterpret_cast<char*>(m_vars[i].into);
|
||||
|
||||
for (; j < max_el; j++) {
|
||||
if (src_is_for_mic) {
|
||||
m_vars[j].ptr =
|
||||
dst_arr_ptr + m_vars[j].ptr_arr_offset;
|
||||
}
|
||||
else {
|
||||
m_vars[j].into =
|
||||
dst_arr_ptr + m_vars[j].ptr_arr_offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case c_data:
|
||||
case c_void_ptr:
|
||||
case c_cean_var:
|
||||
case c_dv:
|
||||
break;
|
||||
|
||||
case c_string_ptr:
|
||||
case c_data_ptr:
|
||||
case c_cean_var_ptr:
|
||||
case c_dv_ptr:
|
||||
if (m_vars[i].alloc_if) {
|
||||
void *buf;
|
||||
if (m_vars[i].flags.sink_addr) {
|
||||
m_in.receive_data(&buf, sizeof(buf));
|
||||
}
|
||||
else {
|
||||
buf = m_buffers.front();
|
||||
m_buffers.pop_front();
|
||||
}
|
||||
if (buf) {
|
||||
if (!is_static) {
|
||||
if (!m_vars[i].flags.sink_addr) {
|
||||
// increment buffer reference
|
||||
OFFLOAD_TIMER_START(c_offload_target_add_buffer_refs);
|
||||
BufferAddRef(buf);
|
||||
OFFLOAD_TIMER_STOP(c_offload_target_add_buffer_refs);
|
||||
}
|
||||
add_ref_count(buf, 0 == m_vars[i].flags.sink_addr);
|
||||
}
|
||||
ptr = static_cast<char*>(buf) +
|
||||
m_vars[i].mic_offset +
|
||||
(m_vars[i].flags.is_stack_buf ?
|
||||
0 : m_vars[i].offset);
|
||||
}
|
||||
*ptr_addr = ptr;
|
||||
}
|
||||
else if (m_vars[i].flags.sink_addr) {
|
||||
void *buf;
|
||||
m_in.receive_data(&buf, sizeof(buf));
|
||||
void *ptr = static_cast<char*>(buf) +
|
||||
m_vars[i].mic_offset +
|
||||
(m_vars[i].flags.is_stack_buf ?
|
||||
0 : m_vars[i].offset);
|
||||
*ptr_addr = ptr;
|
||||
}
|
||||
break;
|
||||
|
||||
case c_func_ptr:
|
||||
break;
|
||||
|
||||
case c_dv_data:
|
||||
case c_dv_ptr_data:
|
||||
case c_dv_data_slice:
|
||||
case c_dv_ptr_data_slice:
|
||||
if (m_vars[i].alloc_if) {
|
||||
void *buf;
|
||||
if (m_vars[i].flags.sink_addr) {
|
||||
m_in.receive_data(&buf, sizeof(buf));
|
||||
}
|
||||
else {
|
||||
buf = m_buffers.front();
|
||||
m_buffers.pop_front();
|
||||
}
|
||||
if (buf) {
|
||||
if (!is_static) {
|
||||
if (!m_vars[i].flags.sink_addr) {
|
||||
// increment buffer reference
|
||||
OFFLOAD_TIMER_START(c_offload_target_add_buffer_refs);
|
||||
BufferAddRef(buf);
|
||||
OFFLOAD_TIMER_STOP(c_offload_target_add_buffer_refs);
|
||||
}
|
||||
add_ref_count(buf, 0 == m_vars[i].flags.sink_addr);
|
||||
}
|
||||
ptr = static_cast<char*>(buf) +
|
||||
m_vars[i].mic_offset + m_vars[i].offset;
|
||||
}
|
||||
*ptr_addr = ptr;
|
||||
}
|
||||
else if (m_vars[i].flags.sink_addr) {
|
||||
void *buf;
|
||||
m_in.receive_data(&buf, sizeof(buf));
|
||||
ptr = static_cast<char*>(buf) +
|
||||
m_vars[i].mic_offset + m_vars[i].offset;
|
||||
*ptr_addr = ptr;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
LIBOFFLOAD_ERROR(c_unknown_var_type, type);
|
||||
abort();
|
||||
}
|
||||
// Release obsolete buffers for stack of persistent objects
|
||||
if (type = c_data_ptr &&
|
||||
m_vars[i].flags.is_stack_buf &&
|
||||
!m_vars[i].direction.bits &&
|
||||
m_vars[i].alloc_if &&
|
||||
m_vars[i].size != 0) {
|
||||
for (int j=0; j < m_vars[i].size; j++) {
|
||||
void *buf;
|
||||
m_in.receive_data(&buf, sizeof(buf));
|
||||
BufferReleaseRef(buf);
|
||||
ref_data.erase(buf);
|
||||
}
|
||||
}
|
||||
// Do copyin
|
||||
switch (m_vars[i].type.dst) {
|
||||
case c_data_ptr_array:
|
||||
break;
|
||||
case c_data:
|
||||
case c_void_ptr:
|
||||
case c_cean_var:
|
||||
if (m_vars[i].direction.in &&
|
||||
!m_vars[i].flags.is_static_dstn) {
|
||||
int64_t size;
|
||||
int64_t disp;
|
||||
char* ptr = m_vars[i].into ?
|
||||
static_cast<char*>(m_vars[i].into) :
|
||||
static_cast<char*>(m_vars[i].ptr);
|
||||
if (m_vars[i].type.dst == c_cean_var) {
|
||||
m_in.receive_data((&size), sizeof(int64_t));
|
||||
m_in.receive_data((&disp), sizeof(int64_t));
|
||||
}
|
||||
else {
|
||||
size = m_vars[i].size;
|
||||
disp = 0;
|
||||
}
|
||||
m_in.receive_data(ptr + disp, size);
|
||||
}
|
||||
break;
|
||||
|
||||
case c_dv:
|
||||
if (m_vars[i].direction.bits ||
|
||||
m_vars[i].alloc_if ||
|
||||
m_vars[i].free_if) {
|
||||
char* ptr = m_vars[i].into ?
|
||||
static_cast<char*>(m_vars[i].into) :
|
||||
static_cast<char*>(m_vars[i].ptr);
|
||||
m_in.receive_data(ptr + sizeof(uint64_t),
|
||||
m_vars[i].size - sizeof(uint64_t));
|
||||
}
|
||||
break;
|
||||
|
||||
case c_string_ptr:
|
||||
case c_data_ptr:
|
||||
case c_cean_var_ptr:
|
||||
case c_dv_ptr:
|
||||
case c_dv_data:
|
||||
case c_dv_ptr_data:
|
||||
case c_dv_data_slice:
|
||||
case c_dv_ptr_data_slice:
|
||||
break;
|
||||
|
||||
case c_func_ptr:
|
||||
if (m_vars[i].direction.in) {
|
||||
m_in.receive_func_ptr((const void**) m_vars[i].ptr);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
LIBOFFLOAD_ERROR(c_unknown_var_type, m_vars[i].type.dst);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
OFFLOAD_TRACE(1, "Total copyin data received from host: [%lld] bytes\n",
|
||||
m_in.get_tfr_size());
|
||||
|
||||
OFFLOAD_TIMER_STOP(c_offload_target_scatter_inputs);
|
||||
|
||||
OFFLOAD_TIMER_START(c_offload_target_compute);
|
||||
}
|
||||
|
||||
void OffloadDescriptor::gather_copyout_data()
|
||||
{
|
||||
OFFLOAD_TIMER_STOP(c_offload_target_compute);
|
||||
|
||||
OFFLOAD_TIMER_START(c_offload_target_gather_outputs);
|
||||
|
||||
for (int i = 0; i < m_vars_total; i++) {
|
||||
bool src_is_for_mic = (m_vars[i].direction.out ||
|
||||
m_vars[i].into == NULL);
|
||||
|
||||
switch (m_vars[i].type.src) {
|
||||
case c_data_ptr_array:
|
||||
break;
|
||||
case c_data:
|
||||
case c_void_ptr:
|
||||
case c_cean_var:
|
||||
if (m_vars[i].direction.out &&
|
||||
!m_vars[i].flags.is_static) {
|
||||
m_out.send_data(
|
||||
static_cast<char*>(m_vars[i].ptr) + m_vars[i].disp,
|
||||
m_vars[i].size);
|
||||
}
|
||||
break;
|
||||
|
||||
case c_dv:
|
||||
break;
|
||||
|
||||
case c_string_ptr:
|
||||
case c_data_ptr:
|
||||
case c_cean_var_ptr:
|
||||
case c_dv_ptr:
|
||||
if (m_vars[i].free_if &&
|
||||
src_is_for_mic &&
|
||||
!m_vars[i].flags.is_static) {
|
||||
void *buf = *static_cast<char**>(m_vars[i].ptr) -
|
||||
m_vars[i].mic_offset -
|
||||
(m_vars[i].flags.is_stack_buf?
|
||||
0 : m_vars[i].offset);
|
||||
if (buf == NULL) {
|
||||
break;
|
||||
}
|
||||
// decrement buffer reference count
|
||||
OFFLOAD_TIMER_START(c_offload_target_release_buffer_refs);
|
||||
BufReleaseRef(buf);
|
||||
OFFLOAD_TIMER_STOP(c_offload_target_release_buffer_refs);
|
||||
}
|
||||
break;
|
||||
|
||||
case c_func_ptr:
|
||||
if (m_vars[i].direction.out) {
|
||||
m_out.send_func_ptr(*((void**) m_vars[i].ptr));
|
||||
}
|
||||
break;
|
||||
|
||||
case c_dv_data:
|
||||
case c_dv_ptr_data:
|
||||
case c_dv_data_slice:
|
||||
case c_dv_ptr_data_slice:
|
||||
if (src_is_for_mic &&
|
||||
m_vars[i].free_if &&
|
||||
!m_vars[i].flags.is_static) {
|
||||
ArrDesc *dvp = (m_vars[i].type.src == c_dv_data ||
|
||||
m_vars[i].type.src == c_dv_data_slice) ?
|
||||
static_cast<ArrDesc*>(m_vars[i].ptr) :
|
||||
*static_cast<ArrDesc**>(m_vars[i].ptr);
|
||||
|
||||
void *buf = reinterpret_cast<char*>(dvp->Base) -
|
||||
m_vars[i].mic_offset -
|
||||
m_vars[i].offset;
|
||||
|
||||
if (buf == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
// decrement buffer reference count
|
||||
OFFLOAD_TIMER_START(c_offload_target_release_buffer_refs);
|
||||
BufReleaseRef(buf);
|
||||
OFFLOAD_TIMER_STOP(c_offload_target_release_buffer_refs);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
LIBOFFLOAD_ERROR(c_unknown_var_type, m_vars[i].type.dst);
|
||||
abort();
|
||||
}
|
||||
|
||||
if (m_vars[i].into) {
|
||||
switch (m_vars[i].type.dst) {
|
||||
case c_data_ptr_array:
|
||||
break;
|
||||
case c_data:
|
||||
case c_void_ptr:
|
||||
case c_cean_var:
|
||||
case c_dv:
|
||||
break;
|
||||
|
||||
case c_string_ptr:
|
||||
case c_data_ptr:
|
||||
case c_cean_var_ptr:
|
||||
case c_dv_ptr:
|
||||
if (m_vars[i].direction.in &&
|
||||
m_vars[i].free_if &&
|
||||
!m_vars[i].flags.is_static_dstn) {
|
||||
void *buf = *static_cast<char**>(m_vars[i].into) -
|
||||
m_vars[i].mic_offset -
|
||||
(m_vars[i].flags.is_stack_buf?
|
||||
0 : m_vars[i].offset);
|
||||
|
||||
if (buf == NULL) {
|
||||
break;
|
||||
}
|
||||
// decrement buffer reference count
|
||||
OFFLOAD_TIMER_START(
|
||||
c_offload_target_release_buffer_refs);
|
||||
BufReleaseRef(buf);
|
||||
OFFLOAD_TIMER_STOP(
|
||||
c_offload_target_release_buffer_refs);
|
||||
}
|
||||
break;
|
||||
|
||||
case c_func_ptr:
|
||||
break;
|
||||
|
||||
case c_dv_data:
|
||||
case c_dv_ptr_data:
|
||||
case c_dv_data_slice:
|
||||
case c_dv_ptr_data_slice:
|
||||
if (m_vars[i].free_if &&
|
||||
m_vars[i].direction.in &&
|
||||
!m_vars[i].flags.is_static_dstn) {
|
||||
ArrDesc *dvp =
|
||||
(m_vars[i].type.dst == c_dv_data_slice ||
|
||||
m_vars[i].type.dst == c_dv_data) ?
|
||||
static_cast<ArrDesc*>(m_vars[i].into) :
|
||||
*static_cast<ArrDesc**>(m_vars[i].into);
|
||||
void *buf = reinterpret_cast<char*>(dvp->Base) -
|
||||
m_vars[i].mic_offset -
|
||||
m_vars[i].offset;
|
||||
|
||||
if (buf == NULL) {
|
||||
break;
|
||||
}
|
||||
// decrement buffer reference count
|
||||
OFFLOAD_TIMER_START(
|
||||
c_offload_target_release_buffer_refs);
|
||||
BufReleaseRef(buf);
|
||||
OFFLOAD_TIMER_STOP(
|
||||
c_offload_target_release_buffer_refs);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
LIBOFFLOAD_ERROR(c_unknown_var_type, m_vars[i].type.dst);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OFFLOAD_DEBUG_TRACE(2, "OUT buffer @ p %p size %lld\n",
|
||||
m_out.get_buffer_start(),
|
||||
m_out.get_buffer_size());
|
||||
|
||||
OFFLOAD_DEBUG_DUMP_BYTES(2,
|
||||
m_out.get_buffer_start(),
|
||||
m_out.get_buffer_size());
|
||||
|
||||
OFFLOAD_DEBUG_TRACE_1(1, get_offload_number(), c_offload_copyout_data,
|
||||
"Total copyout data sent to host: [%lld] bytes\n",
|
||||
m_out.get_tfr_size());
|
||||
|
||||
OFFLOAD_TIMER_STOP(c_offload_target_gather_outputs);
|
||||
}
|
||||
|
||||
void __offload_target_init(void)
|
||||
{
|
||||
#ifdef SEP_SUPPORT
|
||||
const char* env_var = getenv(sep_monitor_env);
|
||||
if (env_var != 0 && *env_var != '\0') {
|
||||
sep_monitor = atoi(env_var);
|
||||
}
|
||||
env_var = getenv(sep_device_env);
|
||||
if (env_var != 0 && *env_var != '\0') {
|
||||
sep_device = env_var;
|
||||
}
|
||||
#endif // SEP_SUPPORT
|
||||
|
||||
prefix = report_get_message_str(c_report_mic);
|
||||
|
||||
// init frequency
|
||||
mic_frequency = COIPerfGetCycleFrequency();
|
||||
}
|
||||
|
||||
// User-visible offload API
|
||||
|
||||
int _Offload_number_of_devices(void)
|
||||
{
|
||||
return mic_engines_total;
|
||||
}
|
||||
|
||||
int _Offload_get_device_number(void)
|
||||
{
|
||||
return mic_index;
|
||||
}
|
||||
|
||||
int _Offload_get_physical_device_number(void)
|
||||
{
|
||||
uint32_t index;
|
||||
EngineGetIndex(&index);
|
||||
return index;
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
// The parts of the offload library used only on the target
|
||||
|
||||
#ifndef OFFLOAD_TARGET_H_INCLUDED
|
||||
#define OFFLOAD_TARGET_H_INCLUDED
|
||||
|
||||
#include "offload_common.h"
|
||||
#include "coi/coi_server.h"
|
||||
|
||||
// The offload descriptor.
|
||||
class OffloadDescriptor
|
||||
{
|
||||
public:
|
||||
~OffloadDescriptor() {
|
||||
if (m_vars != 0) {
|
||||
free(m_vars);
|
||||
}
|
||||
}
|
||||
|
||||
// Entry point for COI. Synchronously execute offloaded region given
|
||||
// the provided buffers, misc and return data.
|
||||
static void offload(
|
||||
uint32_t buffer_count,
|
||||
void** buffers,
|
||||
void* misc_data,
|
||||
uint16_t misc_data_len,
|
||||
void* return_data,
|
||||
uint16_t return_data_len
|
||||
);
|
||||
|
||||
// scatters input data from in buffer to target variables
|
||||
void scatter_copyin_data();
|
||||
|
||||
// gathers output data to the buffer
|
||||
void gather_copyout_data();
|
||||
|
||||
// merges local variable descriptors with the descriptors received from
|
||||
// host
|
||||
void merge_var_descs(VarDesc *vars, VarDesc2 *vars2, int vars_total);
|
||||
|
||||
int get_offload_number() const {
|
||||
return m_offload_number;
|
||||
}
|
||||
|
||||
void set_offload_number(int number) {
|
||||
m_offload_number = number;
|
||||
}
|
||||
|
||||
private:
|
||||
// Constructor
|
||||
OffloadDescriptor() : m_vars(0)
|
||||
{}
|
||||
|
||||
private:
|
||||
typedef std::list<void*> BufferList;
|
||||
|
||||
// The Marshaller for the inputs of the offloaded region.
|
||||
Marshaller m_in;
|
||||
|
||||
// The Marshaller for the outputs of the offloaded region.
|
||||
Marshaller m_out;
|
||||
|
||||
// List of buffers that are passed to dispatch call
|
||||
BufferList m_buffers;
|
||||
|
||||
// Variable descriptors received from host
|
||||
VarDesc* m_vars;
|
||||
int m_vars_total;
|
||||
int m_offload_number;
|
||||
};
|
||||
|
||||
// one time target initialization in main
|
||||
extern void __offload_target_init(void);
|
||||
|
||||
// logical device index
|
||||
extern int mic_index;
|
||||
|
||||
// total number of available logical devices
|
||||
extern int mic_engines_total;
|
||||
|
||||
// device frequency (from COI)
|
||||
extern uint64_t mic_frequency;
|
||||
|
||||
struct RefInfo {
|
||||
RefInfo(bool is_add, long amount):is_added(is_add),count(amount)
|
||||
{}
|
||||
bool is_added;
|
||||
long count;
|
||||
};
|
||||
|
||||
#endif // OFFLOAD_TARGET_H_INCLUDED
|
||||
@@ -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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
extern "C" void __offload_target_main(void);
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
__offload_target_main();
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 OFFLOAD_TIMER_H_INCLUDED
|
||||
#define OFFLOAD_TIMER_H_INCLUDED
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include "liboffload_error_codes.h"
|
||||
|
||||
extern int timer_enabled;
|
||||
|
||||
#ifdef TIMING_SUPPORT
|
||||
|
||||
struct OffloadTargetTimerData {
|
||||
uint64_t frequency;
|
||||
struct {
|
||||
uint64_t start;
|
||||
uint64_t total;
|
||||
} phases[c_offload_target_max_phase];
|
||||
};
|
||||
|
||||
struct OffloadHostTimerData {
|
||||
// source file name and line number
|
||||
const char* file;
|
||||
int line;
|
||||
|
||||
// host timer data
|
||||
struct {
|
||||
uint64_t start;
|
||||
uint64_t total;
|
||||
} phases[c_offload_host_max_phase];
|
||||
|
||||
uint64_t sent_bytes;
|
||||
uint64_t received_bytes;
|
||||
int card_number;
|
||||
int offload_number;
|
||||
|
||||
// target timer data
|
||||
OffloadTargetTimerData target;
|
||||
|
||||
// next element
|
||||
OffloadHostTimerData *next;
|
||||
};
|
||||
|
||||
#if HOST_LIBRARY
|
||||
|
||||
extern int offload_report_level;
|
||||
extern int offload_report_enabled;
|
||||
#define OFFLOAD_REPORT_1 1
|
||||
#define OFFLOAD_REPORT_2 2
|
||||
#define OFFLOAD_REPORT_3 3
|
||||
#define OFFLOAD_REPORT_ON 1
|
||||
#define OFFLOAD_REPORT_OFF 0
|
||||
|
||||
#define OFFLOAD_TIMER_DATALEN() \
|
||||
((timer_enabled || (offload_report_level && offload_report_enabled)) ? \
|
||||
((1 + c_offload_target_max_phase) * sizeof(uint64_t)) : 0)
|
||||
|
||||
#define OFFLOAD_TIMER_START(timer_data, pnode) \
|
||||
if (timer_enabled || \
|
||||
(offload_report_level && offload_report_enabled)) { \
|
||||
offload_timer_start(timer_data, pnode); \
|
||||
}
|
||||
|
||||
#define OFFLOAD_TIMER_STOP(timer_data, pnode) \
|
||||
if (timer_enabled || \
|
||||
(offload_report_level && offload_report_enabled)) { \
|
||||
offload_timer_stop(timer_data, pnode); \
|
||||
}
|
||||
|
||||
#define OFFLOAD_TIMER_INIT(file, line) \
|
||||
offload_timer_init(file, line);
|
||||
|
||||
#define OFFLOAD_TIMER_TARGET_DATA(timer_data, data) \
|
||||
if (timer_enabled || \
|
||||
(offload_report_level && offload_report_enabled)) { \
|
||||
offload_timer_fill_target_data(timer_data, data); \
|
||||
}
|
||||
|
||||
#define OFFLOAD_TIMER_HOST_SDATA(timer_data, data) \
|
||||
if (offload_report_level && offload_report_enabled) { \
|
||||
offload_timer_fill_host_sdata(timer_data, data); \
|
||||
}
|
||||
|
||||
#define OFFLOAD_TIMER_HOST_RDATA(timer_data, data) \
|
||||
if (offload_report_level && offload_report_enabled) { \
|
||||
offload_timer_fill_host_rdata(timer_data, data); \
|
||||
}
|
||||
|
||||
#define OFFLOAD_TIMER_HOST_MIC_NUM(timer_data, data) \
|
||||
if (offload_report_level && offload_report_enabled) { \
|
||||
offload_timer_fill_host_mic_num(timer_data, data); \
|
||||
}
|
||||
|
||||
extern void offload_timer_start(OffloadHostTimerData *,
|
||||
OffloadHostPhase t_node);
|
||||
extern void offload_timer_stop(OffloadHostTimerData *,
|
||||
OffloadHostPhase t_node);
|
||||
extern OffloadHostTimerData * offload_timer_init(const char *file, int line);
|
||||
extern void offload_timer_fill_target_data(OffloadHostTimerData *,
|
||||
void *data);
|
||||
extern void offload_timer_fill_host_sdata(OffloadHostTimerData *,
|
||||
uint64_t sent_bytes);
|
||||
extern void offload_timer_fill_host_rdata(OffloadHostTimerData *,
|
||||
uint64_t sent_bytes);
|
||||
extern void offload_timer_fill_host_mic_num(OffloadHostTimerData *,
|
||||
int card_number);
|
||||
|
||||
// Utility structure for starting/stopping timer
|
||||
struct OffloadTimer {
|
||||
OffloadTimer(OffloadHostTimerData *data, OffloadHostPhase phase) :
|
||||
m_data(data),
|
||||
m_phase(phase)
|
||||
{
|
||||
OFFLOAD_TIMER_START(m_data, m_phase);
|
||||
}
|
||||
|
||||
~OffloadTimer()
|
||||
{
|
||||
OFFLOAD_TIMER_STOP(m_data, m_phase);
|
||||
}
|
||||
|
||||
private:
|
||||
OffloadHostTimerData* m_data;
|
||||
OffloadHostPhase m_phase;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
#define OFFLOAD_TIMER_DATALEN() \
|
||||
((timer_enabled) ? \
|
||||
((1 + c_offload_target_max_phase) * sizeof(uint64_t)) : 0)
|
||||
|
||||
#define OFFLOAD_TIMER_START(pnode) \
|
||||
if (timer_enabled) offload_timer_start(pnode);
|
||||
|
||||
#define OFFLOAD_TIMER_STOP(pnode) \
|
||||
if (timer_enabled) offload_timer_stop(pnode);
|
||||
|
||||
#define OFFLOAD_TIMER_INIT() \
|
||||
if (timer_enabled) offload_timer_init();
|
||||
|
||||
#define OFFLOAD_TIMER_TARGET_DATA(data) \
|
||||
if (timer_enabled) offload_timer_fill_target_data(data);
|
||||
|
||||
extern void offload_timer_start(OffloadTargetPhase t_node);
|
||||
extern void offload_timer_stop(OffloadTargetPhase t_node);
|
||||
extern void offload_timer_init(void);
|
||||
extern void offload_timer_fill_target_data(void *data);
|
||||
|
||||
#endif // HOST_LIBRARY
|
||||
|
||||
#else // TIMING_SUPPORT
|
||||
|
||||
#define OFFLOAD_TIMER_START(...)
|
||||
#define OFFLOAD_TIMER_STOP(...)
|
||||
#define OFFLOAD_TIMER_INIT(...)
|
||||
#define OFFLOAD_TIMER_TARGET_DATA(...)
|
||||
#define OFFLOAD_TIMER_DATALEN(...) (0)
|
||||
|
||||
#endif // TIMING_SUPPORT
|
||||
|
||||
#endif // OFFLOAD_TIMER_H_INCLUDED
|
||||
@@ -0,0 +1,359 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 "offload_timer.h"
|
||||
|
||||
#ifdef __INTEL_COMPILER
|
||||
#include <ia32intrin.h>
|
||||
#else // __INTEL_COMPILER
|
||||
#include <x86intrin.h>
|
||||
#endif // __INTEL_COMPILER
|
||||
|
||||
#include "offload_host.h"
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
int timer_enabled = 0;
|
||||
|
||||
#ifdef TIMING_SUPPORT
|
||||
|
||||
int offload_report_level = 0;
|
||||
int offload_report_enabled = 1;
|
||||
|
||||
static const int host_timer_prefix_spaces[] = {
|
||||
/*c_offload_host_setup_buffers*/ 0,
|
||||
/*c_offload_host_initialize*/ 2,
|
||||
/*c_offload_host_target_acquire*/ 2,
|
||||
/*c_offload_host_wait_deps*/ 2,
|
||||
/*c_offload_host_setup_buffers*/ 2,
|
||||
/*c_offload_host_alloc_buffers*/ 4,
|
||||
/*c_offload_host_setup_misc_data*/ 2,
|
||||
/*c_offload_host_alloc_data_buffer*/ 4,
|
||||
/*c_offload_host_send_pointers*/ 2,
|
||||
/*c_offload_host_gather_inputs*/ 2,
|
||||
/*c_offload_host_map_in_data_buffer*/ 4,
|
||||
/*c_offload_host_unmap_in_data_buffer*/ 4,
|
||||
/*c_offload_host_start_compute*/ 2,
|
||||
/*c_offload_host_wait_compute*/ 2,
|
||||
/*c_offload_host_start_buffers_reads*/ 2,
|
||||
/*c_offload_host_scatter_outputs*/ 2,
|
||||
/*c_offload_host_map_out_data_buffer*/ 4,
|
||||
/*c_offload_host_unmap_out_data_buffer*/ 4,
|
||||
/*c_offload_host_wait_buffers_reads*/ 2,
|
||||
/*c_offload_host_destroy_buffers*/ 2
|
||||
};
|
||||
|
||||
const static int target_timer_prefix_spaces[] = {
|
||||
/*c_offload_target_total_time*/ 0,
|
||||
/*c_offload_target_descriptor_setup*/ 2,
|
||||
/*c_offload_target_func_lookup*/ 2,
|
||||
/*c_offload_target_func_time*/ 2,
|
||||
/*c_offload_target_scatter_inputs*/ 4,
|
||||
/*c_offload_target_add_buffer_refs*/ 6,
|
||||
/*c_offload_target_compute*/ 4,
|
||||
/*c_offload_target_gather_outputs*/ 4,
|
||||
/*c_offload_target_release_buffer_refs*/ 6
|
||||
};
|
||||
|
||||
static OffloadHostTimerData* timer_data_head;
|
||||
static OffloadHostTimerData* timer_data_tail;
|
||||
static mutex_t timer_data_mutex;
|
||||
|
||||
static void offload_host_phase_name(std::stringstream &ss, int p_node);
|
||||
static void offload_target_phase_name(std::stringstream &ss, int p_node);
|
||||
|
||||
extern void Offload_Timer_Print(void)
|
||||
{
|
||||
std::string buf;
|
||||
std::stringstream ss;
|
||||
const char *stars =
|
||||
"**************************************************************";
|
||||
|
||||
ss << "\n\n" << stars << "\n";
|
||||
ss << " ";
|
||||
ss << report_get_message_str(c_report_title) << "\n";
|
||||
ss << stars << "\n";
|
||||
double frequency = cpu_frequency;
|
||||
|
||||
for (OffloadHostTimerData *pnode = timer_data_head;
|
||||
pnode != 0; pnode = pnode->next) {
|
||||
ss << " ";
|
||||
ss << report_get_message_str(c_report_from_file) << " "<< pnode->file;
|
||||
ss << report_get_message_str(c_report_line) << " " << pnode->line;
|
||||
ss << "\n";
|
||||
for (int i = 0; i < c_offload_host_max_phase ; i++) {
|
||||
ss << " ";
|
||||
offload_host_phase_name(ss, i);
|
||||
ss << " " << std::fixed << std::setprecision(5);
|
||||
ss << (double)pnode->phases[i].total / frequency << "\n";
|
||||
}
|
||||
|
||||
for (int i = 0; i < c_offload_target_max_phase ; i++) {
|
||||
double time = 0;
|
||||
if (pnode->target.frequency != 0) {
|
||||
time = (double) pnode->target.phases[i].total /
|
||||
(double) pnode->target.frequency;
|
||||
}
|
||||
ss << " ";
|
||||
offload_target_phase_name(ss, i);
|
||||
ss << " " << std::fixed << std::setprecision(5);
|
||||
ss << time << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
buf = ss.str();
|
||||
fprintf(stdout, buf.data());
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
extern void Offload_Report_Prolog(OffloadHostTimerData *pnode)
|
||||
{
|
||||
double frequency = cpu_frequency;
|
||||
std::string buf;
|
||||
std::stringstream ss;
|
||||
|
||||
if (pnode) {
|
||||
// [Offload] [Mic 0] [File] file.c
|
||||
ss << "[" << report_get_message_str(c_report_offload) << "] [";
|
||||
ss << report_get_message_str(c_report_mic) << " ";
|
||||
ss << pnode->card_number << "] [";
|
||||
ss << report_get_message_str(c_report_file);
|
||||
ss << "] " << pnode->file << "\n";
|
||||
|
||||
// [Offload] [Mic 0] [Line] 1234
|
||||
ss << "[" << report_get_message_str(c_report_offload) << "] [";
|
||||
ss << report_get_message_str(c_report_mic) << " ";
|
||||
ss << pnode->card_number << "] [";
|
||||
ss << report_get_message_str(c_report_line);
|
||||
ss << "] " << pnode->line << "\n";
|
||||
|
||||
// [Offload] [Mic 0] [Tag] Tag 1
|
||||
ss << "[" << report_get_message_str(c_report_offload) << "] [";
|
||||
ss << report_get_message_str(c_report_mic) << " ";
|
||||
ss << pnode->card_number << "] [";
|
||||
ss << report_get_message_str(c_report_tag);
|
||||
ss << "] " << report_get_message_str(c_report_tag);
|
||||
ss << " " << pnode->offload_number << "\n";
|
||||
|
||||
buf = ss.str();
|
||||
fprintf(stdout, buf.data());
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
extern void Offload_Report_Epilog(OffloadHostTimerData * timer_data)
|
||||
{
|
||||
double frequency = cpu_frequency;
|
||||
std::string buf;
|
||||
std::stringstream ss;
|
||||
|
||||
OffloadHostTimerData *pnode = timer_data;
|
||||
|
||||
if (!pnode) {
|
||||
return;
|
||||
}
|
||||
ss << "[" << report_get_message_str(c_report_offload) << "] [";
|
||||
ss << report_get_message_str(c_report_host) << "] [";
|
||||
ss << report_get_message_str(c_report_tag) << " ";
|
||||
ss << pnode->offload_number << "] [";
|
||||
ss << report_get_message_str(c_report_cpu_time) << "] ";
|
||||
ss << std::fixed << std::setprecision(6);
|
||||
ss << (double) pnode->phases[0].total / frequency;
|
||||
ss << report_get_message_str(c_report_seconds) << "\n";
|
||||
|
||||
if (offload_report_level >= OFFLOAD_REPORT_2) {
|
||||
ss << "[" << report_get_message_str(c_report_offload) << "] [";
|
||||
ss << report_get_message_str(c_report_mic);
|
||||
ss << " " << pnode->card_number;
|
||||
ss << "] [" << report_get_message_str(c_report_tag) << " ";
|
||||
ss << pnode->offload_number << "] [";
|
||||
ss << report_get_message_str(c_report_cpu_to_mic_data) << "] ";
|
||||
ss << pnode->sent_bytes << " ";
|
||||
ss << report_get_message_str(c_report_bytes) << "\n";
|
||||
}
|
||||
|
||||
double time = 0;
|
||||
if (pnode->target.frequency != 0) {
|
||||
time = (double) pnode->target.phases[0].total /
|
||||
(double) pnode->target.frequency;
|
||||
}
|
||||
ss << "[" << report_get_message_str(c_report_offload) << "] [";
|
||||
ss << report_get_message_str(c_report_mic) << " ";
|
||||
ss << pnode->card_number<< "] [";
|
||||
ss << report_get_message_str(c_report_tag) << " ";
|
||||
ss << pnode->offload_number << "] [";
|
||||
ss << report_get_message_str(c_report_mic_time) << "] ";
|
||||
ss << std::fixed << std::setprecision(6) << time;
|
||||
ss << report_get_message_str(c_report_seconds) << "\n";
|
||||
|
||||
if (offload_report_level >= OFFLOAD_REPORT_2) {
|
||||
ss << "[" << report_get_message_str(c_report_offload) << "] [";
|
||||
ss << report_get_message_str(c_report_mic);
|
||||
ss << " " << pnode->card_number;
|
||||
ss << "] [" << report_get_message_str(c_report_tag) << " ";
|
||||
ss << pnode->offload_number << "] [";
|
||||
ss << report_get_message_str(c_report_mic_to_cpu_data) << "] ";
|
||||
ss << pnode->received_bytes << " ";
|
||||
ss << report_get_message_str(c_report_bytes) << "\n";
|
||||
}
|
||||
ss << "\n";
|
||||
|
||||
buf = ss.str();
|
||||
fprintf(stdout, buf.data());
|
||||
fflush(stdout);
|
||||
|
||||
offload_report_free_data(timer_data);
|
||||
}
|
||||
|
||||
extern void offload_report_free_data(OffloadHostTimerData * timer_data)
|
||||
{
|
||||
OffloadHostTimerData *pnode_last = NULL;
|
||||
|
||||
for (OffloadHostTimerData *pnode = timer_data_head;
|
||||
pnode != 0; pnode = pnode->next) {
|
||||
if (timer_data == pnode) {
|
||||
if (pnode_last) {
|
||||
pnode_last->next = pnode->next;
|
||||
}
|
||||
else {
|
||||
timer_data_head = pnode->next;
|
||||
}
|
||||
OFFLOAD_FREE(pnode);
|
||||
break;
|
||||
}
|
||||
pnode_last = pnode;
|
||||
}
|
||||
}
|
||||
|
||||
static void fill_buf_with_spaces(std::stringstream &ss, int num)
|
||||
{
|
||||
for (; num > 0; num--) {
|
||||
ss << " ";
|
||||
}
|
||||
}
|
||||
|
||||
static void offload_host_phase_name(std::stringstream &ss, int p_node)
|
||||
{
|
||||
int prefix_spaces;
|
||||
int str_length;
|
||||
int tail_length;
|
||||
const int message_length = 40;
|
||||
char const *str;
|
||||
|
||||
str = report_get_host_stage_str(p_node);
|
||||
prefix_spaces = host_timer_prefix_spaces[p_node];
|
||||
fill_buf_with_spaces(ss, prefix_spaces);
|
||||
str_length = strlen(str);
|
||||
ss << str;
|
||||
tail_length = message_length - prefix_spaces - str_length;
|
||||
tail_length = tail_length > 0? tail_length : 1;
|
||||
fill_buf_with_spaces(ss, tail_length);
|
||||
}
|
||||
|
||||
static void offload_target_phase_name(std::stringstream &ss, int p_node)
|
||||
{
|
||||
int prefix_spaces;
|
||||
int str_length;
|
||||
const int message_length = 40;
|
||||
int tail_length;
|
||||
char const *str;
|
||||
|
||||
str = report_get_target_stage_str(p_node);
|
||||
prefix_spaces = target_timer_prefix_spaces[p_node];
|
||||
fill_buf_with_spaces(ss, prefix_spaces);
|
||||
str_length = strlen(str);
|
||||
ss << str;
|
||||
tail_length = message_length - prefix_spaces - str_length;
|
||||
tail_length = (tail_length > 0)? tail_length : 1;
|
||||
fill_buf_with_spaces(ss, tail_length);
|
||||
}
|
||||
|
||||
void offload_timer_start(OffloadHostTimerData * timer_data,
|
||||
OffloadHostPhase p_type)
|
||||
{
|
||||
timer_data->phases[p_type].start = _rdtsc();
|
||||
}
|
||||
|
||||
void offload_timer_stop(OffloadHostTimerData * timer_data,
|
||||
OffloadHostPhase p_type)
|
||||
{
|
||||
timer_data->phases[p_type].total += _rdtsc() -
|
||||
timer_data->phases[p_type].start;
|
||||
}
|
||||
|
||||
void offload_timer_fill_target_data(OffloadHostTimerData * timer_data,
|
||||
void *buf)
|
||||
{
|
||||
uint64_t *data = (uint64_t*) buf;
|
||||
|
||||
timer_data->target.frequency = *data++;
|
||||
for (int i = 0; i < c_offload_target_max_phase; i++) {
|
||||
timer_data->target.phases[i].total = *data++;
|
||||
}
|
||||
}
|
||||
|
||||
void offload_timer_fill_host_sdata(OffloadHostTimerData * timer_data,
|
||||
uint64_t sent_bytes)
|
||||
{
|
||||
if (timer_data) {
|
||||
timer_data->sent_bytes += sent_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
void offload_timer_fill_host_rdata(OffloadHostTimerData * timer_data,
|
||||
uint64_t received_bytes)
|
||||
{
|
||||
if (timer_data) {
|
||||
timer_data->received_bytes += received_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
void offload_timer_fill_host_mic_num(OffloadHostTimerData * timer_data,
|
||||
int card_number)
|
||||
{
|
||||
if (timer_data) {
|
||||
timer_data->card_number = card_number;
|
||||
}
|
||||
}
|
||||
|
||||
OffloadHostTimerData* offload_timer_init(const char *file, int line)
|
||||
{
|
||||
static bool first_time = true;
|
||||
OffloadHostTimerData* timer_data = NULL;
|
||||
|
||||
timer_data_mutex.lock();
|
||||
{
|
||||
if (timer_enabled ||
|
||||
(offload_report_level && offload_report_enabled)) {
|
||||
timer_data = (OffloadHostTimerData*)
|
||||
OFFLOAD_MALLOC(sizeof(OffloadHostTimerData), 0);
|
||||
memset(timer_data, 0, sizeof(OffloadHostTimerData));
|
||||
|
||||
timer_data->offload_number = OFFLOAD_DEBUG_INCR_OFLD_NUM() - 1;
|
||||
|
||||
if (timer_data_head == 0) {
|
||||
timer_data_head = timer_data;
|
||||
timer_data_tail = timer_data;
|
||||
}
|
||||
else {
|
||||
timer_data_tail->next = timer_data;
|
||||
timer_data_tail = timer_data;
|
||||
}
|
||||
|
||||
timer_data->file = file;
|
||||
timer_data->line = line;
|
||||
}
|
||||
}
|
||||
timer_data_mutex.unlock();
|
||||
return timer_data;
|
||||
}
|
||||
|
||||
#endif // TIMING_SUPPORT
|
||||
@@ -0,0 +1,67 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 "offload_timer.h"
|
||||
#include "offload_target.h"
|
||||
|
||||
#ifdef __INTEL_COMPILER
|
||||
#include <ia32intrin.h>
|
||||
#else // __INTEL_COMPILER
|
||||
#include <x86intrin.h>
|
||||
#endif // __INTEL_COMPILER
|
||||
|
||||
|
||||
|
||||
int timer_enabled = 0;
|
||||
|
||||
#ifdef TIMING_SUPPORT
|
||||
|
||||
#if defined(LINUX) || defined(FREEBSD)
|
||||
static __thread OffloadTargetTimerData timer_data;
|
||||
#else // WINNT
|
||||
static __declspec(thread) OffloadTargetTimerData timer_data;
|
||||
#endif // defined(LINUX) || defined(FREEBSD)
|
||||
|
||||
|
||||
void offload_timer_start(
|
||||
OffloadTargetPhase p_type
|
||||
)
|
||||
{
|
||||
timer_data.phases[p_type].start = _rdtsc();
|
||||
}
|
||||
|
||||
void offload_timer_stop(
|
||||
OffloadTargetPhase p_type
|
||||
)
|
||||
{
|
||||
timer_data.phases[p_type].total += _rdtsc() -
|
||||
timer_data.phases[p_type].start;
|
||||
}
|
||||
|
||||
void offload_timer_init()
|
||||
{
|
||||
memset(&timer_data, 0, sizeof(OffloadTargetTimerData));
|
||||
}
|
||||
|
||||
void offload_timer_fill_target_data(
|
||||
void *buf
|
||||
)
|
||||
{
|
||||
uint64_t *data = (uint64_t*) buf;
|
||||
|
||||
timer_data.frequency = mic_frequency;
|
||||
memcpy(data++, &(timer_data.frequency), sizeof(uint64_t));
|
||||
|
||||
for (int i = 0; i < c_offload_target_max_phase; i++) {
|
||||
memcpy(data++, &(timer_data.phases[i].total), sizeof(uint64_t));
|
||||
}
|
||||
}
|
||||
|
||||
#endif // TIMING_SUPPORT
|
||||
@@ -0,0 +1,309 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 "offload_trace.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <sstream>
|
||||
#include "liboffload_error_codes.h"
|
||||
|
||||
extern const char *prefix;
|
||||
|
||||
#if !HOST_LIBRARY
|
||||
extern int mic_index;
|
||||
#endif
|
||||
|
||||
// The debug routines
|
||||
|
||||
static const char * offload_stage(std::stringstream &ss,
|
||||
int offload_number,
|
||||
const char *tag,
|
||||
const char *text,
|
||||
bool print_tag)
|
||||
{
|
||||
ss << "[" << report_get_message_str(c_report_offload) << "]";
|
||||
#if HOST_LIBRARY
|
||||
ss << " [" << prefix << "]";
|
||||
if (print_tag) {
|
||||
ss << " [" << report_get_message_str(c_report_tag);
|
||||
ss << " " << offload_number << "]";
|
||||
}
|
||||
else {
|
||||
ss << " ";
|
||||
}
|
||||
ss << " [" << tag << "]";
|
||||
ss << " " << text;
|
||||
#else
|
||||
ss << " [" << prefix << " " << mic_index << "]";
|
||||
if (print_tag) {
|
||||
ss << " [" << report_get_message_str(c_report_tag);
|
||||
ss << " " << offload_number << "]";
|
||||
}
|
||||
ss << " [" << tag << "]";
|
||||
ss << " " << text;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char * offload_signal(std::stringstream &ss,
|
||||
int offload_number,
|
||||
const char *tag,
|
||||
const char *text)
|
||||
{
|
||||
ss << "[" << report_get_message_str(c_report_offload) << "]";
|
||||
ss << " [" << prefix << "]";
|
||||
ss << " [" << report_get_message_str(c_report_tag);
|
||||
ss << " " << offload_number << "]";
|
||||
ss << " [" << tag << "]";
|
||||
ss << " " << text;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void offload_stage_print(int stage, int offload_number, ...)
|
||||
{
|
||||
std::string buf;
|
||||
std::stringstream ss;
|
||||
char const *str1;
|
||||
char const *str2;
|
||||
va_list va_args;
|
||||
va_start(va_args, offload_number);
|
||||
va_arg(va_args, char*);
|
||||
|
||||
switch (stage) {
|
||||
case c_offload_start:
|
||||
str1 = report_get_message_str(c_report_state);
|
||||
str2 = report_get_message_str(c_report_start);
|
||||
offload_stage(ss, offload_number, str1, str2, true);
|
||||
break;
|
||||
case c_offload_init:
|
||||
str1 = report_get_message_str(c_report_state);
|
||||
str2 = report_get_message_str(c_report_init);
|
||||
offload_stage(ss, offload_number, str1, str2, false);
|
||||
ss << " " << report_get_message_str(c_report_logical_card);
|
||||
ss << " " << va_arg(va_args, int);
|
||||
ss << " = " << report_get_message_str(c_report_physical_card);
|
||||
ss << " " << va_arg(va_args, int);
|
||||
break;
|
||||
case c_offload_register:
|
||||
str1 = report_get_message_str(c_report_state);
|
||||
str2 = report_get_message_str(c_report_register);
|
||||
offload_stage(ss, offload_number, str1, str2, true);
|
||||
break;
|
||||
case c_offload_init_func:
|
||||
str1 = report_get_message_str(c_report_state);
|
||||
str2 = report_get_message_str(c_report_init_func);
|
||||
offload_stage(ss, offload_number, str1, str2, true);
|
||||
ss << ": " << va_arg(va_args, char*);
|
||||
break;
|
||||
case c_offload_create_buf_host:
|
||||
str1 = report_get_message_str(c_report_state);
|
||||
str2 = report_get_message_str(c_report_create_buf_host);
|
||||
offload_stage(ss, offload_number, str1, str2, true);
|
||||
ss << ": base=0x" << std::hex << va_arg(va_args, uint64_t);
|
||||
ss << " length=" << std::dec << va_arg(va_args, uint64_t);
|
||||
break;
|
||||
case c_offload_create_buf_mic:
|
||||
str1 = report_get_message_str(c_report_state);
|
||||
str2 = report_get_message_str(c_report_create_buf_mic);
|
||||
offload_stage(ss, offload_number, str1, str2, true);
|
||||
ss << ": size=" << va_arg(va_args, uint64_t);
|
||||
ss << " offset=" << va_arg(va_args, int);
|
||||
if (va_arg(va_args,int))
|
||||
ss << " (2M page)";
|
||||
break;
|
||||
case c_offload_send_pointer_data:
|
||||
str1 = report_get_message_str(c_report_state);
|
||||
str2 = report_get_message_str(c_report_send_pointer_data);
|
||||
offload_stage(ss, offload_number, str1, str2, true);
|
||||
break;
|
||||
case c_offload_sent_pointer_data:
|
||||
str1 = report_get_message_str(c_report_state);
|
||||
str2 = report_get_message_str(c_report_sent_pointer_data);
|
||||
offload_stage(ss, offload_number, str1, str2, true);
|
||||
ss << " " << va_arg(va_args, uint64_t);
|
||||
break;
|
||||
case c_offload_gather_copyin_data:
|
||||
str1 = report_get_message_str(c_report_state);
|
||||
str2 = report_get_message_str(c_report_gather_copyin_data);
|
||||
offload_stage(ss, offload_number, str1, str2, true);
|
||||
break;
|
||||
case c_offload_copyin_data:
|
||||
str1 = report_get_message_str(c_report_state);
|
||||
str2 = report_get_message_str(c_report_copyin_data);
|
||||
offload_stage(ss, offload_number, str1, str2, true);
|
||||
ss << " " << va_arg(va_args, uint64_t) << " ";
|
||||
break;
|
||||
case c_offload_compute:
|
||||
str1 = report_get_message_str(c_report_state);
|
||||
str2 = report_get_message_str(c_report_compute);
|
||||
offload_stage(ss, offload_number, str1, str2, true);
|
||||
break;
|
||||
case c_offload_receive_pointer_data:
|
||||
str1 = report_get_message_str(c_report_state);
|
||||
str2 = report_get_message_str(c_report_receive_pointer_data);
|
||||
offload_stage(ss, offload_number, str1, str2, true);
|
||||
break;
|
||||
case c_offload_received_pointer_data:
|
||||
str1 = report_get_message_str(c_report_state);
|
||||
str2 = report_get_message_str(c_report_received_pointer_data);
|
||||
offload_stage(ss, offload_number, str1, str2, true);
|
||||
ss << " " << va_arg(va_args, uint64_t);
|
||||
break;
|
||||
case c_offload_start_target_func:
|
||||
str1 = report_get_message_str(c_report_state);
|
||||
str2 = report_get_message_str(c_report_start_target_func);
|
||||
offload_stage(ss, offload_number, str1, str2, true);
|
||||
ss << ": " << va_arg(va_args, char*);
|
||||
break;
|
||||
case c_offload_var:
|
||||
str1 = report_get_message_str(c_report_var);
|
||||
offload_stage(ss, offload_number, str1, " ", true);
|
||||
va_arg(va_args, int);
|
||||
ss << va_arg(va_args, char*);
|
||||
ss << " " << " " << va_arg(va_args, char*);
|
||||
break;
|
||||
case c_offload_scatter_copyin_data:
|
||||
str1 = report_get_message_str(c_report_state);
|
||||
str2 = report_get_message_str(c_report_scatter_copyin_data);
|
||||
offload_stage(ss, offload_number, str1, str2, true);
|
||||
break;
|
||||
case c_offload_gather_copyout_data:
|
||||
str1 = report_get_message_str(c_report_state);
|
||||
str2 = report_get_message_str(c_report_gather_copyout_data);
|
||||
offload_stage(ss, offload_number, str1, str2, true);
|
||||
break;
|
||||
case c_offload_scatter_copyout_data:
|
||||
str1 = report_get_message_str(c_report_state);
|
||||
str2 = report_get_message_str(c_report_scatter_copyout_data);
|
||||
offload_stage(ss, offload_number, str1, str2, true);
|
||||
break;
|
||||
case c_offload_copyout_data:
|
||||
str1 = report_get_message_str(c_report_state);
|
||||
str2 = report_get_message_str(c_report_copyout_data);
|
||||
offload_stage(ss, offload_number, str1, str2, true);
|
||||
ss << " " << va_arg(va_args, uint64_t);
|
||||
break;
|
||||
case c_offload_signal:
|
||||
{
|
||||
uint64_t *signal;
|
||||
str1 = report_get_message_str(c_report_state_signal);
|
||||
str2 = report_get_message_str(c_report_signal);
|
||||
offload_signal(ss, offload_number, str1, str2);
|
||||
signal = va_arg(va_args, uint64_t*);
|
||||
if (signal)
|
||||
ss << " 0x" << std::hex << *signal;
|
||||
else
|
||||
ss << " none";
|
||||
}
|
||||
break;
|
||||
case c_offload_wait:
|
||||
{
|
||||
int count;
|
||||
uint64_t **signal;
|
||||
str1 = report_get_message_str(c_report_state_signal);
|
||||
str2 = report_get_message_str(c_report_wait);
|
||||
offload_signal(ss, offload_number, str1, str2);
|
||||
count = va_arg(va_args, int);
|
||||
signal = va_arg(va_args, uint64_t**);
|
||||
if (count) {
|
||||
while (count) {
|
||||
ss << " " << std::hex << signal[count-1];
|
||||
count--;
|
||||
}
|
||||
}
|
||||
else
|
||||
ss << " none";
|
||||
}
|
||||
break;
|
||||
case c_offload_unregister:
|
||||
str1 = report_get_message_str(c_report_state);
|
||||
str2 = report_get_message_str(c_report_unregister);
|
||||
offload_stage(ss, offload_number, str1, str2, false);
|
||||
break;
|
||||
case c_offload_destroy:
|
||||
str1 = report_get_message_str(c_report_state);
|
||||
str2 = report_get_message_str(c_report_destroy);
|
||||
offload_stage(ss, offload_number, str1, str2, true);
|
||||
break;
|
||||
case c_offload_myoinit:
|
||||
str1 = report_get_message_str(c_report_state);
|
||||
str2 = report_get_message_str(c_report_myoinit);
|
||||
offload_stage(ss, offload_number, str1, str2, false);
|
||||
break;
|
||||
case c_offload_myoregister:
|
||||
str1 = report_get_message_str(c_report_state);
|
||||
str2 = report_get_message_str(c_report_myoregister);
|
||||
offload_stage(ss, offload_number, str1, str2, false);
|
||||
break;
|
||||
case c_offload_myofini:
|
||||
str1 = report_get_message_str(c_report_state);
|
||||
str2 = report_get_message_str(c_report_myofini);
|
||||
offload_stage(ss, offload_number, str1, str2, false);
|
||||
break;
|
||||
case c_offload_mic_myo_shared:
|
||||
str1 = report_get_message_str(c_report_state);
|
||||
str2 = report_get_message_str(c_report_mic_myo_shared);
|
||||
offload_stage(ss, offload_number, str1, str2, false);
|
||||
ss << " " << va_arg(va_args, char*);
|
||||
break;
|
||||
case c_offload_mic_myo_fptr:
|
||||
str1 = report_get_message_str(c_report_state);
|
||||
str2 = report_get_message_str(c_report_mic_myo_fptr);
|
||||
offload_stage(ss, offload_number, str1, str2, false);
|
||||
ss << " " << va_arg(va_args, char*);
|
||||
break;
|
||||
case c_offload_myosharedmalloc:
|
||||
str1 = report_get_message_str(c_report_state);
|
||||
str2 = report_get_message_str(c_report_myosharedmalloc);
|
||||
offload_stage(ss, offload_number, str1, str2, false);
|
||||
va_arg(va_args, char*);
|
||||
ss << " " << va_arg(va_args, size_t);
|
||||
break;
|
||||
case c_offload_myosharedfree:
|
||||
str1 = report_get_message_str(c_report_state);
|
||||
str2 = report_get_message_str(c_report_myosharedfree);
|
||||
offload_stage(ss, offload_number, str1, str2, false);
|
||||
break;
|
||||
case c_offload_myosharedalignedmalloc:
|
||||
str1 = report_get_message_str(c_report_state);
|
||||
str2 = report_get_message_str(c_report_myosharedalignedmalloc);
|
||||
offload_stage(ss, offload_number, str1, str2, false);
|
||||
va_arg(va_args, char*);
|
||||
ss << " " << va_arg(va_args, size_t);
|
||||
ss << " " << va_arg(va_args, size_t);
|
||||
break;
|
||||
case c_offload_myosharedalignedfree:
|
||||
str1 = report_get_message_str(c_report_state);
|
||||
str2 = report_get_message_str(c_report_myosharedalignedfree);
|
||||
offload_stage(ss, offload_number, str1, str2, false);
|
||||
break;
|
||||
case c_offload_myoacquire:
|
||||
str1 = report_get_message_str(c_report_state);
|
||||
str2 = report_get_message_str(c_report_myoacquire);
|
||||
offload_stage(ss, offload_number, str1, str2, false);
|
||||
break;
|
||||
case c_offload_myorelease:
|
||||
str1 = report_get_message_str(c_report_state);
|
||||
str2 = report_get_message_str(c_report_myorelease);
|
||||
offload_stage(ss, offload_number, str1, str2, false);
|
||||
break;
|
||||
default:
|
||||
LIBOFFLOAD_ERROR(c_report_unknown_trace_node);
|
||||
abort();
|
||||
}
|
||||
ss << "\n";
|
||||
buf = ss.str();
|
||||
fprintf(stdout, buf.data());
|
||||
fflush(stdout);
|
||||
|
||||
va_end(va_args);
|
||||
return;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
// The parts of the offload library common to host and target
|
||||
|
||||
void offload_stage_print(int stage, int offload_number, ...);
|
||||
|
||||
enum OffloadTraceStage {
|
||||
// Total time spent on the target
|
||||
c_offload_start = 0,
|
||||
c_offload_init,
|
||||
c_offload_register,
|
||||
c_offload_init_func,
|
||||
c_offload_create_buf_host,
|
||||
c_offload_create_buf_mic,
|
||||
c_offload_send_pointer_data,
|
||||
c_offload_sent_pointer_data,
|
||||
c_offload_gather_copyin_data,
|
||||
c_offload_copyin_data,
|
||||
c_offload_compute,
|
||||
c_offload_receive_pointer_data,
|
||||
c_offload_received_pointer_data,
|
||||
c_offload_start_target_func,
|
||||
c_offload_var,
|
||||
c_offload_scatter_copyin_data,
|
||||
c_offload_gather_copyout_data,
|
||||
c_offload_scatter_copyout_data,
|
||||
c_offload_copyout_data,
|
||||
c_offload_signal,
|
||||
c_offload_wait,
|
||||
c_offload_unregister,
|
||||
c_offload_destroy,
|
||||
c_offload_finish,
|
||||
c_offload_myoinit,
|
||||
c_offload_myoregister,
|
||||
c_offload_mic_myo_shared,
|
||||
c_offload_mic_myo_fptr,
|
||||
c_offload_myosharedmalloc,
|
||||
c_offload_myosharedfree,
|
||||
c_offload_myosharedalignedmalloc,
|
||||
c_offload_myosharedalignedfree,
|
||||
c_offload_myoacquire,
|
||||
c_offload_myorelease,
|
||||
c_offload_myofini
|
||||
};
|
||||
@@ -0,0 +1,206 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 "offload_util.h"
|
||||
#include <errno.h>
|
||||
#include "liboffload_error_codes.h"
|
||||
|
||||
#ifdef TARGET_WINNT
|
||||
void *thread_getspecific(pthread_key_t key)
|
||||
{
|
||||
if (key == 0) {
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
return TlsGetValue(key);
|
||||
}
|
||||
}
|
||||
|
||||
int thread_setspecific(pthread_key_t key, const void *value)
|
||||
{
|
||||
return (TlsSetValue(key, (LPVOID)value)) ? 0 : GetLastError();
|
||||
}
|
||||
#endif // TARGET_WINNT
|
||||
|
||||
bool __offload_parse_size_string(const char *str, uint64_t &new_size)
|
||||
{
|
||||
uint64_t val;
|
||||
char *suffix;
|
||||
|
||||
errno = 0;
|
||||
#ifdef TARGET_WINNT
|
||||
val = strtoul(str, &suffix, 10);
|
||||
#else // TARGET_WINNT
|
||||
val = strtoull(str, &suffix, 10);
|
||||
#endif // TARGET_WINNT
|
||||
if (errno != 0 || suffix == str) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (suffix[0] == '\0') {
|
||||
// default is Kilobytes
|
||||
new_size = val * 1024;
|
||||
return true;
|
||||
}
|
||||
else if (suffix[1] == '\0') {
|
||||
// Optional suffixes: B (bytes), K (Kilobytes), M (Megabytes),
|
||||
// G (Gigabytes), or T (Terabytes) specify the units.
|
||||
switch (suffix[0]) {
|
||||
case 'b':
|
||||
case 'B':
|
||||
new_size = val;
|
||||
break;
|
||||
|
||||
case 'k':
|
||||
case 'K':
|
||||
new_size = val * 1024;
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
case 'M':
|
||||
new_size = val * 1024 * 1024;
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
case 'G':
|
||||
new_size = val * 1024 * 1024 * 1024;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
case 'T':
|
||||
new_size = val * 1024 * 1024 * 1024 * 1024;
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool __offload_parse_int_string(const char *str, int64_t &value)
|
||||
{
|
||||
int64_t val;
|
||||
char *suffix;
|
||||
|
||||
errno = 0;
|
||||
#ifdef TARGET_WINNT
|
||||
val = strtol(str, &suffix, 0);
|
||||
#else
|
||||
val = strtoll(str, &suffix, 0);
|
||||
#endif
|
||||
if (errno == 0 && suffix != str && *suffix == '\0') {
|
||||
value = val;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef TARGET_WINNT
|
||||
extern void* DL_open(const char *path)
|
||||
{
|
||||
void *handle;
|
||||
int error_mode;
|
||||
|
||||
/*
|
||||
* do not display message box with error if it the call below fails to
|
||||
* load dynamic library.
|
||||
*/
|
||||
error_mode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
|
||||
|
||||
/* load dynamic library */
|
||||
handle = (void*) LoadLibrary(path);
|
||||
|
||||
/* restore error mode */
|
||||
SetErrorMode(error_mode);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
extern int DL_addr(const void *addr, Dl_info *dl_info)
|
||||
{
|
||||
MEMORY_BASIC_INFORMATION mem_info;
|
||||
char mod_name[MAX_PATH];
|
||||
HMODULE mod_handle;
|
||||
|
||||
/* Fill MEMORY_BASIC_INFORMATION struct */
|
||||
if (!VirtualQuery(addr, &mem_info, sizeof(mem_info))) {
|
||||
return 0;
|
||||
}
|
||||
mod_handle = (HMODULE)mem_info.AllocationBase;
|
||||
|
||||
/* ANSI file name for module */
|
||||
if (!GetModuleFileNameA(mod_handle, (char*) mod_name, sizeof(mod_name))) {
|
||||
return 0;
|
||||
}
|
||||
strcpy(dl_info->dli_fname, mod_name);
|
||||
dl_info->dli_fbase = mem_info.BaseAddress;
|
||||
dl_info->dli_saddr = addr;
|
||||
strcpy(dl_info->dli_sname, mod_name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Run once
|
||||
static BOOL CALLBACK __offload_run_once_wrapper(
|
||||
PINIT_ONCE initOnce,
|
||||
PVOID parameter,
|
||||
PVOID *context
|
||||
)
|
||||
{
|
||||
void (*init_routine)(void) = (void(*)(void)) parameter;
|
||||
init_routine();
|
||||
return true;
|
||||
}
|
||||
|
||||
void __offload_run_once(OffloadOnceControl *ctrl, void (*func)(void))
|
||||
{
|
||||
InitOnceExecuteOnce(ctrl, __offload_run_once_wrapper, (void*) func, 0);
|
||||
}
|
||||
#endif // TARGET_WINNT
|
||||
|
||||
/* ARGSUSED */ // version is not used on windows
|
||||
void* DL_sym(void *handle, const char *name, const char *version)
|
||||
{
|
||||
#ifdef TARGET_WINNT
|
||||
return GetProcAddress((HMODULE) handle, name);
|
||||
#else // TARGET_WINNT
|
||||
if (version == 0) {
|
||||
return dlsym(handle, name);
|
||||
}
|
||||
else {
|
||||
return dlvsym(handle, name, version);
|
||||
}
|
||||
#endif // TARGET_WINNT
|
||||
}
|
||||
|
||||
int64_t get_el_value(
|
||||
char *base,
|
||||
int64_t offset,
|
||||
int64_t size)
|
||||
{
|
||||
int64_t val = 0;
|
||||
switch (size) {
|
||||
case 1:
|
||||
val = static_cast<int64_t>(*((char *)(base + offset)));
|
||||
break;
|
||||
case 2:
|
||||
val = static_cast<int64_t>(*((short *)(base + offset)));
|
||||
break;
|
||||
case 4:
|
||||
val = static_cast<int64_t>(*((int *)(base + offset)));
|
||||
break;
|
||||
default:
|
||||
val = *((int64_t *)(base + offset));
|
||||
break;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 OFFLOAD_UTIL_H_INCLUDED
|
||||
#define OFFLOAD_UTIL_H_INCLUDED
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef TARGET_WINNT
|
||||
#include <windows.h>
|
||||
#include <process.h>
|
||||
#else // TARGET_WINNT
|
||||
#include <dlfcn.h>
|
||||
#include <pthread.h>
|
||||
#endif // TARGET_WINNT
|
||||
|
||||
#ifdef TARGET_WINNT
|
||||
typedef unsigned pthread_key_t;
|
||||
typedef int pid_t;
|
||||
|
||||
#define __func__ __FUNCTION__
|
||||
#define strtok_r(s,d,p) strtok_s(s,d,p)
|
||||
#define strcasecmp(a,b) stricmp(a,b)
|
||||
|
||||
#define thread_key_create(key, destructor) \
|
||||
(((*key = TlsAlloc()) > 0) ? 0 : GetLastError())
|
||||
#define thread_key_delete(key) TlsFree(key)
|
||||
|
||||
#ifndef S_ISREG
|
||||
#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
|
||||
#endif
|
||||
|
||||
void* thread_getspecific(pthread_key_t key);
|
||||
int thread_setspecific(pthread_key_t key, const void *value);
|
||||
#else
|
||||
#define thread_key_create(key, destructor) \
|
||||
pthread_key_create((key), (destructor))
|
||||
#define thread_key_delete(key) pthread_key_delete(key)
|
||||
#define thread_getspecific(key) pthread_getspecific(key)
|
||||
#define thread_setspecific(key, value) pthread_setspecific(key, value)
|
||||
#endif // TARGET_WINNT
|
||||
|
||||
// Mutex implementation
|
||||
struct mutex_t {
|
||||
mutex_t() {
|
||||
#ifdef TARGET_WINNT
|
||||
InitializeCriticalSection(&m_lock);
|
||||
#else // TARGET_WINNT
|
||||
pthread_mutex_init(&m_lock, 0);
|
||||
#endif // TARGET_WINNT
|
||||
}
|
||||
|
||||
~mutex_t() {
|
||||
#ifdef TARGET_WINNT
|
||||
DeleteCriticalSection(&m_lock);
|
||||
#else // TARGET_WINNT
|
||||
pthread_mutex_destroy(&m_lock);
|
||||
#endif // TARGET_WINNT
|
||||
}
|
||||
|
||||
void lock() {
|
||||
#ifdef TARGET_WINNT
|
||||
EnterCriticalSection(&m_lock);
|
||||
#else // TARGET_WINNT
|
||||
pthread_mutex_lock(&m_lock);
|
||||
#endif // TARGET_WINNT
|
||||
}
|
||||
|
||||
void unlock() {
|
||||
#ifdef TARGET_WINNT
|
||||
LeaveCriticalSection(&m_lock);
|
||||
#else // TARGET_WINNT
|
||||
pthread_mutex_unlock(&m_lock);
|
||||
#endif // TARGET_WINNT
|
||||
}
|
||||
|
||||
private:
|
||||
#ifdef TARGET_WINNT
|
||||
CRITICAL_SECTION m_lock;
|
||||
#else
|
||||
pthread_mutex_t m_lock;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct mutex_locker_t {
|
||||
mutex_locker_t(mutex_t &mutex) : m_mutex(mutex) {
|
||||
m_mutex.lock();
|
||||
}
|
||||
|
||||
~mutex_locker_t() {
|
||||
m_mutex.unlock();
|
||||
}
|
||||
|
||||
private:
|
||||
mutex_t &m_mutex;
|
||||
};
|
||||
|
||||
// Dynamic loader interface
|
||||
#ifdef TARGET_WINNT
|
||||
struct Dl_info
|
||||
{
|
||||
char dli_fname[MAX_PATH];
|
||||
void *dli_fbase;
|
||||
char dli_sname[MAX_PATH];
|
||||
const void *dli_saddr;
|
||||
};
|
||||
|
||||
void* DL_open(const char *path);
|
||||
#define DL_close(handle) FreeLibrary((HMODULE) (handle))
|
||||
int DL_addr(const void *addr, Dl_info *info);
|
||||
#else
|
||||
#define DL_open(path) dlopen((path), RTLD_NOW)
|
||||
#define DL_close(handle) dlclose(handle)
|
||||
#define DL_addr(addr, info) dladdr((addr), (info))
|
||||
#endif // TARGET_WINNT
|
||||
|
||||
extern void* DL_sym(void *handle, const char *name, const char *version);
|
||||
|
||||
// One-time initialization API
|
||||
#ifdef TARGET_WINNT
|
||||
typedef INIT_ONCE OffloadOnceControl;
|
||||
#define OFFLOAD_ONCE_CONTROL_INIT INIT_ONCE_STATIC_INIT
|
||||
|
||||
extern void __offload_run_once(OffloadOnceControl *ctrl, void (*func)(void));
|
||||
#else
|
||||
typedef pthread_once_t OffloadOnceControl;
|
||||
#define OFFLOAD_ONCE_CONTROL_INIT PTHREAD_ONCE_INIT
|
||||
|
||||
#define __offload_run_once(ctrl, func) pthread_once(ctrl, func)
|
||||
#endif // TARGET_WINNT
|
||||
|
||||
// Parses size specification string.
|
||||
extern bool __offload_parse_size_string(const char *str, uint64_t &new_size);
|
||||
|
||||
// Parses string with integer value
|
||||
extern bool __offload_parse_int_string(const char *str, int64_t &value);
|
||||
|
||||
// get value by its base, offset and size
|
||||
int64_t get_el_value(
|
||||
char *base,
|
||||
int64_t offset,
|
||||
int64_t size
|
||||
);
|
||||
#endif // OFFLOAD_UTIL_H_INCLUDED
|
||||
@@ -0,0 +1,164 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
#if HOST_LIBRARY
|
||||
#include "offload_host.h"
|
||||
#include "offload_myo_host.h"
|
||||
#else
|
||||
#include "compiler_if_target.h"
|
||||
#include "offload_target.h"
|
||||
#include "offload_myo_target.h"
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_WINNT
|
||||
#define ALLOCATE(name) __declspec(allocate(name))
|
||||
#define DLL_LOCAL
|
||||
#else // TARGET_WINNT
|
||||
#define ALLOCATE(name) __attribute__((section(name)))
|
||||
#define DLL_LOCAL __attribute__((visibility("hidden")))
|
||||
#endif // TARGET_WINNT
|
||||
|
||||
#if HOST_LIBRARY
|
||||
// the host program/shared library should always have __offload_target_image
|
||||
// symbol defined. This symbol specifies the beginning of the target program
|
||||
// image.
|
||||
extern "C" DLL_LOCAL const void* __offload_target_image;
|
||||
#else // HOST_LIBRARY
|
||||
// Define a weak main which would be used on target side in case usere's
|
||||
// source file containing main does not have offload code.
|
||||
#pragma weak main
|
||||
int main(void)
|
||||
{
|
||||
OFFLOAD_TARGET_MAIN();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#pragma weak MAIN__
|
||||
extern "C" int MAIN__(void)
|
||||
{
|
||||
OFFLOAD_TARGET_MAIN();
|
||||
return 0;
|
||||
}
|
||||
#endif // HOST_LIBRARY
|
||||
|
||||
// offload section prolog
|
||||
ALLOCATE(OFFLOAD_ENTRY_TABLE_SECTION_START)
|
||||
#ifdef TARGET_WINNT
|
||||
__declspec(align(sizeof(FuncTable::Entry)))
|
||||
#endif // TARGET_WINNT
|
||||
static FuncTable::Entry __offload_entry_table_start = { 0 };
|
||||
|
||||
// list element for the current module
|
||||
static FuncList::Node __offload_entry_node = {
|
||||
{ &__offload_entry_table_start + 1, -1 },
|
||||
0, 0
|
||||
};
|
||||
|
||||
// offload fp section prolog
|
||||
ALLOCATE(OFFLOAD_FUNC_TABLE_SECTION_START)
|
||||
#ifdef TARGET_WINNT
|
||||
__declspec(align(sizeof(FuncTable::Entry)))
|
||||
#endif // TARGET_WINNT
|
||||
static FuncTable::Entry __offload_func_table_start = { 0 };
|
||||
|
||||
// list element for the current module
|
||||
static FuncList::Node __offload_func_node = {
|
||||
{ &__offload_func_table_start + 1, -1 },
|
||||
0, 0
|
||||
};
|
||||
|
||||
// offload fp section prolog
|
||||
ALLOCATE(OFFLOAD_VAR_TABLE_SECTION_START)
|
||||
#ifdef TARGET_WINNT
|
||||
__declspec(align(sizeof(VarTable::Entry)))
|
||||
#endif // TARGET_WINNT
|
||||
static VarTable::Entry __offload_var_table_start = { 0 };
|
||||
|
||||
// list element for the current module
|
||||
static VarList::Node __offload_var_node = {
|
||||
{ &__offload_var_table_start + 1 },
|
||||
0, 0
|
||||
};
|
||||
|
||||
#ifdef MYO_SUPPORT
|
||||
|
||||
// offload myo shared var section prolog
|
||||
ALLOCATE(OFFLOAD_MYO_SHARED_TABLE_SECTION_START)
|
||||
#ifdef TARGET_WINNT
|
||||
__declspec(align(sizeof(SharedTableEntry)))
|
||||
#endif // TARGET_WINNT
|
||||
static SharedTableEntry __offload_myo_shared_table_start = { 0 };
|
||||
|
||||
#if HOST_LIBRARY
|
||||
// offload myo shared var init section prolog
|
||||
ALLOCATE(OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_START)
|
||||
#ifdef TARGET_WINNT
|
||||
__declspec(align(sizeof(InitTableEntry)))
|
||||
#endif // TARGET_WINNT
|
||||
static InitTableEntry __offload_myo_shared_init_table_start = { 0 };
|
||||
#endif
|
||||
|
||||
// offload myo fptr section prolog
|
||||
ALLOCATE(OFFLOAD_MYO_FPTR_TABLE_SECTION_START)
|
||||
#ifdef TARGET_WINNT
|
||||
__declspec(align(sizeof(FptrTableEntry)))
|
||||
#endif // TARGET_WINNT
|
||||
static FptrTableEntry __offload_myo_fptr_table_start = { 0 };
|
||||
|
||||
#endif // MYO_SUPPORT
|
||||
|
||||
// init/fini code which adds/removes local lookup data to/from the global list
|
||||
|
||||
static void offload_fini();
|
||||
|
||||
#ifndef TARGET_WINNT
|
||||
static void offload_init() __attribute__((constructor(101)));
|
||||
#else // TARGET_WINNT
|
||||
static void offload_init();
|
||||
|
||||
// Place offload initialization before user constructors
|
||||
ALLOCATE(OFFLOAD_CRTINIT_SECTION_START)
|
||||
static void (*addressof_offload_init)() = offload_init;
|
||||
#endif // TARGET_WINNT
|
||||
|
||||
static void offload_init()
|
||||
{
|
||||
// register offload tables
|
||||
__offload_register_tables(&__offload_entry_node,
|
||||
&__offload_func_node,
|
||||
&__offload_var_node);
|
||||
|
||||
#if HOST_LIBRARY
|
||||
__offload_register_image(&__offload_target_image);
|
||||
atexit(offload_fini);
|
||||
#endif // HOST_LIBRARY
|
||||
|
||||
#ifdef MYO_SUPPORT
|
||||
__offload_myoRegisterTables(
|
||||
#if HOST_LIBRARY
|
||||
&__offload_myo_shared_init_table_start + 1,
|
||||
#endif // HOST_LIBRARY
|
||||
&__offload_myo_shared_table_start + 1,
|
||||
&__offload_myo_fptr_table_start + 1
|
||||
);
|
||||
#endif // MYO_SUPPORT
|
||||
}
|
||||
|
||||
static void offload_fini()
|
||||
{
|
||||
#if HOST_LIBRARY
|
||||
__offload_unregister_image(&__offload_target_image);
|
||||
#endif // HOST_LIBRARY
|
||||
|
||||
// unregister offload tables
|
||||
__offload_unregister_tables(&__offload_entry_node,
|
||||
&__offload_func_node,
|
||||
&__offload_var_node);
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
#if HOST_LIBRARY
|
||||
#include "offload_host.h"
|
||||
#include "offload_myo_host.h"
|
||||
#else
|
||||
#include "offload_target.h"
|
||||
#include "offload_myo_target.h"
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_WINNT
|
||||
#define ALLOCATE(name) __declspec(allocate(name))
|
||||
#else // TARGET_WINNT
|
||||
#define ALLOCATE(name) __attribute__((section(name)))
|
||||
#endif // TARGET_WINNT
|
||||
|
||||
// offload entry table
|
||||
ALLOCATE(OFFLOAD_ENTRY_TABLE_SECTION_END)
|
||||
#ifdef TARGET_WINNT
|
||||
__declspec(align(sizeof(FuncTable::Entry)))
|
||||
#endif // TARGET_WINNT
|
||||
static FuncTable::Entry __offload_entry_table_end = { (const char*)-1 };
|
||||
|
||||
// offload function table
|
||||
ALLOCATE(OFFLOAD_FUNC_TABLE_SECTION_END)
|
||||
#ifdef TARGET_WINNT
|
||||
__declspec(align(sizeof(FuncTable::Entry)))
|
||||
#endif // TARGET_WINNT
|
||||
static FuncTable::Entry __offload_func_table_end = { (const char*)-1 };
|
||||
|
||||
// data table
|
||||
ALLOCATE(OFFLOAD_VAR_TABLE_SECTION_END)
|
||||
#ifdef TARGET_WINNT
|
||||
__declspec(align(sizeof(VarTable::Entry)))
|
||||
#endif // TARGET_WINNT
|
||||
static VarTable::Entry __offload_var_table_end = { (const char*)-1 };
|
||||
|
||||
#ifdef MYO_SUPPORT
|
||||
|
||||
// offload myo shared var section epilog
|
||||
ALLOCATE(OFFLOAD_MYO_SHARED_TABLE_SECTION_END)
|
||||
#ifdef TARGET_WINNT
|
||||
__declspec(align(sizeof(SharedTableEntry)))
|
||||
static SharedTableEntry __offload_myo_shared_table_end = { (const char*)-1, 0 };
|
||||
#else // TARGET_WINNT
|
||||
static SharedTableEntry __offload_myo_shared_table_end = { 0 };
|
||||
#endif // TARGET_WINNT
|
||||
|
||||
#if HOST_LIBRARY
|
||||
// offload myo shared var init section epilog
|
||||
ALLOCATE(OFFLOAD_MYO_SHARED_INIT_TABLE_SECTION_END)
|
||||
#ifdef TARGET_WINNT
|
||||
__declspec(align(sizeof(InitTableEntry)))
|
||||
static InitTableEntry __offload_myo_shared_init_table_end = { (const char*)-1, 0 };
|
||||
#else // TARGET_WINNT
|
||||
static InitTableEntry __offload_myo_shared_init_table_end = { 0 };
|
||||
#endif // TARGET_WINNT
|
||||
#endif // HOST_LIBRARY
|
||||
|
||||
// offload myo fptr section epilog
|
||||
ALLOCATE(OFFLOAD_MYO_FPTR_TABLE_SECTION_END)
|
||||
#ifdef TARGET_WINNT
|
||||
__declspec(align(sizeof(FptrTableEntry)))
|
||||
static FptrTableEntry __offload_myo_fptr_table_end = { (const char*)-1, 0, 0 };
|
||||
#else // TARGET_WINNT
|
||||
static FptrTableEntry __offload_myo_fptr_table_end = { 0 };
|
||||
#endif // TARGET_WINNT
|
||||
|
||||
#endif // MYO_SUPPORT
|
||||
@@ -0,0 +1,221 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 _ORSL_LITE_H_
|
||||
#define _ORSL_LITE_H_
|
||||
|
||||
#ifndef TARGET_WINNT
|
||||
#include <sched.h>
|
||||
#else
|
||||
#define cpu_set_t int
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Type of a ORSLBusySet */
|
||||
typedef enum ORSLBusySetType {
|
||||
BUSY_SET_EMPTY = 0, /**< Empty set */
|
||||
BUSY_SET_PARTIAL = 1, /**< Non-empty set that omits some threads */
|
||||
BUSY_SET_FULL = 2 /**< A set that includes all threads on the card */
|
||||
} BusySetType;
|
||||
|
||||
/** ORSLBusySet encapsulation */
|
||||
typedef struct ORSLBusySet {
|
||||
BusySetType type; /**< Set type */
|
||||
#ifdef __linux__
|
||||
cpu_set_t cpu_set; /**< CPU mask (unused for BUSY_SET_EMPTY and
|
||||
BUSY_SET_PARTIAL sets) represented by the standard
|
||||
Linux CPU set type -- cpu_set_t. Threads are numbered
|
||||
starting from 0. The maximal possible thread number
|
||||
is system-specific. See CPU_SET(3) family of macros
|
||||
for more details. Unused in ORSL Lite. */
|
||||
#endif
|
||||
} ORSLBusySet;
|
||||
|
||||
/** Client tag */
|
||||
typedef char* ORSLTag;
|
||||
|
||||
/** Maximal length of tag in characters */
|
||||
#define ORSL_MAX_TAG_LEN 128
|
||||
|
||||
/** Maximal number of cards that can be managed by ORSL */
|
||||
#define ORSL_MAX_CARDS 32
|
||||
|
||||
/** Reserves computational resources on a set of cards. Blocks.
|
||||
*
|
||||
* If any of the resources cannot be reserved, this function will block until
|
||||
* they become available. Reservation can be recursive if performed by the
|
||||
* same tag. A recursively reserved resource must be released the same number
|
||||
* of times it was reserved.
|
||||
*
|
||||
* @see ORSLTryReserve
|
||||
*
|
||||
* @param[in] n Number of cards to reserve resources on. Cannot be < 0
|
||||
* or > ORSL_MAX_CARDS.
|
||||
*
|
||||
* @param[in] inds Indices of the cards: an integer array with n elements.
|
||||
* Cannot be NULL if n > 0. Valid card indices are from 0
|
||||
* to ORSL_MAX_CARDS-1. Cannot contain duplicate elements.
|
||||
*
|
||||
* @param[in] bsets Requested resources on each of the card. Cannot be NULL
|
||||
* if n > 0.
|
||||
*
|
||||
* @param[in] tag ORSLTag of the calling client. Cannot be NULL. Length
|
||||
* must not exeed ORSL_MAX_TAG_LEN.
|
||||
*
|
||||
* @returns 0 if the resources were successfully reserved
|
||||
*
|
||||
* @returns EINVAL if any of the arguments is invalid
|
||||
*
|
||||
* @returns EAGAIN limit of recursive reservations reached
|
||||
* (not in ORSL Lite)
|
||||
*
|
||||
* @returns ENOSYS (in ORSL Lite) if type of any of the busy sets is
|
||||
* equal to BUSY_SET_PARTIAL
|
||||
*/
|
||||
int ORSLReserve(const int n, const int *__restrict inds,
|
||||
const ORSLBusySet *__restrict bsets,
|
||||
const ORSLTag __restrict tag);
|
||||
|
||||
/** Reserves computational resources on a set of cards. Does not block.
|
||||
*
|
||||
* If any of the resources cannot be reserved, this function will return
|
||||
* immediately. Reservation can be recursive if performed by the same tag.
|
||||
* A recursively reserved resource must be released the same number of times
|
||||
* it was reserved.
|
||||
*
|
||||
* @see ORSLReserve
|
||||
*
|
||||
* @param[in] n Number of cards to reserve resources on. Cannot be < 0
|
||||
* or > ORSL_MAX_CARDS.
|
||||
*
|
||||
* @param[in] inds Indices of the cards: an integer array with n elements.
|
||||
* Cannot be NULL if n > 0. Valid card indices are from 0
|
||||
* to ORSL_MAX_CARDS-1. Cannot contain duplicate elements.
|
||||
*
|
||||
* @param[inout] bsets Requested resources on each of the card. Cannot be
|
||||
* NULL if n > 0.
|
||||
*
|
||||
* @param[in] tag ORSLTag of the calling client. Cannot be NULL. Length
|
||||
* must not exceed ORSL_MAX_TAG_LEN.
|
||||
*
|
||||
* @returns 0 if the resources were successfully reserved
|
||||
*
|
||||
* @returns EBUSY if some of the requested resources are busy
|
||||
*
|
||||
* @returns EINVAL if any of the arguments is invalid
|
||||
*
|
||||
* @returns EAGAIN limit of recursive reservations reached
|
||||
* (not in ORSL Lite)
|
||||
*
|
||||
* @returns ENOSYS (in ORSL Lite) if type of any of the busy sets is
|
||||
* equal to BUSY_SET_PARTIAL
|
||||
*/
|
||||
int ORSLTryReserve(const int n, const int *__restrict inds,
|
||||
const ORSLBusySet *__restrict bsets,
|
||||
const ORSLTag __restrict tag);
|
||||
|
||||
/** Granularify of partial reservation */
|
||||
typedef enum ORSLPartialGranularity {
|
||||
GRAN_CARD = 0, /**< Card granularity */
|
||||
GRAN_THREAD = 1 /**< Thread granularity */
|
||||
} ORSLPartialGranularity;
|
||||
|
||||
/** Requests reservation of some of computational resources on a set of cards.
|
||||
* Does not block. Updates user-provided bsets to indicate which resources
|
||||
* were reserved.
|
||||
*
|
||||
* If any of the resources cannot be reserved, this function will update busy
|
||||
* sets provided by the caller to reflect what resources were actually
|
||||
* reserved. This function supports two granularity modes: 'card' and
|
||||
* 'thread'. When granularity is set to 'card', a failure to reserve a thread
|
||||
* on the card will imply that reservation has failed for the whole card. When
|
||||
* granularity is set to 'thread', reservation on a card will be considered
|
||||
* successful as long as at least one thread on the card was successfully
|
||||
* reserved. Reservation can be recursive if performed by the same tag. A
|
||||
* recursively reserved resource must be released the same number of times it
|
||||
* was reserved.
|
||||
*
|
||||
* @param[in] gran Reservation granularity
|
||||
*
|
||||
* @param[in] n Number of cards to reserve resources on. Cannot be < 0
|
||||
* or > ORSL_MAX_CARDS.
|
||||
*
|
||||
* @param[in] inds Indices of the cards: an integer array with n elements.
|
||||
* Cannot be NULL if n > 0. Valid card indices are from 0
|
||||
* to ORSL_MAX_CARDS-1. Cannot contain duplicate elements.
|
||||
*
|
||||
* @param[in] bsets Requested resources on each of the card. Cannot be NULL
|
||||
* if n > 0.
|
||||
*
|
||||
* @param[in] tag ORSLTag of the calling client. Cannot be NULL. Length
|
||||
* must not exceed ORSL_MAX_TAG_LEN.
|
||||
*
|
||||
* @returns 0 if at least some of the resources were successfully
|
||||
* reserved
|
||||
*
|
||||
* @returns EBUSY if all of the requested resources are busy
|
||||
*
|
||||
* @returns EINVAL if any of the arguments is invalid
|
||||
*
|
||||
* @returns EAGAIN limit of recursive reservations reached
|
||||
* (not in ORSL Lite)
|
||||
*
|
||||
* @returns ENOSYS (in ORSL Lite) if type of any of the busy sets is
|
||||
* equal to BUSY_SET_PARTIAL
|
||||
*/
|
||||
int ORSLReservePartial(const ORSLPartialGranularity gran, const int n,
|
||||
const int *__restrict inds,
|
||||
ORSLBusySet *__restrict bsets,
|
||||
const ORSLTag __restrict tag);
|
||||
|
||||
/** Releases previously reserved computational resources on a set of cards.
|
||||
*
|
||||
* This function will fail if any of the resources to be released were not
|
||||
* reserved by the calling client.
|
||||
*
|
||||
* @see ORSLReserve
|
||||
* @see ORSLTryReserve
|
||||
* @see ORSLReservePartial
|
||||
*
|
||||
* @param[in] n Number of cards to reserve resources on. Cannot be < 0
|
||||
* or > ORSL_MAX_CARDS.
|
||||
*
|
||||
* @param[in] inds Indices of the cards: an integer array with n elements.
|
||||
* Cannot be NULL if n > 0. Valid card indices are from 0
|
||||
* to ORSL_MAX_CARDS-1. Cannot contain duplicate elements.
|
||||
*
|
||||
* @param[in] bsets Requested resources on each of the card. Cannot be NULL
|
||||
* if n > 0.
|
||||
*
|
||||
* @param[in] tag ORSLTag of the calling client. Cannot be NULL. Length
|
||||
* must not exceed ORSL_MAX_TAG_LEN.
|
||||
*
|
||||
* @returns 0 if the resources were successfully released
|
||||
*
|
||||
* @returns EINVAL if any of the arguments is invalid
|
||||
*
|
||||
* @returns EPERM the calling client did not reserve some of the
|
||||
* resources it is trying to release.
|
||||
*
|
||||
* @returns ENOSYS (in ORSL Lite) if type of any of the busy sets is
|
||||
* equal to BUSY_SET_PARTIAL
|
||||
*/
|
||||
int ORSLRelease(const int n, const int *__restrict inds,
|
||||
const ORSLBusySet *__restrict bsets,
|
||||
const ORSLTag __restrict tag);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,337 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 <errno.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "orsl-lite/include/orsl-lite.h"
|
||||
|
||||
#define DISABLE_SYMBOL_VERSIONING
|
||||
|
||||
#if defined(__linux__) && !defined(DISABLE_SYMBOL_VERSIONING)
|
||||
#define symver(src, tgt, verstr) __asm__(".symver " #src "," #tgt verstr)
|
||||
symver(ORSLReserve0, ORSLReserve, "@@ORSL_0.0");
|
||||
symver(ORSLTryReserve0, ORSLTryReserve, "@@ORSL_0.0");
|
||||
symver(ORSLReservePartial0, ORSLReservePartial, "@@ORSL_0.0");
|
||||
symver(ORSLRelease0, ORSLRelease, "@@ORSL_0.0");
|
||||
#else
|
||||
#define ORSLReserve0 ORSLReserve
|
||||
#define ORSLTryReserve0 ORSLTryReserve
|
||||
#define ORSLReservePartial0 ORSLReservePartial
|
||||
#define ORSLRelease0 ORSLRelease
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
#include <pthread.h>
|
||||
static pthread_mutex_t global_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_cond_t release_cond = PTHREAD_COND_INITIALIZER;
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#pragma intrinsic(_ReadWriteBarrier)
|
||||
static SRWLOCK global_mutex = SRWLOCK_INIT;
|
||||
static volatile int release_cond_initialized = 0;
|
||||
static CONDITION_VARIABLE release_cond;
|
||||
|
||||
static void state_lazy_init_sync()
|
||||
{
|
||||
if (!release_cond_initialized) {
|
||||
AcquireSRWLockExclusive(&global_mutex);
|
||||
_ReadWriteBarrier();
|
||||
if (!release_cond_initialized) {
|
||||
InitializeConditionVariable(&release_cond);
|
||||
release_cond_initialized = 1;
|
||||
}
|
||||
ReleaseSRWLockExclusive(&global_mutex);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int state_lock()
|
||||
{
|
||||
#ifdef __linux__
|
||||
return pthread_mutex_lock(&global_mutex);
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
AcquireSRWLockExclusive(&global_mutex);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int state_unlock()
|
||||
{
|
||||
#ifdef __linux__
|
||||
return pthread_mutex_unlock(&global_mutex);
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
ReleaseSRWLockExclusive(&global_mutex);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int state_wait_for_release()
|
||||
{
|
||||
#ifdef __linux__
|
||||
return pthread_cond_wait(&release_cond, &global_mutex);
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
return SleepConditionVariableSRW(&release_cond,
|
||||
&global_mutex, INFINITE, 0) == 0 ? 1 : 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int state_signal_release()
|
||||
{
|
||||
#ifdef __linux__
|
||||
return pthread_cond_signal(&release_cond);
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
WakeConditionVariable(&release_cond);
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static struct {
|
||||
char owner[ORSL_MAX_TAG_LEN + 1];
|
||||
unsigned long rsrv_cnt;
|
||||
} rsrv_data[ORSL_MAX_CARDS];
|
||||
|
||||
static int check_args(const int n, const int *__restrict inds,
|
||||
const ORSLBusySet *__restrict bsets,
|
||||
const ORSLTag __restrict tag)
|
||||
{
|
||||
int i;
|
||||
int card_specified[ORSL_MAX_CARDS];
|
||||
if (tag == NULL) return -1;
|
||||
if (strlen((char *)tag) > ORSL_MAX_TAG_LEN) return -1;
|
||||
if (n < 0 || n >= ORSL_MAX_CARDS) return -1;
|
||||
if (n != 0 && (inds == NULL || bsets == NULL)) return -1;
|
||||
for (i = 0; i < ORSL_MAX_CARDS; i++)
|
||||
card_specified[i] = 0;
|
||||
for (i = 0; i < n; i++) {
|
||||
int ind = inds[i];
|
||||
if (ind < 0 || ind >= ORSL_MAX_CARDS) return -1;
|
||||
if (card_specified[ind]) return -1;
|
||||
card_specified[ind] = 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int check_bsets(const int n, const ORSLBusySet *bsets)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < n; i++)
|
||||
if (bsets[i].type == BUSY_SET_PARTIAL) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int can_reserve_card(int card, const ORSLBusySet *__restrict bset,
|
||||
const ORSLTag __restrict tag)
|
||||
{
|
||||
assert(tag != NULL);
|
||||
assert(bset != NULL);
|
||||
assert(strlen((char *)tag) < ORSL_MAX_TAG_LEN);
|
||||
assert(bset->type != BUSY_SET_PARTIAL);
|
||||
|
||||
return (bset->type == BUSY_SET_EMPTY ||
|
||||
((rsrv_data[card].rsrv_cnt == 0 ||
|
||||
strncmp((char *)tag,
|
||||
rsrv_data[card].owner, ORSL_MAX_TAG_LEN) == 0) &&
|
||||
rsrv_data[card].rsrv_cnt < ULONG_MAX)) ? 0 : - 1;
|
||||
}
|
||||
|
||||
static void reserve_card(int card, const ORSLBusySet *__restrict bset,
|
||||
const ORSLTag __restrict tag)
|
||||
{
|
||||
assert(tag != NULL);
|
||||
assert(bset != NULL);
|
||||
assert(strlen((char *)tag) < ORSL_MAX_TAG_LEN);
|
||||
assert(bset->type != BUSY_SET_PARTIAL);
|
||||
|
||||
if (bset->type == BUSY_SET_EMPTY)
|
||||
return;
|
||||
|
||||
assert(rsrv_data[card].rsrv_cnt == 0 ||
|
||||
strncmp((char *)tag,
|
||||
rsrv_data[card].owner, ORSL_MAX_TAG_LEN) == 0);
|
||||
assert(rsrv_data[card].rsrv_cnt < ULONG_MAX);
|
||||
|
||||
if (rsrv_data[card].rsrv_cnt == 0)
|
||||
strncpy(rsrv_data[card].owner, (char *)tag, ORSL_MAX_TAG_LEN);
|
||||
rsrv_data[card].owner[ORSL_MAX_TAG_LEN] = '\0';
|
||||
rsrv_data[card].rsrv_cnt++;
|
||||
}
|
||||
|
||||
static int can_release_card(int card, const ORSLBusySet *__restrict bset,
|
||||
const ORSLTag __restrict tag)
|
||||
{
|
||||
assert(tag != NULL);
|
||||
assert(bset != NULL);
|
||||
assert(strlen((char *)tag) < ORSL_MAX_TAG_LEN);
|
||||
assert(bset->type != BUSY_SET_PARTIAL);
|
||||
|
||||
return (bset->type == BUSY_SET_EMPTY || (rsrv_data[card].rsrv_cnt > 0 &&
|
||||
strncmp((char *)tag,
|
||||
rsrv_data[card].owner, ORSL_MAX_TAG_LEN) == 0)) ? 0 : 1;
|
||||
}
|
||||
|
||||
static void release_card(int card, const ORSLBusySet *__restrict bset,
|
||||
const ORSLTag __restrict tag)
|
||||
{
|
||||
assert(tag != NULL);
|
||||
assert(bset != NULL);
|
||||
assert(strlen((char *)tag) < ORSL_MAX_TAG_LEN);
|
||||
assert(bset->type != BUSY_SET_PARTIAL);
|
||||
|
||||
if (bset->type == BUSY_SET_EMPTY)
|
||||
return;
|
||||
|
||||
assert(strncmp((char *)tag,
|
||||
rsrv_data[card].owner, ORSL_MAX_TAG_LEN) == 0);
|
||||
assert(rsrv_data[card].rsrv_cnt > 0);
|
||||
|
||||
rsrv_data[card].rsrv_cnt--;
|
||||
}
|
||||
|
||||
int ORSLReserve0(const int n, const int *__restrict inds,
|
||||
const ORSLBusySet *__restrict bsets,
|
||||
const ORSLTag __restrict tag)
|
||||
{
|
||||
int i, ok;
|
||||
|
||||
if (n == 0) return 0;
|
||||
if (check_args(n, inds, bsets, tag) != 0) return EINVAL;
|
||||
if (check_bsets(n, bsets) != 0) return ENOSYS;
|
||||
|
||||
state_lock();
|
||||
|
||||
/* Loop until we find that all the resources we want are available */
|
||||
do {
|
||||
ok = 1;
|
||||
for (i = 0; i < n; i++)
|
||||
if (can_reserve_card(inds[i], &bsets[i], tag) != 0) {
|
||||
ok = 0;
|
||||
/* Wait for someone to release some resources */
|
||||
state_wait_for_release();
|
||||
break;
|
||||
}
|
||||
} while (!ok);
|
||||
|
||||
/* At this point we are good to reserve_card the resources we want */
|
||||
for (i = 0; i < n; i++)
|
||||
reserve_card(inds[i], &bsets[i], tag);
|
||||
|
||||
state_unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ORSLTryReserve0(const int n, const int *__restrict inds,
|
||||
const ORSLBusySet *__restrict bsets,
|
||||
const ORSLTag __restrict tag)
|
||||
{
|
||||
int i, rc = EBUSY;
|
||||
|
||||
if (n == 0) return 0;
|
||||
if (check_args(n, inds, bsets, tag) != 0) return EINVAL;
|
||||
if (check_bsets(n, bsets) != 0) return ENOSYS;
|
||||
|
||||
state_lock();
|
||||
|
||||
/* Check resource availability once */
|
||||
for (i = 0; i < n; i++)
|
||||
if (can_reserve_card(inds[i], &bsets[i], tag) != 0)
|
||||
goto bail_out;
|
||||
|
||||
/* At this point we are good to reserve the resources we want */
|
||||
for (i = 0; i < n; i++)
|
||||
reserve_card(inds[i], &bsets[i], tag);
|
||||
|
||||
rc = 0;
|
||||
|
||||
bail_out:
|
||||
state_unlock();
|
||||
return rc;
|
||||
}
|
||||
|
||||
int ORSLReservePartial0(const ORSLPartialGranularity gran, const int n,
|
||||
const int *__restrict inds, ORSLBusySet *__restrict bsets,
|
||||
const ORSLTag __restrict tag)
|
||||
{
|
||||
int rc = EBUSY;
|
||||
int i, num_avail = n;
|
||||
|
||||
if (n == 0) return 0;
|
||||
if (gran != GRAN_CARD && gran != GRAN_THREAD) return EINVAL;
|
||||
if (gran != GRAN_CARD) return EINVAL;
|
||||
if (check_args(n, inds, bsets, tag) != 0) return EINVAL;
|
||||
if (check_bsets(n, bsets) != 0) return ENOSYS;
|
||||
|
||||
state_lock();
|
||||
|
||||
/* Check resource availability once; remove unavailable resources from the
|
||||
* user-provided list */
|
||||
for (i = 0; i < n; i++)
|
||||
if (can_reserve_card(inds[i], &bsets[i], tag) != 0) {
|
||||
num_avail--;
|
||||
bsets[i].type = BUSY_SET_EMPTY;
|
||||
}
|
||||
|
||||
if (num_avail == 0)
|
||||
goto bail_out;
|
||||
|
||||
/* At this point we are good to reserve the resources we want */
|
||||
for (i = 0; i < n; i++)
|
||||
reserve_card(inds[i], &bsets[i], tag);
|
||||
|
||||
rc = 0;
|
||||
|
||||
bail_out:
|
||||
state_unlock();
|
||||
return rc;
|
||||
}
|
||||
|
||||
int ORSLRelease0(const int n, const int *__restrict inds,
|
||||
const ORSLBusySet *__restrict bsets,
|
||||
const ORSLTag __restrict tag)
|
||||
{
|
||||
int i, rc = EPERM;
|
||||
|
||||
if (n == 0) return 0;
|
||||
if (check_args(n, inds, bsets, tag) != 0) return EINVAL;
|
||||
if (check_bsets(n, bsets) != 0) return ENOSYS;
|
||||
|
||||
state_lock();
|
||||
|
||||
/* Check that we can release all the resources */
|
||||
for (i = 0; i < n; i++)
|
||||
if (can_release_card(inds[i], &bsets[i], tag) != 0)
|
||||
goto bail_out;
|
||||
|
||||
/* At this point we are good to release the resources we want */
|
||||
for (i = 0; i < n; i++)
|
||||
release_card(inds[i], &bsets[i], tag);
|
||||
|
||||
state_signal_release();
|
||||
|
||||
rc = 0;
|
||||
|
||||
bail_out:
|
||||
state_unlock();
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* vim:set et: */
|
||||
@@ -0,0 +1 @@
|
||||
ORSL-lite 0.7
|
||||
@@ -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 <stdint.h>
|
||||
|
||||
uint64_t _rdtsc()
|
||||
{
|
||||
uint32_t eax, edx;
|
||||
asm volatile ("rdtsc" : "=a" (eax), "=d" (edx));
|
||||
return ((uint64_t)edx << 32) | eax;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
2.1.6720-13
|
||||
@@ -0,0 +1 @@
|
||||
2.1.6720-13
|
||||
@@ -0,0 +1,225 @@
|
||||
#
|
||||
#//===----------------------------------------------------------------------===//
|
||||
#//
|
||||
#// 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.
|
||||
#//
|
||||
#//===----------------------------------------------------------------------===//
|
||||
#
|
||||
|
||||
Building libiomp5 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++ -Darch=32 .. # Initial configuration
|
||||
$ make all common
|
||||
...
|
||||
$ make clean
|
||||
$ cmake -Darch=32e -DCMAKE_BUILD_TYPE=Debug .. # Second configuration
|
||||
$ make all common
|
||||
...
|
||||
$ rm -rf *
|
||||
$ cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -Darch=32e .. # Third configuration
|
||||
$ make all common
|
||||
- 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 libomp_top_level/ [ directory with src/ , exports/ , tools/ , etc. ]
|
||||
$ mkdir build
|
||||
$ cd build
|
||||
|
||||
[ Linux* , Mac* Libraries ]
|
||||
$ cmake -DCMAKE_C_COMPILER=<C Compiler> -DCMAKE_CXX_COMPILER=<C++ Compiler> ..
|
||||
|
||||
[ Intel(R) Many Integrated Core Library (Intel(R) MIC Library) ]
|
||||
$ cmake -DCMAKE_C_COMPILER=<C Compiler> -DCMAKE_CXX_COMPILER=<C++ Compiler> -Dos=mic -Darch=32e ..
|
||||
|
||||
[ Windows Libraries ]
|
||||
$ cmake -G "Unix Makefiles" -DCMAKE_C_COMPILER=<C Compiler> -DCMAKE_CXX_COMPILER=<C++ Compiler> -DCMAKE_ASM_MASM_COMPILER=[ml | ml64] -DCMAKE_BUILD_TYPE=Release ..
|
||||
|
||||
$ make all common
|
||||
|
||||
=================
|
||||
Mac* Fat Libraries
|
||||
=================
|
||||
On OS X* machines, it is possible to build universal (or fat) libraries which
|
||||
include both IA-32 architecture and Intel(R) 64 architecture objects in a
|
||||
single archive; just build the 32 and 32e libraries separately:
|
||||
$ cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -Darch=32 ..
|
||||
$ make
|
||||
$ cmake -Darch=32e ..
|
||||
$ make
|
||||
then invoke make again with a special argument as follows:
|
||||
$ make fat
|
||||
- The fat target is only available for the arch=32e configuration.
|
||||
- The fat libraries will be put in exports/mac_32e/lib while the "thin" libraries
|
||||
will be in exports/mac_32e/lib.thin and exports/mac_32/lib.thin
|
||||
|
||||
================
|
||||
Compiler options
|
||||
================
|
||||
-DCMAKE_C_COMPILER=<C compiler name>
|
||||
-DCMAKE_CXX_COMPILER=<C++ compiler name>
|
||||
|
||||
-DCMAKE_Fortran_COMPILER=<Fortran compiler name>
|
||||
Unix* systems (Optional as compiler is default):
|
||||
This option is only needed when -Dcreate_fortran_modules is true
|
||||
|
||||
-DCMAKE_ASM_COMPILER=<Assembler name>
|
||||
This option isn't usually needed for Non-Windows* builds
|
||||
|
||||
-DCMAKE_ASM_MASM_COMPILER=[ml | ml64 ]
|
||||
This option is Windows* Only
|
||||
|
||||
=============
|
||||
Build options
|
||||
=============
|
||||
|
||||
==========================
|
||||
==== Operating System ====
|
||||
==========================
|
||||
-Dos=lin|mac|win|mic
|
||||
* Operating system can be lin (Linux*), mac (Mac*), win (Windows*), or
|
||||
mic (Intel(R) Many Integrated Core Architecture (Intel(R) MIC Architecture)).
|
||||
If not specified, cmake will try to determine your current operating system.
|
||||
|
||||
======================
|
||||
==== Architecture ====
|
||||
======================
|
||||
-Darch=32|32e|arm|ppc64
|
||||
* Architecture can be 32 (IA-32 architecture), 32e (Intel(R) 64 architecture),
|
||||
arm (ARM architecture), or ppc64 (PPC64 architecture).
|
||||
This option, by default is chosen based on the
|
||||
CMake variable CMAKE_SIZEOF_VOID_P. If it is 8, then Intel(R) 64 architecture
|
||||
is assumed. If it is 4, then IA-32 architecture is assumed. If you want to
|
||||
use a different architecture other than x86 based architecture, you must specify
|
||||
it when calling cmake initially using this -Darch=<arch> option or by changing
|
||||
the arch value via CMakeCache.txt or the CMake GUI after the initial CMake run.
|
||||
|
||||
---- First values listed are the default value ----
|
||||
-Dlib_type=normal|profile|stubs
|
||||
Library type can be normal, profile, or stubs.
|
||||
|
||||
-DCMAKE_BUILD_TYPE=Release|Debug|RelWithDebInfo
|
||||
Build type can be Release, Debug, or RelWithDebInfo.
|
||||
See below for interaction when -DUSE_BUILDPL_RULES is on.
|
||||
|
||||
-Dversion=5|4
|
||||
libiomp5 version can be 5 or 4.
|
||||
|
||||
-Domp_version=40|30
|
||||
OpenMP version can be either 40 or 30.
|
||||
|
||||
-Dmic_arch=knc|knf
|
||||
Intel(R) MIC Architecture. Can be
|
||||
knf (Knights Ferry) or knc (Knights Corner).
|
||||
This value is ignored if os != mic
|
||||
|
||||
-Dmic_os=lin|bsd
|
||||
Operating system on Intel(R) MIC Architecture.
|
||||
Can be either bsd or lin. This value is ignored if os != mic
|
||||
|
||||
-Dcreate_fortran_modules=off|on
|
||||
Should the Fortran modules be created (requires Fortran compiler)
|
||||
|
||||
-Dstats=off|on
|
||||
Should include stats-gathering code?
|
||||
|
||||
=====================
|
||||
==== Micro tests ====
|
||||
=====================
|
||||
After the library has been built, five microtests are performed.
|
||||
Some will be skipped based upon the platform.
|
||||
These tests can be turned on (default) or off with the following options:
|
||||
-Dtest_touch=on|off -- Should the touch test be done?
|
||||
-Dtest_relo=on|off -- Should the position independent code test be done?
|
||||
-Dtest_execstack=on|off -- Should the stack be checked for executability?
|
||||
-Dtest_instr=on|off -- Should the Intel(R) MIC Libraries be checked
|
||||
for correct instruction set?
|
||||
-Dtest_deps=on|off -- Should libiomp5's dependencies be checked?
|
||||
-Dtests=off|on -- Should any of the above tests be done?
|
||||
|
||||
============================================
|
||||
==== How to append flags to compilation ====
|
||||
============================================
|
||||
- These flags are *appended*. They do not
|
||||
overwrite any of the preset flags.
|
||||
-DUSER_CPP_FLAGS=<space-separated flags> -- Additional C Preprocessor flags
|
||||
(typically additional -Ddef=val flags)
|
||||
-DUSER_C_FLAGS=<space-separated flags> -- Additional C compiler flags
|
||||
-DUSER_CXX_FLAGS=<space-separated flags> -- Additional C++ compiler flags
|
||||
-DUSER_ASM_FLAGS=<space-separated flags> -- Additional assembly flags
|
||||
-DUSER_LD_FLAGS=<space-separated flags> -- Additional linker flags
|
||||
-DUSER_LD_LIB_FLAGS=<space-separated flags> -- Additional libraries to link
|
||||
to during link phase
|
||||
-DUSER_F_FLAGS=<space-separated flags> -- Additional Fortran compiler flags
|
||||
|
||||
===================================
|
||||
==== Feature Based Compilation ====
|
||||
===================================
|
||||
-DUSE_BUILDPL_RULES=false|true
|
||||
Should the build imitate build.pl's build process.
|
||||
When this is true, the Unix* Release builds will build libiomp5
|
||||
with -O2 and -g flags activated (same as RelWithDebInfo). Then,
|
||||
the debug info is stripped out of the library and put into libiomp5.dbg
|
||||
This is done for interaction with Intel(R) Parallel Amplifier.
|
||||
|
||||
-DUSE_ADAPTIVE_LOCKS=true|false
|
||||
Should adaptive (TSX-based) locks be included?
|
||||
These are x86 specific. This feature is turned on by default
|
||||
for IA-32 architecture and Intel(R) 64 architecture.
|
||||
Otherwise, it is turned off.
|
||||
|
||||
-DUSE_PREDEFINED_LINKER_FLAGS=true|false
|
||||
Should the predefined linker flags in CommonFlags.cmake be included
|
||||
in the link command? This is true by default and should work for
|
||||
Linux*, Mac*, and Windows*. The --version-script flag on Unix* based
|
||||
operating systems will be included regardless.
|
||||
|
||||
========================
|
||||
Examples usages of CMake
|
||||
========================
|
||||
---- Typical usage ----
|
||||
cmake -DCMAKE_C_COMPILER=icc -DCMAKE_CXX_COMPILER=icpc ..
|
||||
cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ ..
|
||||
cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ ..
|
||||
|
||||
---- With Various Options ----
|
||||
cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -Dos=lin -Darch=32 ..
|
||||
cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -Dos=mac -Darch=32 -DCMAKE_BUILD_TYPE=Debug ..
|
||||
cmake -DCMAKE_C_COMPILER=icc -DCMAKE_CXX_COMPILER=icpc -DCMAKE_Fortran_COMPILER=ifort -Dtests=on -Dcreate_fortran_modules=on -DUSE_BUILDPL_RULES=on ..
|
||||
cmake -DUSER_CFLAGS='Werror' -DUSER_CPP_FLAGS='-DNEW_FEATURE=1 -DOLD_FEATURE=0' -DUSER_CXX_FLAGS='-Werror -Wsign-compare' ..
|
||||
|
||||
---- Stubs library ----
|
||||
cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -Dlib_type=stubs ..
|
||||
|
||||
=========
|
||||
Footnotes
|
||||
=========
|
||||
[*] Other names and brands may be claimed as the property of others.
|
||||
@@ -0,0 +1,833 @@
|
||||
#
|
||||
#//===----------------------------------------------------------------------===//
|
||||
#//
|
||||
#// 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.
|
||||
#//
|
||||
#//===----------------------------------------------------------------------===//
|
||||
#
|
||||
|
||||
################
|
||||
# CMAKE libiomp5
|
||||
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
|
||||
project(libiomp C CXX)
|
||||
|
||||
#########
|
||||
# GLOBALS
|
||||
set(GLOBAL_DEBUG 0)
|
||||
|
||||
# Add cmake directory to search for custom cmake functions
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH})
|
||||
|
||||
# Set base libomp directory (directory with exports/ , src/ , tools/ , etc.)
|
||||
# The top-level CMakeLists.txt should define this variable.
|
||||
set(LIBOMP_WORK ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
# These include files are in cmake/ subdirectory except for FindPerl which is a cmake standard module
|
||||
include(HelperFunctions)
|
||||
include(Definitions) # -D definitions when compiling
|
||||
include(CommonFlags) # compiler, assembler, fortran, linker flags common for all compilers
|
||||
include(SourceFiles) # source files to compile
|
||||
include(PerlFlags) # Perl flags for generate-def.pl and expand-vars.pl
|
||||
include(FindPerl) # Standard cmake module to check for Perl
|
||||
|
||||
####################################################################
|
||||
# CONFIGURATION
|
||||
#
|
||||
# * Any variable/value that is CACHE-ed can be changed after the initial run of cmake
|
||||
# through the file, CMakeCache.txt which is in the build directory.
|
||||
# * If you change any value in CMakeCache.txt, then just run cmake ..
|
||||
# and the changed will be picked up. One can also use -DVARIABLE=VALUE
|
||||
# when calling cmake to changed configuration values.
|
||||
# * CMAKE_C_COMPILER, CMAKE_CXX_COMPILER, CMAKE_ASM_MASM_COMPILER, CMAKE_ASM_COMPILER,
|
||||
# CMAKE_Fortran_COMPILER can only by specified on the initial run of cmake.
|
||||
# This means you cannot specify -DCMAKE_C_COMPILER= on a subsequent run of cmake
|
||||
# in the same build directory until that build directory is emptied.
|
||||
# If you want to change the compiler, then empty the build directory and rerun cmake.
|
||||
|
||||
# Build Configuration
|
||||
set(os_possible_values lin mac win mic)
|
||||
set(arch_possible_values 32e 32 arm ppc64)
|
||||
set(build_type_possible_values release debug relwithdebinfo)
|
||||
set(omp_version_possible_values 40 30)
|
||||
set(lib_type_possible_values normal profile stubs)
|
||||
set(mic_arch_possible_values knf knc)
|
||||
set(mic_os_possible_values bsd lin)
|
||||
|
||||
# Below, cmake will try and determine the operating system and architecture for you (it assumes Intel architecture)
|
||||
# These values are set in CMakeCache.txt when cmake is first run (-Dvar_name=... will take precedence)
|
||||
# parameter | default value
|
||||
# ----------------------------
|
||||
# Right now, this build system considers os=lin to mean "Unix-like that is not MAC"
|
||||
if(${APPLE}) # Apple goes first because CMake considers Mac to be a Unix based operating system, while libiomp5 considers it a special case
|
||||
set(os mac CACHE STRING "The operating system to build for (lin/mac/win/mic)")
|
||||
elseif(${UNIX})
|
||||
set(os lin CACHE STRING "The operating system to build for (lin/mac/win/mic)")
|
||||
elseif(${WIN32})
|
||||
set(os win CACHE STRING "The operating system to build for (lin/mac/win/mic)")
|
||||
else()
|
||||
set(os lin CACHE STRING "The operating system to build for (lin/mac/win/mic)")
|
||||
endif()
|
||||
|
||||
# set to default architecture if the user did not specify an architecture explicitly
|
||||
if(NOT arch)
|
||||
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "4")
|
||||
set(arch 32 CACHE STRING "The architecture to build for (32e/32/arm/ppc64). 32e is Intel(R) 64 architecture, 32 is IA-32 architecture")
|
||||
else()
|
||||
set(arch 32e CACHE STRING "The architecture to build for (32e/32/arm/ppc64). 32e is Intel(R) 64 architecture, 32 is IA-32 architecture")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(lib_type normal CACHE STRING "Performance,Profiling,Stubs library (normal/profile/stubs)")
|
||||
set(version 5 CACHE STRING "Produce libguide (version 4) or libiomp5 (version 5)")
|
||||
set(omp_version 40 CACHE STRING "The OpenMP version (40/30)")
|
||||
set(mic_arch knc CACHE STRING "Intel(R) Many Integrated Core Architecture (Intel(R) MIC Architecture) (knf/knc). Ignored if not Intel(R) MIC Architecture build.")
|
||||
set(mic_os lin CACHE STRING "Intel(R) MIC Architecture operating system (bsd/lin). Ignored if not Intel(R) MIC Architecture build.")
|
||||
set(create_fortran_modules false CACHE STRING "Create Fortran module files? (requires fortran compiler)")
|
||||
|
||||
# - These tests are little tests performed after the library is formed.
|
||||
# - The library won't be copied to the exports directory until it has passed/skipped all below tests
|
||||
# - To skip these tests, just pass -Dtests=OFF to cmake or change tests value in CMakeCache.txt to OFF after running cmake
|
||||
set(test_touch true CACHE BOOL "Perform a small touch test?" )
|
||||
set(test_relo true CACHE BOOL "Perform a relocation test for dynamic libraries?" )
|
||||
set(test_execstack true CACHE BOOL "Perform a execstack test for linux dynamic libraries?" )
|
||||
set(test_instr true CACHE BOOL "Perform an instruction test for Intel(R) MIC Architecture libraries?" )
|
||||
set(test_deps true CACHE BOOL "Perform a library dependency test?" )
|
||||
set(tests false CACHE BOOL "Perform touch, relo, execstack, instr, and deps tests?" )
|
||||
|
||||
# - stats-gathering enables OpenMP stats where things like the number of parallel regions, clock ticks spent in
|
||||
# particular openmp regions are recorded.
|
||||
set(stats false CACHE BOOL "Stats-Gathering functionality?" )
|
||||
|
||||
# User specified flags. These are appended to the predetermined flags found in CommonFlags.cmake and ${CMAKE_C_COMPILER_ID}/*Flags.cmake (i.e., GNU/CFlags.cmake)
|
||||
set(USER_C_FLAGS "" CACHE STRING "Appended user specified C compiler flags." )
|
||||
set(USER_CXX_FLAGS "" CACHE STRING "Appended user specified C++ compiler flags." )
|
||||
set(USER_CPP_FLAGS "" CACHE STRING "Appended user specified C preprocessor flags." )
|
||||
set(USER_ASM_FLAGS "" CACHE STRING "Appended user specified assembler flags." )
|
||||
set(USER_LD_FLAGS "" CACHE STRING "Appended user specified linker flags." )
|
||||
set(USER_LD_LIB_FLAGS "" CACHE STRING "Appended user specified linked libs flags. (i.e., -lm)")
|
||||
set(USER_F_FLAGS "" CACHE STRING "Appended user specified Fortran compiler flags. These are only used if create_fortran_modules==true." )
|
||||
|
||||
# - Allow three build types: Release, Debug, RelWithDebInfo (these relate to build.pl's release, debug, and diag settings respectively)
|
||||
# - default is Release (when CMAKE_BUILD_TYPE is not defined)
|
||||
# - CMAKE_BUILD_TYPE affects the -O and -g flags (CMake magically includes correct version of them on per compiler basis)
|
||||
# - typical: Release = -O3 -DNDEBUG
|
||||
# RelWithDebInfo = -O2 -g -DNDEBUG
|
||||
# Debug = -g
|
||||
if(CMAKE_BUILD_TYPE)
|
||||
# CMAKE_BUILD_TYPE was defined, check for validity
|
||||
string(TOLOWER "${CMAKE_BUILD_TYPE}" cmake_build_type_lowercase)
|
||||
check_variable(cmake_build_type_lowercase "${build_type_possible_values}")
|
||||
else()
|
||||
# CMAKE_BUILD_TYPE was not defined, set default to Release
|
||||
unset(CMAKE_BUILD_TYPE CACHE)
|
||||
set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build, options are: Release/Debug/RelWithDebInfo")
|
||||
string(TOLOWER "${CMAKE_BUILD_TYPE}" cmake_build_type_lowercase)
|
||||
check_variable(cmake_build_type_lowercase "${build_type_possible_values}")
|
||||
endif()
|
||||
|
||||
# Check valid values
|
||||
check_variable(os "${os_possible_values}" )
|
||||
check_variable(arch "${arch_possible_values}" )
|
||||
check_variable(omp_version "${omp_version_possible_values}")
|
||||
check_variable(lib_type "${lib_type_possible_values}" )
|
||||
if("${os}" STREQUAL "mic")
|
||||
check_variable(mic_arch "${mic_arch_possible_values}" )
|
||||
check_variable(mic_os "${mic_os_possible_values}" )
|
||||
endif()
|
||||
# Get the build number from kmp_version.c
|
||||
get_build_number("${LIBOMP_WORK}" build_number)
|
||||
|
||||
# Getting time and date
|
||||
# As of now, no timestamp will be created.
|
||||
set(date "No Timestamp")
|
||||
|
||||
#################################################################
|
||||
# Set some useful flags variables for other parts of cmake to use
|
||||
# Operating System
|
||||
set(LINUX FALSE)
|
||||
set(MAC FALSE)
|
||||
set(WINDOWS FALSE)
|
||||
set(MIC FALSE)
|
||||
set(FREEBSD FALSE)
|
||||
if("${os}" STREQUAL "lin")
|
||||
set(LINUX TRUE)
|
||||
set(real_os lin)
|
||||
elseif("${os}" STREQUAL "mac")
|
||||
set(MAC TRUE)
|
||||
set(real_os mac)
|
||||
elseif("${os}" STREQUAL "win")
|
||||
set(WINDOWS TRUE)
|
||||
set(real_os win)
|
||||
elseif("${os}" STREQUAL "mic")
|
||||
set(MIC TRUE)
|
||||
set(real_os lrb)
|
||||
endif()
|
||||
if("${CMAKE_SYSTEM_NAME}" STREQUAL "FreeBSD")
|
||||
set(FREEBSD TRUE)
|
||||
endif()
|
||||
|
||||
# Architecture
|
||||
set(IA32 FALSE)
|
||||
set(INTEL64 FALSE)
|
||||
set(ARM FALSE)
|
||||
set(PPC64 FALSE)
|
||||
if("${arch}" STREQUAL "32") # IA-32 architecture
|
||||
set(IA32 TRUE)
|
||||
elseif("${arch}" STREQUAL "32e") # Intel(R) 64 architecture
|
||||
set(INTEL64 TRUE)
|
||||
elseif("${arch}" STREQUAL "arm") # ARM architecture
|
||||
set(ARM TRUE)
|
||||
elseif("${arch}" STREQUAL "ppc64") # PPC64 architecture
|
||||
set(PPC64 TRUE)
|
||||
endif()
|
||||
|
||||
# Set some flags based on build_type
|
||||
# cmake_build_type_lowercase is based off of CMAKE_BUILD_TYPE, just put in lowercase.
|
||||
set(RELEASE_BUILD FALSE)
|
||||
set(DEBUG_BUILD FALSE)
|
||||
set(RELWITHDEBINFO_BUILD FALSE)
|
||||
if("${cmake_build_type_lowercase}" STREQUAL "release")
|
||||
set(RELEASE_BUILD TRUE)
|
||||
elseif("${cmake_build_type_lowercase}" STREQUAL "debug")
|
||||
set(DEBUG_BUILD TRUE)
|
||||
elseif("${cmake_build_type_lowercase}" STREQUAL "relwithdebinfo")
|
||||
set(RELWITHDEBINFO_BUILD TRUE)
|
||||
endif()
|
||||
|
||||
# Stats-gathering on or off?
|
||||
set(STATS_GATHERING FALSE)
|
||||
if("${stats}") # string "on" or "ON" is seen as boolean TRUE
|
||||
set(STATS_GATHERING TRUE)
|
||||
endif()
|
||||
|
||||
# Include itt notify interface? Right now, always.
|
||||
set(USE_ITT_NOTIFY TRUE)
|
||||
|
||||
# normal, profile, stubs library.
|
||||
set(NORMAL_LIBRARY FALSE)
|
||||
set(STUBS_LIBRARY FALSE)
|
||||
set(PROFILE_LIBRARY FALSE)
|
||||
if("${lib_type}" STREQUAL "normal")
|
||||
set(NORMAL_LIBRARY TRUE)
|
||||
elseif("${lib_type}" STREQUAL "profile")
|
||||
set(PROFILE_LIBRARY TRUE)
|
||||
elseif("${lib_type}" STREQUAL "stubs")
|
||||
set(STUBS_LIBRARY TRUE)
|
||||
endif()
|
||||
|
||||
###############################################
|
||||
# Features for compilation and build in general
|
||||
|
||||
# - Does the compiler support a 128-bit floating point data type? Default is false
|
||||
# - If a compiler does, then change it in the CMakeCache.txt file (or using the cmake GUI)
|
||||
# or send to cmake -DCOMPILER_SUPPORTS_QUAD_PRECISION=true
|
||||
# - If COMPILER_SUPPORTS_QUAD_PRECISION is true, then a corresponding COMPILER_QUAD_TYPE must be given
|
||||
# This is the compiler's quad-precision data type.
|
||||
# ** TODO: This isn't complete yet. Finish it. Requires changing macros in kmp_os.h **
|
||||
set(COMPILER_SUPPORTS_QUAD_PRECISION false CACHE BOOL "*INCOMPLETE* Does the compiler support a 128-bit floating point type?")
|
||||
set(COMPILER_QUAD_TYPE "" CACHE STRING "*INCOMPLETE* The quad precision data type (i.e., for gcc, __float128)")
|
||||
|
||||
# - Should the orignal build rules for builds be used? (cmake/OriginalBuildRules.cmake). This setting is off by default.
|
||||
# - This always compiles with -g. And if it is a release build, the debug info is stripped out via objcopy and put into libiomp5.dbg.
|
||||
set(USE_BUILDPL_RULES false CACHE BOOL "Should the build follow build.pl rules/recipes?")
|
||||
|
||||
# - Should the build use the predefined linker flags (OS-dependent) in CommonFlags.cmake?
|
||||
# - these predefined linker flags should work for Windows, Mac, and True Linux for the most popular compilers/linkers
|
||||
set(USE_PREDEFINED_LINKER_FLAGS true CACHE BOOL "Should the build use the predefined linker flags in CommonFlags.cmake?")
|
||||
|
||||
# - TSX based locks have __asm code which can be troublesome for some compilers. This feature is also x86 specific.
|
||||
if({${IA32} OR ${INTEL64})
|
||||
set(USE_ADAPTIVE_LOCKS true CACHE BOOL "Should TSX-based lock be compiled (adaptive lock in kmp_lock.cpp). These are x86 specific.")
|
||||
else()
|
||||
set(USE_ADAPTIVE_LOCKS false CACHE BOOL "Should TSX-based lock be compiled (adaptive lock in kmp_lock.cpp). These are x86 specific.")
|
||||
endif()
|
||||
|
||||
##################################
|
||||
# Error checking the configuration
|
||||
if(${STATS_GATHERING} AND (${WINDOWS} OR ${MAC}))
|
||||
error_say("Stats-gathering functionality is only supported on x86-Linux and Intel(R) MIC Architecture")
|
||||
endif()
|
||||
if(${STATS_GATHERING} AND NOT (${IA32} OR ${INTEL64}))
|
||||
error_say("Stats-gathering functionality is only supported on x86-Linux and Intel(R) MIC Architecture")
|
||||
endif()
|
||||
if(${USE_ADAPTIVE_LOCKS} AND NOT(${IA32} OR ${INTEL64}))
|
||||
error_say("Adaptive locks (TSX) functionality is only supported on x86 Architecture")
|
||||
endif()
|
||||
|
||||
###############################################
|
||||
# - Create the suffix for the export directory
|
||||
# - Only add to suffix when not a default value
|
||||
# - Example suffix: .deb.30.s1
|
||||
# final export directory: exports/lin_32e.deb.30.s1/lib
|
||||
# - These suffixes imply the build is a Debug, OpenMP 3.0, Stats-Gathering version of the library
|
||||
if(NOT "${cmake_build_type_lowercase}" STREQUAL "release")
|
||||
string(SUBSTRING "${cmake_build_type_lowercase}" 0 3 build_type_suffix)
|
||||
set(suffix "${suffix}.${build_type_suffix}")
|
||||
endif()
|
||||
if(NOT "${omp_version}" STREQUAL "40")
|
||||
set(suffix "${suffix}.${omp_version}")
|
||||
endif()
|
||||
if(${STATS_GATHERING})
|
||||
set(suffix "${suffix}.s1")
|
||||
endif()
|
||||
if(${MIC})
|
||||
if(NOT "${mic_arch}" STREQUAL "knf")
|
||||
set(suffix "${suffix}.${mic_arch}")
|
||||
endif()
|
||||
if(NOT "${mic_os}" STREQUAL "bsd")
|
||||
set(suffix "${suffix}.${mic_os}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
####################################
|
||||
# Setting file extensions / suffixes
|
||||
set(obj ${CMAKE_C_OUTPUT_EXTENSION} )
|
||||
set(lib ${CMAKE_STATIC_LIBRARY_SUFFIX})
|
||||
set(dll ${CMAKE_SHARED_LIBRARY_SUFFIX})
|
||||
set(exe ${CMAKE_EXECUTABLE_SUFFIX} )
|
||||
|
||||
######################
|
||||
# Find perl executable
|
||||
# Perl is used to create omp.h (and other headers) along with kmp_i18n_id.inc and kmp_i18n_default.inc (see below in Rules section)
|
||||
if(NOT "${PERL_FOUND}") # variable is defined in FindPerl Standard CMake Module
|
||||
error_say("Error: Could not find valid perl")
|
||||
endif()
|
||||
|
||||
#########################
|
||||
# Setting directory names
|
||||
set(platform "${real_os}_${arch}" ) # i.e., lin_32e, mac_32
|
||||
set(build_dir "${CMAKE_CURRENT_BINARY_DIR}" ) # build directory (Where CMakeCache.txt is created, build files generated)
|
||||
set(src_dir "${LIBOMP_WORK}/src" )
|
||||
set(tools_dir "${LIBOMP_WORK}/tools" )
|
||||
set(export_dir "${LIBOMP_WORK}/exports" )
|
||||
set(export_cmn_dir "${export_dir}/common${suffix}" )
|
||||
set(export_ptf_dir "${export_dir}/${platform}${suffix}")
|
||||
_export_lib_dir(${platform} export_lib_dir) # set exports directory (relative to build_dir) i.e., ../exports/lin_32e/lib/
|
||||
# or i.e., ../exports/mac_32e/lib.thin/ for mac
|
||||
if(${MAC})
|
||||
# macs use lib.thin/ subdirectory for non-fat libraries that only contain one architecture
|
||||
# macs use lib/ subdirectory for fat libraries that contain both IA-32 architecture and Intel(R) 64 architecture code.
|
||||
_export_lib_fat_dir(${platform} export_lib_fat_dir)
|
||||
endif()
|
||||
set(inc_dir "${LIBOMP_WORK}/src/include/${omp_version}")
|
||||
|
||||
############################
|
||||
# Setting final library name
|
||||
set(lib_item "libiomp")
|
||||
if(${PROFILE_LIBRARY})
|
||||
set(lib_item "${lib_item}prof")
|
||||
endif()
|
||||
if(${STUBS_LIBRARY})
|
||||
set(lib_item "${lib_item}stubs")
|
||||
endif()
|
||||
set(lib_item "${lib_item}${version}")
|
||||
if(${WINDOWS})
|
||||
set(lib_item "${lib_item}md")
|
||||
endif()
|
||||
set(lib_ext "${dll}")
|
||||
# ${lib_file} is real library name:
|
||||
# libiomp5.so for Linux
|
||||
# libiomp5.dylib for Mac
|
||||
# libiomp5md.dll for Windows
|
||||
set(lib_file "${lib_item}${lib_ext}")
|
||||
|
||||
########################################
|
||||
# Setting export file names (full paths)
|
||||
if(${WINDOWS})
|
||||
set(imp_file "${lib_item}${lib}") # this is exported (libiomp5md.lib)
|
||||
set(def_file "${lib_item}.def") # this is not exported
|
||||
set(rc_file "${lib_item}.rc") # this is not exported
|
||||
if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug" OR "${CMAKE_BUILD_TYPE}" STREQUAL "RelWithDebInfo" OR ${USE_BUILDPL_RULES})
|
||||
set(pdb_file "${lib_file}.pdb") # this is exported if it exists (libiomp5md.dll.pdb)
|
||||
endif()
|
||||
endif()
|
||||
set(export_lib_files "${lib_file}" "${imp_file}" "${pdb_file}")
|
||||
set(export_inc_files "iomp_lib.h")
|
||||
set(export_mod_files "omp_lib.mod" "omp_lib_kinds.mod")
|
||||
set(export_cmn_files1 "omp.h" "omp_lib.h" "omp_lib.f" "omp_lib.f90")
|
||||
set(export_cmn_files2 "iomp.h")
|
||||
add_prefix("${export_lib_dir}/" export_lib_files)
|
||||
add_prefix("${export_ptf_dir}/include_compat/" export_inc_files)
|
||||
add_prefix("${export_ptf_dir}/include/" export_mod_files)
|
||||
add_prefix("${export_cmn_dir}/include/" export_cmn_files1)
|
||||
add_prefix("${export_cmn_dir}/include_compat/" export_cmn_files2)
|
||||
set(export_cmn_files "${export_cmn_files1}" "${export_cmn_files2}")
|
||||
if("${export_lib_fat_dir}")
|
||||
set(export_lib_fat_files "${lib_file}" "${imp_file}")
|
||||
add_prefix("${export_lib_fat_dir}/" export_lib_fat_files)
|
||||
endif()
|
||||
|
||||
#########################
|
||||
# Getting legal type/arch
|
||||
set_legal_type(legal_type)
|
||||
set_legal_arch(legal_arch)
|
||||
|
||||
#################################################
|
||||
# Preprocessor Definitions (cmake/Definitions.cmake)
|
||||
# Preprocessor Includes
|
||||
# Compiler (C/C++) Flags (cmake/CommonFlags.cmake)
|
||||
# Assembler Flags (cmake/CommonFlags.cmake)
|
||||
# Fortran Flags (cmake/CommonFlags.cmake)
|
||||
# Linker Flags (cmake/CommonFlags.cmake)
|
||||
# Archiver Flags (cmake/CommonFlags.cmake)
|
||||
# Helper Perl Script Flags (cmake/PerlFlags.cmake)
|
||||
# * Inside the cmake/CommonFlags.cmake file, the USER_*_FLAGS are added.
|
||||
# * Cannot use CMAKE_*_FLAGS directly because -x c++ is put in the linker command and mangles the linking phase.
|
||||
|
||||
# preprocessor flags (-D definitions and -I includes)
|
||||
# Grab environment variable CPPFLAGS and append those to definitions
|
||||
set(include_dirs ${CMAKE_CURRENT_BINARY_DIR} ${src_dir} ${src_dir}/i18n ${inc_dir} ${src_dir}/thirdparty/ittnotify)
|
||||
include_directories(${include_dirs})
|
||||
|
||||
# Grab assembler-dependent flags
|
||||
# CMake will look for cmake/${CMAKE_ASM_COMPILER_ID}/AsmFlags.cmake to append additional assembler flags.
|
||||
if(${WINDOWS})
|
||||
# Windows based systems use CMAKE_ASM_MASM_COMPILER
|
||||
# The windows assembly files are in MASM format, and they require a tool that can handle MASM syntax (ml.exe or ml64.exe typically)
|
||||
enable_language(ASM_MASM)
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${CMAKE_ASM_MASM_COMPILER_ID} ${CMAKE_MODULE_PATH})
|
||||
find_file(assembler_specific_include_file_found AsmFlags.cmake ${CMAKE_MODULE_PATH})
|
||||
if(assembler_specific_include_file_found)
|
||||
include(AsmFlags)
|
||||
append_assembler_specific_asm_flags(ASM_FLAGS)
|
||||
else()
|
||||
warning_say("Could not find cmake/${CMAKE_ASM_MASM_COMPILER_ID}/AsmFlags.cmake: will only use default flags")
|
||||
endif()
|
||||
else()
|
||||
# Unix (including Mac) based systems use CMAKE_ASM_COMPILER
|
||||
# Unix assembly files can be handled by compiler usually.
|
||||
enable_language(ASM)
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${CMAKE_ASM_COMPILER_ID} ${CMAKE_MODULE_PATH})
|
||||
find_file(assembler_specific_include_file_found AsmFlags.cmake ${CMAKE_MODULE_PATH})
|
||||
if(assembler_specific_include_file_found)
|
||||
include(AsmFlags)
|
||||
append_assembler_specific_asm_flags(ASM_FLAGS)
|
||||
else()
|
||||
warning_say("Could not find cmake/${CMAKE_ASM_COMPILER_ID}/AsmFlags.cmake: will only use default flags")
|
||||
endif()
|
||||
endif()
|
||||
# Grab compiler-dependent flags
|
||||
# Cmake will look for cmake/${CMAKE_C_COMPILER_ID}/CFlags.cmake to append additional c, cxx, and linker flags.
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${CMAKE_C_COMPILER_ID} ${CMAKE_MODULE_PATH})
|
||||
find_file(compiler_specific_include_file_found CFlags.cmake ${CMAKE_MODULE_PATH})
|
||||
if(compiler_specific_include_file_found)
|
||||
include(CFlags) # COMPILER_SUPPORTS_QUAD_PRECISION changed in here
|
||||
append_compiler_specific_c_and_cxx_flags(C_FLAGS CXX_FLAGS)
|
||||
append_compiler_specific_linker_flags(LD_FLAGS LD_LIB_FLAGS)
|
||||
else()
|
||||
warning_say("Could not find cmake/${CMAKE_C_COMPILER_ID}/CFlags.cmake: will only use default flags")
|
||||
endif()
|
||||
|
||||
# Grab all the compiler-independent flags
|
||||
append_c_and_cxx_flags_common(C_FLAGS CXX_FLAGS)
|
||||
append_asm_flags_common(ASM_FLAGS)
|
||||
append_fort_flags_common(F_FLAGS)
|
||||
append_linker_flags_common(LD_FLAGS LD_LIB_FLAGS)
|
||||
append_archiver_flags_common(AR_FLAGS)
|
||||
append_cpp_flags(DEFINITIONS_FLAGS)
|
||||
|
||||
# Setup the flags correctly for cmake (covert to string)
|
||||
# Pretty them up (STRIP any beginning and trailing whitespace)
|
||||
list_to_string("${DEFINITIONS_FLAGS}" DEFINITIONS_FLAGS)
|
||||
list_to_string("${C_FLAGS}" C_FLAGS )
|
||||
list_to_string("${CXX_FLAGS}" CXX_FLAGS )
|
||||
list_to_string("${ASM_FLAGS}" ASM_FLAGS )
|
||||
list_to_string("${LD_FLAGS}" LD_FLAGS )
|
||||
list_to_string("${LD_LIB_FLAGS}" LD_LIB_FLAGS )
|
||||
list_to_string("${AR_FLAGS}" AR_FLAGS ) # Windows specific for creating import library
|
||||
string(STRIP "${DEFINITIONS_FLAGS}" DEFINITIONS_FLAGS)
|
||||
string(STRIP "${C_FLAGS}" C_FLAGS )
|
||||
string(STRIP "${CXX_FLAGS}" CXX_FLAGS )
|
||||
string(STRIP "${ASM_FLAGS}" ASM_FLAGS )
|
||||
string(STRIP "${LD_FLAGS}" LD_FLAGS )
|
||||
string(STRIP "${LD_LIB_FLAGS}" LD_LIB_FLAGS )
|
||||
string(STRIP "${AR_FLAGS}" AR_FLAGS ) # Windows specific for creating import library
|
||||
|
||||
# Grab the Perl flags
|
||||
set_ev_flags(ev_flags) # expand-vars.pl flags
|
||||
set_gd_flags(gd_flags) # generate-def.pl flags (Windows only)
|
||||
set(oa_opts "--os=${real_os}" "--arch=${arch}") # sent to the perl scripts
|
||||
|
||||
#########################################################
|
||||
# Getting correct source files (cmake/SourceFiles.cmake)
|
||||
set_c_files(lib_c_items)
|
||||
set_cpp_files(lib_cxx_items)
|
||||
set_asm_files(lib_asm_items)
|
||||
set_imp_c_files(imp_c_items) # Windows-specific
|
||||
|
||||
###################################
|
||||
# Setting all source file variables
|
||||
set(lib_src_files "${lib_c_items}" "${lib_cxx_items}" "${lib_asm_items}")
|
||||
set(imp_src_files "${imp_c_items}")
|
||||
add_prefix("${src_dir}/" lib_src_files)
|
||||
add_prefix("${src_dir}/" imp_src_files) # Windows-specific
|
||||
add_prefix("${src_dir}/" lib_c_items )
|
||||
add_prefix("${src_dir}/" lib_cxx_items)
|
||||
add_prefix("${src_dir}/" lib_asm_items)
|
||||
add_prefix("${src_dir}/" imp_c_items ) # Windows-specific
|
||||
|
||||
#####################################################################
|
||||
# Debug print outs. Will print "variable = ${variable}" if GLOBAL_DEBUG == 1
|
||||
if(GLOBAL_DEBUG)
|
||||
include(CMakePrintSystemInformation)
|
||||
endif()
|
||||
debug_say_var(CMAKE_ASM_COMPILE_OBJECT)
|
||||
debug_say_var(CMAKE_RC_COMPILER)
|
||||
debug_say_var(CMAKE_C_COMPILER_ID)
|
||||
debug_say_var(LIBOMP_WORK)
|
||||
debug_say_var(date)
|
||||
debug_say_var(stats)
|
||||
debug_say_var(lib_file)
|
||||
debug_say_var(export_lib_files)
|
||||
debug_say_var(DEFINITIONS_FLAGS)
|
||||
debug_say_var(C_FLAGS)
|
||||
debug_say_var(CXX_FLAGS)
|
||||
debug_say_var(ASM_FLAGS)
|
||||
debug_say_var(F_FLAGS)
|
||||
debug_say_var(LD_FLAGS)
|
||||
debug_say_var(LD_LIB_FLAGS)
|
||||
debug_say_var(AR_FLAGS)
|
||||
debug_say_var(ev_flags)
|
||||
debug_say_var(gd_flags)
|
||||
debug_say_var(oa_opts)
|
||||
debug_say_var(lib_c_items)
|
||||
debug_say_var(lib_cxx_items)
|
||||
debug_say_var(lib_asm_items)
|
||||
debug_say_var(imp_c_items)
|
||||
debug_say_var(lib_src_files)
|
||||
debug_say_var(imp_src_files)
|
||||
|
||||
####################################################################
|
||||
# --------------------- #
|
||||
# --- Rules/Recipes --- #
|
||||
# --------------------- #
|
||||
####################################################################
|
||||
# Below, ${ldeps} always stands for "local dependencies" for the
|
||||
# next immediate target to be created via add_custom_target() or
|
||||
# add_custom_command()
|
||||
|
||||
####################
|
||||
# --- Create all ---
|
||||
add_custom_target(lib ALL DEPENDS ${export_lib_files})
|
||||
add_custom_target(inc ALL DEPENDS ${export_inc_files})
|
||||
if(${create_fortran_modules})
|
||||
add_custom_target(mod ALL DEPENDS ${export_mod_files})
|
||||
endif()
|
||||
# --- Enforce the tests to be completed/skipped before copying to exports directory ---
|
||||
if(${tests})
|
||||
if(${WINDOWS})
|
||||
set(test-dependencies test-touch-mt/.success test-touch-md/.success test-relo/.success test-execstack/.success test-instr/.success test-deps/.success)
|
||||
else()
|
||||
set(test-dependencies test-touch-rt/.success test-relo/.success test-execstack/.success test-instr/.success test-deps/.success)
|
||||
endif()
|
||||
set_source_files_properties(${export_lib_files} PROPERTIES OBJECT_DEPENDS "${test-dependencies}")
|
||||
endif()
|
||||
|
||||
#############################
|
||||
# --- Create Common Files ---
|
||||
add_custom_target(common DEPENDS ${export_cmn_files})
|
||||
add_custom_target(clean-common COMMAND ${CMAKE_COMMAND} -E remove -f ${export_cmn_files})
|
||||
|
||||
##########################################
|
||||
# --- Copy files to export directories ---
|
||||
# - just a simple copy recipe which acts as an install step
|
||||
# - copies out of the src_dir into the dest_dir
|
||||
#
|
||||
# dest_dir/target : src_dir/target
|
||||
# cp src_dir/target dest_dir/target
|
||||
macro (simple_copy_recipe target src_dir dest_dir)
|
||||
get_source_file_property(extra_depends ${dest_dir}/${target} OBJECT_DEPENDS)
|
||||
if("${extra_depends}" MATCHES "NOTFOUND")
|
||||
set(extra_depends)
|
||||
endif()
|
||||
set(ldeps ${src_dir}/${target} "${extra_depends}")
|
||||
if(NOT "${target}" STREQUAL "")
|
||||
file(MAKE_DIRECTORY ${dest_dir}) # make sure destination directory exists
|
||||
add_custom_command(
|
||||
OUTPUT ${dest_dir}/${target}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${src_dir}/${target} ${dest_dir}/${target}
|
||||
DEPENDS ${ldeps}
|
||||
)
|
||||
endif()
|
||||
endmacro()
|
||||
# copy from build directory to final resting places in exports directory
|
||||
simple_copy_recipe("omp.h" "${build_dir}" "${export_cmn_dir}/include")
|
||||
simple_copy_recipe("omp_lib.h" "${build_dir}" "${export_cmn_dir}/include")
|
||||
simple_copy_recipe("omp_lib.f" "${build_dir}" "${export_cmn_dir}/include")
|
||||
simple_copy_recipe("omp_lib.f90" "${build_dir}" "${export_cmn_dir}/include")
|
||||
simple_copy_recipe("iomp.h" "${build_dir}" "${export_cmn_dir}/include_compat")
|
||||
simple_copy_recipe("${lib_file}" "${build_dir}" "${export_lib_dir}")
|
||||
simple_copy_recipe("${imp_file}" "${build_dir}" "${export_lib_dir}")
|
||||
simple_copy_recipe("${pdb_file}" "${build_dir}" "${export_lib_dir}")
|
||||
simple_copy_recipe("${dbg_file}" "${build_dir}" "${export_lib_dir}")
|
||||
simple_copy_recipe("omp_lib.mod" "${build_dir}" "${export_ptf_dir}/include")
|
||||
simple_copy_recipe("omp_lib_kinds.mod" "${build_dir}" "${export_ptf_dir}/include")
|
||||
simple_copy_recipe("iomp_lib.h" "${build_dir}" "${export_ptf_dir}/include_compat")
|
||||
|
||||
######################################################
|
||||
# --- Build the main library ---
|
||||
# $(lib_file) <== Main library file to create
|
||||
|
||||
# objects depend on : .inc files and omp.h
|
||||
# This way the *.inc and omp.h are generated before any compilations take place
|
||||
add_custom_target(needed-headers DEPENDS ${build_dir}/kmp_i18n_id.inc ${build_dir}/kmp_i18n_default.inc ${build_dir}/omp.h)
|
||||
|
||||
# For Windows, there is a definitions file (.def) and resource file (.res) created using generate-def.pl and rc.exe respectively.
|
||||
if(${WINDOWS})
|
||||
add_custom_target(needed-windows-files DEPENDS ${build_dir}/${def_file} ${build_dir}/${rc_file})
|
||||
list(APPEND lib_src_files ${build_dir}/${rc_file})
|
||||
# The windows assembly files are in MASM format, and they require a tool that can handle MASM syntax (ml.exe or ml64.exe typically)
|
||||
enable_language(ASM_MASM)
|
||||
else()
|
||||
# Unix assembly files can be handled by compiler.
|
||||
enable_language(ASM)
|
||||
endif()
|
||||
|
||||
# Remove any cmake-automatic linking of libraries by linker, This is so linux
|
||||
# and mac don't include libstdc++ just because we compile c++ files.
|
||||
if(${USE_PREDEFINED_LINKER_FLAGS})
|
||||
set(CMAKE_C_IMPLICIT_LINK_LIBRARIES "")
|
||||
set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "")
|
||||
set(CMAKE_ASM_IMPLICIT_LINK_LIBRARIES "")
|
||||
endif()
|
||||
|
||||
# --- ${lib_file} rule ---
|
||||
add_library(iomp5 SHARED ${lib_src_files})
|
||||
set_target_properties(iomp5 PROPERTIES
|
||||
PREFIX "" SUFFIX "" # Take control
|
||||
OUTPUT_NAME "${lib_file}" # of output name
|
||||
LINK_FLAGS "${LD_FLAGS}"
|
||||
LINKER_LANGUAGE C # use C Compiler for linking step
|
||||
SKIP_BUILD_RPATH true # have Mac linker -install_name just be "-install_name libiomp5.dylib"
|
||||
)
|
||||
# Target lib (export files) depend on the library (iomp5) being built
|
||||
add_dependencies(lib iomp5)
|
||||
|
||||
# Linking command will include libraries in LD_LIB_FLAGS
|
||||
target_link_libraries(iomp5 ${LD_LIB_FLAGS})
|
||||
|
||||
# Create *.inc and omp.h before compiling any sources
|
||||
add_dependencies(iomp5 needed-headers)
|
||||
if(${WINDOWS})
|
||||
# Create .def and .rc file before compiling any sources
|
||||
add_dependencies(iomp5 needed-windows-files)
|
||||
endif()
|
||||
|
||||
# Set the compiler flags for each type of source
|
||||
set_source_files_properties(${lib_c_items}
|
||||
${imp_c_items} PROPERTIES COMPILE_FLAGS "${C_FLAGS}" )
|
||||
set_source_files_properties(${lib_cxx_items} PROPERTIES COMPILE_FLAGS "${CXX_FLAGS}")
|
||||
set_source_files_properties(${lib_asm_items} PROPERTIES COMPILE_FLAGS "${ASM_FLAGS}")
|
||||
# Set the -D definitions for all sources
|
||||
add_definitions(${DEFINITIONS_FLAGS})
|
||||
|
||||
# If creating a build that imitates build.pl's rules then set USE_BUILDPL_RULES to true
|
||||
if(${USE_BUILDPL_RULES})
|
||||
include(BuildPLRules)
|
||||
endif()
|
||||
|
||||
######################################################
|
||||
# --- Source file specific flags ---
|
||||
# kmp_version.o : -D _KMP_BUILD_TIME="\"$(date)}\""
|
||||
set_source_files_properties(${src_dir}/kmp_version.c PROPERTIES COMPILE_DEFINITIONS "_KMP_BUILD_TIME=\"\\\"${date}\\\"\"")
|
||||
|
||||
# z_Linux_asm.o : -D KMP_ARCH_*
|
||||
if(${ARM})
|
||||
set_source_files_properties(${src_dir}/z_Linux_asm.s PROPERTIES COMPILE_DEFINITIONS "KMP_ARCH_ARM")
|
||||
elseif(${INTEL64})
|
||||
set_source_files_properties(${src_dir}/z_Linux_asm.s PROPERTIES COMPILE_DEFINITIONS "KMP_ARCH_X86_64")
|
||||
elseif(${IA32})
|
||||
set_source_files_properties(${src_dir}/z_Linux_asm.s PROPERTIES COMPILE_DEFINITIONS "KMP_ARCH_X86")
|
||||
elseif(${PPC64})
|
||||
set_source_files_properties(${src_dir}/z_Linux_asm.s PROPERTIES COMPILE_DEFINITIONS "KMP_ARCH_PPC64")
|
||||
endif()
|
||||
|
||||
if(${WINDOWS})
|
||||
set_source_files_properties(${src_dir}/thirdparty/ittnotify/ittnotify_static.c PROPERTIES COMPILE_DEFINITIONS "UNICODE")
|
||||
endif()
|
||||
|
||||
######################################################
|
||||
# MAC specific build rules
|
||||
if(${MAC})
|
||||
# fat library rules
|
||||
if(${INTEL64})
|
||||
_export_lib_fat_dir( "mac_32e" export_fat_mac_32e)
|
||||
_export_lib_dir( "mac_32" export_mac_32 )
|
||||
_export_lib_dir( "mac_32e" export_mac_32e )
|
||||
file(MAKE_DIRECTORY ${export_fat_mac_32e})
|
||||
add_custom_target(fat
|
||||
COMMAND ${CMAKE_COMMAND} -E echo Building 32 and 32e fat libraries from ${export_mac_32}/${lib_file} and ${export_mac_32e}/${lib_file}
|
||||
COMMAND ${CMAKE_COMMAND} -E echo Will put fat library in ${export_fat_mac_32e} directory
|
||||
COMMAND lipo -create -output ${export_fat_mac_32e}/${lib_file} ${export_mac_32}/${lib_file} ${export_mac_32e}/${lib_file}
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
######################################################
|
||||
# Windows specific build rules
|
||||
if(${WINDOWS})
|
||||
|
||||
# --- Create $(imp_file) ---
|
||||
# This file is first created in the unstripped/${lib_file} creation step.
|
||||
# It is then "re-linked" to include kmp_import.c which prevents linking of both Visual Studio OpenMP and newly built OpenMP
|
||||
if(NOT "${imp_file}" STREQUAL "")
|
||||
set(generated_import_file ${lib_file}${lib})
|
||||
add_library(iomp5imp STATIC ${generated_import_file} ${imp_src_files})
|
||||
set_source_files_properties(${generated_import_file} PROPERTIES GENERATED TRUE EXTERNAL_OBJECT TRUE)
|
||||
set_target_properties(iomp5imp PROPERTIES
|
||||
PREFIX "" SUFFIX ""
|
||||
OUTPUT_NAME "${imp_file}"
|
||||
STATIC_LIBRARY_FLAGS "${AR_FLAGS}"
|
||||
LINKER_LANGUAGE C
|
||||
SKIP_BUILD_RPATH true
|
||||
)
|
||||
add_custom_command(TARGET iomp5imp PRE_BUILD COMMAND ${CMAKE_COMMAND} -E remove -f ${imp_file})
|
||||
add_dependencies(iomp5imp iomp5)
|
||||
endif()
|
||||
|
||||
# --- Create $(def_file) ---
|
||||
if(NOT "${def_file}" STREQUAL "")
|
||||
string_to_list("${gd_flags}" gd_flags)
|
||||
add_custom_command(
|
||||
OUTPUT ${def_file}
|
||||
COMMAND ${PERL_EXECUTABLE} ${tools_dir}/generate-def.pl ${gd_flags} -o ${def_file} ${src_dir}/dllexports
|
||||
DEPENDS ${src_dir}/dllexports ${tools_dir}/generate-def.pl
|
||||
)
|
||||
endif()
|
||||
|
||||
# --- Create $(rc_file) ---
|
||||
if(NOT "${rc_file}" STREQUAL "")
|
||||
add_custom_command(
|
||||
OUTPUT ${rc_file}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy libiomp.rc ${rc_file}
|
||||
DEPENDS libiomp.rc
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
######################################################
|
||||
# kmp_i18n_id.inc and kmp_i18n_default.inc
|
||||
set(perlcmd "${PERL_EXECUTABLE}" "${tools_dir}/message-converter.pl" "${oa_opts}" "--prefix=kmp_i18n" "--enum=kmp_i18n_id.inc" "${src_dir}/i18n/en_US.txt")
|
||||
add_custom_command(
|
||||
OUTPUT ${build_dir}/kmp_i18n_id.inc
|
||||
COMMAND ${perlcmd}
|
||||
DEPENDS ${src_dir}/i18n/en_US.txt ${tools_dir}/message-converter.pl
|
||||
)
|
||||
set(perlcmd "${PERL_EXECUTABLE}" "${tools_dir}/message-converter.pl" "${oa_opts}" "--prefix=kmp_i18n" "--default=kmp_i18n_default.inc" "${src_dir}/i18n/en_US.txt")
|
||||
add_custom_command(
|
||||
OUTPUT ${build_dir}/kmp_i18n_default.inc
|
||||
COMMAND ${perlcmd}
|
||||
DEPENDS ${src_dir}/i18n/en_US.txt ${tools_dir}/message-converter.pl
|
||||
)
|
||||
|
||||
######################################################
|
||||
# Micro test rules for after library has been built (cmake/MicroTests.cmake)
|
||||
# - Only perform if ${tests} == true (specify when invoking: cmake -Dtests=on ...)
|
||||
if(${tests})
|
||||
include(MicroTests)
|
||||
endif()
|
||||
|
||||
######################################################
|
||||
# --- Create Fortran Files ---
|
||||
# omp_lib.mod
|
||||
if(${create_fortran_modules})
|
||||
# Grab fortran-compiler-dependent flags
|
||||
# Cmake will look for cmake/${CMAKE_Fortran_COMPILER_ID}/FortranFlags.cmake to append additional fortran flags.
|
||||
enable_language(Fortran)
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${CMAKE_Fortran_COMPILER_ID} ${CMAKE_MODULE_PATH})
|
||||
find_file(fortran_specific_include_file_found FortranFlags.cmake ${CMAKE_MODULE_PATH})
|
||||
if(fortran_specific_include_file_found)
|
||||
include(FortranFlags)
|
||||
append_fortran_compiler_specific_fort_flags(F_FLAGS)
|
||||
else()
|
||||
warning_say("Could not find cmake/${CMAKE_Fortran_COMPILER_ID}/FortranFlags.cmake: will only use default flags in CommonFlags.cmake")
|
||||
endif()
|
||||
set(omp_lib_f "omp_lib.f90" )
|
||||
add_custom_command(
|
||||
OUTPUT "omp_lib.mod"
|
||||
COMMAND ${CMAKE_Fortran_COMPILER} -c ${F_FLAGS} ${omp_lib_f}
|
||||
DEPENDS ${omp_lib_f}
|
||||
)
|
||||
add_custom_command(
|
||||
OUTPUT "omp_lib_kinds.mod"
|
||||
COMMAND ${CMAKE_Fortran_COMPILER} -c ${F_FLAGS} ${omp_lib_f}
|
||||
DEPENDS ${omp_lib_f}
|
||||
)
|
||||
# clean omp_lib.o from build directory when "make clean"
|
||||
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES omp_lib${obj})
|
||||
endif()
|
||||
|
||||
###############################################################
|
||||
# --- Using expand-vars.pl to generate files ---
|
||||
# - 'file' is generated using expand-vars.pl and 'file'.var
|
||||
# - Any .h .f .f90 .rc files should be created with this recipe
|
||||
macro(expand_vars_recipe filename)
|
||||
get_source_file_property(extra_ev_flags ${filename} COMPILE_DEFINITIONS)
|
||||
if("${extra_ev_flags}" MATCHES "NOTFOUND")
|
||||
set(extra_ev_flags)
|
||||
else()
|
||||
string_to_list("${extra_ev_flags}" extra_ev_flags)
|
||||
endif()
|
||||
find_file(${filename}_path ${filename}.var PATHS ${src_dir}/include/${omp_version} ${src_dir})
|
||||
set(ldeps "${${filename}_path}" "${src_dir}/kmp_version.c" "${tools_dir}/expand-vars.pl")
|
||||
set(expandvarscmd ${PERL_EXECUTABLE} ${tools_dir}/expand-vars.pl --strict ${ev_flags} ${extra_ev_flags} ${${filename}_path} ${filename})
|
||||
if(NOT "${filename}" STREQUAL "")
|
||||
add_custom_command(
|
||||
OUTPUT ${filename}
|
||||
COMMAND ${expandvarscmd}
|
||||
DEPENDS ${ldeps}
|
||||
)
|
||||
endif()
|
||||
endmacro()
|
||||
string_to_list("${ev_flags}" ev_flags)
|
||||
# omp_lib.h : ev-flags += -D KMP_INT_PTR_KIND="int_ptr_kind()"
|
||||
set_source_files_properties(omp_lib.h PROPERTIES COMPILE_DEFINITIONS "-D KMP_INT_PTR_KIND=\"int_ptr_kind()\"")
|
||||
# iomp_lib.h : ev-flags += -D KMP_INT_PTR_KIND=$(if $(filter 32,$(arch)),4,8)
|
||||
if(${IA32}) # 32 bit archs
|
||||
set_source_files_properties(iomp_lib.h PROPERTIES COMPILE_DEFINITIONS "-D KMP_INT_PTR_KIND=4")
|
||||
else()
|
||||
set_source_files_properties(iomp_lib.h PROPERTIES COMPILE_DEFINITIONS "-D KMP_INT_PTR_KIND=8")
|
||||
endif()
|
||||
# libiomp.rc : ev-flags += -D KMP_FILE=$(lib_file)
|
||||
set_source_files_properties(libiomp.rc PROPERTIES COMPILE_DEFINITIONS "-D KMP_FILE=${lib_file}")
|
||||
expand_vars_recipe(omp.h)
|
||||
expand_vars_recipe(omp_lib.h)
|
||||
expand_vars_recipe(omp_lib.f)
|
||||
expand_vars_recipe(omp_lib.f90)
|
||||
expand_vars_recipe(iomp.h)
|
||||
expand_vars_recipe(iomp_lib.h)
|
||||
expand_vars_recipe(libiomp.rc)
|
||||
|
||||
|
||||
####################################################################
|
||||
# Print configuration after all variables are set.
|
||||
say("")
|
||||
say("----------------------- CONFIGURATION -----------------------")
|
||||
say("Operating System : ${os}")
|
||||
say("Architecture : ${arch}")
|
||||
say("Build Type : ${CMAKE_BUILD_TYPE}")
|
||||
say("OpenMP Version : ${omp_version}")
|
||||
say("Lib Type : ${lib_type}")
|
||||
if(${MIC})
|
||||
say("Intel(R) MIC Architecture : ${mic_arch}")
|
||||
say("Intel(R) MIC Architecture OS : ${mic_os}")
|
||||
endif()
|
||||
say("Fortran Modules : ${create_fortran_modules}")
|
||||
# will say development if all zeros
|
||||
if("${build_number}" STREQUAL "00000000")
|
||||
set(build "development")
|
||||
else()
|
||||
set(build "${build_number}")
|
||||
endif()
|
||||
say("Build : ${build}")
|
||||
say("Stats-Gathering : ${stats}")
|
||||
say("Use build.pl rules : ${USE_BUILDPL_RULES}")
|
||||
say("Adaptive locks : ${USE_ADAPTIVE_LOCKS}")
|
||||
say("Use predefined linker flags : ${USE_PREDEFINED_LINKER_FLAGS}")
|
||||
say("Compiler supports quad precision : ${COMPILER_SUPPORTS_QUAD_PRECISION}")
|
||||
say("-------------------------------------------------------------")
|
||||
say("")
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
project(openmp)
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
set(VERSION 5)
|
||||
set(OMP_VERSION "201107")
|
||||
set(OMP_VERSION_NUM "40")
|
||||
|
||||
add_subdirectory(src)
|
||||
@@ -0,0 +1,45 @@
|
||||
#
|
||||
#//===----------------------------------------------------------------------===//
|
||||
#//
|
||||
#// 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.
|
||||
#//
|
||||
#//===----------------------------------------------------------------------===//
|
||||
#
|
||||
|
||||
omp_root?=.
|
||||
include $(omp_root)/tools/common.inc
|
||||
.PHONY: default all omp
|
||||
|
||||
default: omp
|
||||
|
||||
all: omp stubs
|
||||
|
||||
omp: info mkdir
|
||||
@echo $(omp_root)/tools/build.pl $(build_args) --arch=$(arch) --mode=$(mode) lib inc common
|
||||
$(omp_root)/tools/build.pl $(build_args) --arch=$(arch) --mode=$(mode) lib inc common
|
||||
|
||||
stubs: mkdir
|
||||
@echo $(omp_root)/tools/build.pl $(build_args) --arch=$(arch) --mode=$(mode) --stubs lib inc common
|
||||
$(omp_root)/tools/build.pl $(build_args) --arch=$(arch) --mode=$(mode) --stubs lib inc common
|
||||
|
||||
.PHONY: clean info
|
||||
|
||||
clean:
|
||||
$(shell $(RM) -rf $(omp_root)$(SLASH)tmp)
|
||||
@echo clean done
|
||||
|
||||
mkdir:
|
||||
$(shell $(MD) $(omp_root)$(SLASH)tmp >$(NUL) 2>$(NUL))
|
||||
@echo Created $(omp_root)$(SLASH)tmp directory
|
||||
|
||||
info:
|
||||
@echo omp_root=$(omp_root)
|
||||
@echo omp_os=$(omp_os)
|
||||
@echo arch=$(arch)
|
||||
@echo compiler=$(compiler)
|
||||
@echo mic=$(mic)
|
||||
@echo mode=$(mode)
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
|
||||
README for Intel(R) OpenMP* Runtime Library
|
||||
===========================================
|
||||
|
||||
How to Build Documentation
|
||||
==========================
|
||||
|
||||
The main documentation is in Doxygen* format, and this distribution
|
||||
should come with pre-built PDF documentation in doc/Reference.pdf.
|
||||
However, an HTML version can be built by executing:
|
||||
|
||||
% doxygen doc/doxygen/config
|
||||
|
||||
in this directory.
|
||||
|
||||
That will produce HTML documentation in the doc/doxygen/generated
|
||||
directory, which can be accessed by pointing a web browser at the
|
||||
index.html file there.
|
||||
|
||||
If you don't have Doxygen installed, you can download it from
|
||||
www.doxygen.org.
|
||||
|
||||
|
||||
How to Build the Intel(R) OpenMP* Runtime Library
|
||||
=================================================
|
||||
|
||||
The Makefile at the top-level will attempt to detect what it needs to
|
||||
build the Intel(R) OpenMP* Runtime Library. To see the default settings,
|
||||
type:
|
||||
|
||||
make info
|
||||
|
||||
You can change the Makefile's behavior with the following options:
|
||||
|
||||
omp_root: The path to the top-level directory containing the top-level
|
||||
Makefile. By default, this will take on the value of the
|
||||
current working directory.
|
||||
|
||||
omp_os: Operating system. By default, the build will attempt to
|
||||
detect this. Currently supports "linux", "freebsd", "macos", and
|
||||
"windows".
|
||||
|
||||
arch: Architecture. By default, the build will attempt to
|
||||
detect this if not specified by the user. Currently
|
||||
supported values are
|
||||
"32" for IA-32 architecture
|
||||
"32e" for Intel(R) 64 architecture
|
||||
"mic" for Intel(R) Many Integrated Core Architecture
|
||||
|
||||
If "mic" is specified then "icc" will be used as the
|
||||
compiler, and appropriate k1om binutils will be used. The
|
||||
necessary packages must be installed on the build machine
|
||||
for this to be possible (but an Intel(R) Xeon Phi(TM)
|
||||
coprocessor card is not required to build the library).
|
||||
|
||||
compiler: Which compiler to use for the build. Defaults to "icc"
|
||||
or "icl" depending on the value of omp_os. Also supports
|
||||
some versions of "gcc"* when omp_os is "linux". The selected
|
||||
compiler should be installed and in the user's path. The
|
||||
corresponding Fortran compiler should also be in the path.
|
||||
See "Supported RTL Build Configurations" below for more
|
||||
information on compiler versions.
|
||||
|
||||
mode: Library mode: default is "release". Also supports "debug".
|
||||
|
||||
To use any of the options above, simple add <option_name>=<value>. For
|
||||
example, if you want to build with gcc instead of icc, type:
|
||||
|
||||
make compiler=gcc
|
||||
|
||||
There is also an experimental CMake build system. This is *not* yet
|
||||
supported for production use and resulting binaries have not been checked
|
||||
for compatibility.
|
||||
|
||||
Supported RTL Build Configurations
|
||||
==================================
|
||||
|
||||
Supported Architectures: IA-32 architecture, Intel(R) 64, and
|
||||
Intel(R) Many Integrated Core Architecture
|
||||
|
||||
--------------------------------------------
|
||||
| icc/icl | gcc | clang |
|
||||
--------------|---------------|--------------------------|
|
||||
| Linux* OS | Yes(1,5) | Yes(2,4) | Yes(4,6,7) |
|
||||
| FreeBSD* | No | No | Yes(4,6,7) |
|
||||
| OS X* | Yes(1,3,4) | No | Yes(4,6,7) |
|
||||
| Windows* OS | Yes(1,4) | No | No |
|
||||
----------------------------------------------------------
|
||||
|
||||
(1) On IA-32 architecture and Intel(R) 64, icc/icl versions 12.x are
|
||||
supported (12.1 is recommended).
|
||||
(2) gcc version 4.6.2 is supported.
|
||||
(3) For icc on OS X*, OS X* version 10.5.8 is supported.
|
||||
(4) Intel(R) Many Integrated Core Architecture not supported.
|
||||
(5) On Intel(R) Many Integrated Core Architecture, icc/icl versions 13.0
|
||||
or later are required.
|
||||
(6) clang version 3.3 is supported.
|
||||
(7) clang currently does not offer a software-implemented 128 bit extended
|
||||
precision type. Thus, all entry points reliant on this type are removed
|
||||
from the library and cannot be called in the user program. The following
|
||||
functions are not available:
|
||||
__kmpc_atomic_cmplx16_*
|
||||
__kmpc_atomic_float16_*
|
||||
__kmpc_atomic_*_fp
|
||||
|
||||
Front-end Compilers that work with this RTL
|
||||
===========================================
|
||||
|
||||
The following compilers are known to do compatible code generation for
|
||||
this RTL: icc/icl, gcc. See the documentation for more detail.
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
Notices
|
||||
=======
|
||||
|
||||
*Other names and brands may be claimed as the property of others.
|
||||
@@ -0,0 +1,100 @@
|
||||
###############################################################################
|
||||
# This file contains additional build rules that correspond to build.pl's rules
|
||||
# Building libiomp5.dbg is linux only, Windows will build libiomp5md.dll.pdb
|
||||
#
|
||||
# ######### BUILD DEPENDENCIES ##########
|
||||
#
|
||||
# exports/.../libiomp5.so exports/.../libiomp5.dbg
|
||||
# [copy] | | [copy]
|
||||
# | |
|
||||
# ./libiomp5.so ./libiomp5.dbg
|
||||
# [copy] / OR \____________ [copy] | [copy]
|
||||
# / \ |
|
||||
# ./unstripped/libiomp5.so ./stripped/libiomp5.so ./unstripped/libiomp5.dbg
|
||||
# / \ /
|
||||
# / [linking] \[strip] /[strip and store]
|
||||
# / \ /
|
||||
# ${objs} (maybe compiled with -g) ./unstripped/libiomp5.so (library with debug info in it)
|
||||
# |
|
||||
# | [linking]
|
||||
# |
|
||||
# ${objs} (always compiled with -g)
|
||||
#
|
||||
# For icc Linux builds, we always include debugging information via -g and create libiomp5.dbg
|
||||
# so that Intel(R) Parallel Amplifier can use the .dbg file.
|
||||
# For icc Windows builds, we always include debugging information via -Zi and create libiomp5.pdb
|
||||
# in a fashion similar to libiomp5.dbg
|
||||
# For icc Mac builds, we don't bother with the debug info.
|
||||
|
||||
# We build library in unstripped directory
|
||||
file(MAKE_DIRECTORY ${build_dir}/unstripped)
|
||||
|
||||
# Only build the .dbg file for Release builds
|
||||
# Debug and RelWithDebInfo builds should not create a .dbg file.
|
||||
# The debug info should remain in the library file.
|
||||
if(${LINUX} AND ${RELEASE_BUILD})
|
||||
set(dbg_file ${lib_item}.dbg)
|
||||
endif()
|
||||
|
||||
################################
|
||||
# --- Create $(lib_file).dbg ---
|
||||
if(NOT "${dbg_file}" STREQUAL "")
|
||||
# if a ${dbg_file} file is going to be created, then
|
||||
file(MAKE_DIRECTORY ${build_dir}/stripped)
|
||||
|
||||
# ./${lib_file} : stripped/${lib_file}
|
||||
# copy stripped/${lib_file} ./${lib_file}
|
||||
simple_copy_recipe("${lib_file}" "${build_dir}/stripped" "${build_dir}")
|
||||
|
||||
# stripped/${lib_file} : unstripped/${lib_file} ./${dbg_file}
|
||||
# objcopy --strip-debug unstripped/${lib_file} stripped/${lib_file}.tmp
|
||||
# objcopy --add-gnu-debuglink=${dbg_file} stripped/${lib_file}.tmp stripped/${lib_file}
|
||||
add_custom_command(
|
||||
OUTPUT ${build_dir}/stripped/${lib_file}
|
||||
COMMAND ${CMAKE_OBJCOPY} --strip-debug ${build_dir}/unstripped/${lib_file} ${build_dir}/stripped/${lib_file}.tmp
|
||||
COMMAND ${CMAKE_OBJCOPY} --add-gnu-debuglink=${dbg_file} ${build_dir}/stripped/${lib_file}.tmp ${build_dir}/stripped/${lib_file}
|
||||
DEPENDS "${build_dir}/${dbg_file}"
|
||||
)
|
||||
|
||||
# ./${dbg_file} : unstripped/${dbg_file}
|
||||
# copy unstripped/${dbg_file} ./${dbg_file}
|
||||
simple_copy_recipe("${dbg_file}" "${build_dir}/unstripped" "${build_dir}")
|
||||
|
||||
# unstripped/${dbg_file} : unstripped/${lib_file}
|
||||
# objcopy --only-keep-debug unstripped/${lib_file} unstripped/${dbg_file}
|
||||
add_custom_command(
|
||||
OUTPUT ${build_dir}/unstripped/${dbg_file}
|
||||
COMMAND ${CMAKE_OBJCOPY} --only-keep-debug ${build_dir}/unstripped/${lib_file} ${build_dir}/unstripped/${dbg_file}
|
||||
DEPENDS iomp5
|
||||
)
|
||||
|
||||
else()
|
||||
|
||||
# ./${lib_file} : unstripped/${lib_file}
|
||||
# copy unstripped/${lib_file} ./${lib_file}
|
||||
simple_copy_recipe("${lib_file}" "${build_dir}/unstripped" "${build_dir}")
|
||||
endif()
|
||||
|
||||
# Windows specific command to move around debug info files post-build
|
||||
if(NOT "${pdb_file}" STREQUAL "" AND ${RELEASE_BUILD})
|
||||
add_custom_command(TARGET iomp5 POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E rename ${pdb_file} ${pdb_file}.nonstripped
|
||||
COMMAND ${CMAKE_COMMAND} -E rename ${pdb_file}.stripped ${pdb_file}
|
||||
)
|
||||
endif()
|
||||
|
||||
# Have icc build libiomp5 in unstripped directory
|
||||
set_target_properties(iomp5 PROPERTIES
|
||||
LIBRARY_OUTPUT_DIRECTORY "${build_dir}/unstripped"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${build_dir}/unstripped"
|
||||
ARCHIVE_OUTPUT_DIRECTORY "${build_dir}"
|
||||
)
|
||||
|
||||
# Always use RelWithDebInfo flags for Release builds when using the build.pl's build rules (use -g -O2 instead of just -O3)
|
||||
# The debug info is then stripped out at the end of the build and put into libiomp5.dbg for Linux
|
||||
if(${RELEASE_BUILD} AND NOT ${MAC})
|
||||
set(CMAKE_C_FLAGS_RELEASE ${CMAKE_C_FLAGS_RELWITHDEBINFO} )
|
||||
set(CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELWITHDEBINFO})
|
||||
set(CMAKE_ASM_FLAGS_RELEASE ${CMAKE_ASM_FLAGS_RELWITHDEBINFO})
|
||||
endif()
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
# This file holds Clang (clang/clang++) specific compiler dependent flags
|
||||
# The flag types are:
|
||||
# 1) Assembly flags
|
||||
|
||||
#########################################################
|
||||
# Assembly flags
|
||||
function(append_assembler_specific_asm_flags input_asm_flags)
|
||||
set(local_asm_flags)
|
||||
append_asm_flags("-x assembler-with-cpp") # Assembly file that needs to be preprocessed
|
||||
if(${IA32})
|
||||
append_asm_flags("-m32") # Generate 32 bit IA-32 architecture code
|
||||
append_asm_flags("-msse2") # Allow use of Streaming SIMD Instructions
|
||||
endif()
|
||||
set(${input_asm_flags} ${${input_asm_flags}} "${local_asm_flags}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
# This file holds Clang (clang/clang++) specific compiler dependent flags
|
||||
# The flag types are:
|
||||
# 1) C/C++ Compiler flags
|
||||
# 2) Linker flags
|
||||
|
||||
#########################################################
|
||||
# C/C++ Compiler flags
|
||||
function(append_compiler_specific_c_and_cxx_flags input_c_flags input_cxx_flags)
|
||||
set(local_c_flags)
|
||||
set(local_cxx_flags)
|
||||
append_c_and_cxx_flags("-std=c++0x") # Enables support for many C++11 (formerly known as C++0x) features. The following are the most recently added features:
|
||||
append_c_and_cxx_flags("-fno-exceptions") # Exception handling table generation is disabled.
|
||||
append_c_and_cxx_flags("-x c++") # Compile C files as C++ files
|
||||
if(${IA32})
|
||||
append_c_and_cxx_flags("-m32") # Generate 32 bit IA-32 architecture code
|
||||
append_c_and_cxx_flags("-msse2") # Allow use of Streaming SIMD Instructions
|
||||
elseif(${ARM})
|
||||
append_c_and_cxx_flags("-marm") # Target the ARM architecture
|
||||
endif()
|
||||
append_c_and_cxx_flags("-Wno-unused-value") # Don't warn about unused values
|
||||
append_c_and_cxx_flags("-Wno-switch") # Don't warn about switch statements that don't cover entire range of values
|
||||
set(${input_c_flags} ${${input_c_flags}} "${local_c_flags}" PARENT_SCOPE)
|
||||
set(${input_cxx_flags} ${${input_cxx_flags}} "${local_cxx_flags}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
#########################################################
|
||||
# Linker flags
|
||||
function(append_compiler_specific_linker_flags input_ld_flags input_ld_flags_libs)
|
||||
set(local_ld_flags)
|
||||
set(local_ld_flags_libs)
|
||||
if(${IA32})
|
||||
append_linker_flags("-m32")
|
||||
append_linker_flags("-msse2")
|
||||
endif()
|
||||
set(${input_ld_flags} ${${input_ld_flags}} "${local_ld_flags}" PARENT_SCOPE)
|
||||
set(${input_ld_flags_libs} ${${input_ld_flags_libs}} "${local_ld_flags_libs}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
# This file holds the common flags independent of compiler
|
||||
# The flag types are:
|
||||
# 1) Assembly flags (append_asm_flags_common)
|
||||
# 2) C/C++ Compiler flags (append_c_and_cxx_flags_common)
|
||||
# 3) Fortran Compiler flags (append_fort_flags_common)
|
||||
# 4) Linker flags (append_linker_flags_common)
|
||||
# 5) Archiver flags (append_archiver_flags_common)
|
||||
|
||||
# These append_* macros all append to the corresponding list variable holding the flags.
|
||||
macro(append_c_flags new_flag)
|
||||
list(APPEND local_c_flags "${new_flag}")
|
||||
endmacro()
|
||||
|
||||
macro(append_cxx_flags new_flag)
|
||||
list(APPEND local_cxx_flags "${new_flag}")
|
||||
endmacro()
|
||||
|
||||
macro(append_c_and_cxx_flags new_flag)
|
||||
append_c_flags("${new_flag}")
|
||||
append_cxx_flags("${new_flag}")
|
||||
endmacro()
|
||||
|
||||
macro(append_asm_flags new_flag)
|
||||
list(APPEND local_asm_flags "${new_flag}")
|
||||
endmacro()
|
||||
|
||||
macro(append_fort_flags new_flag)
|
||||
list(APPEND local_fort_flags "${new_flag}")
|
||||
endmacro()
|
||||
|
||||
# The difference between linker_flags and linker_flags_libs is linker_flags_libs
|
||||
# is put at the end of the linker command where linking libraries should be done.
|
||||
macro(append_linker_flags new_flag)
|
||||
list(APPEND local_ld_flags "${new_flag}")
|
||||
endmacro()
|
||||
|
||||
macro(append_linker_flags_library new_flag)
|
||||
list(APPEND local_ld_flags_libs "${new_flag}")
|
||||
endmacro()
|
||||
|
||||
macro(append_archiver_flags new_flag)
|
||||
list(APPEND local_ar_flags "${new_flag}")
|
||||
endmacro()
|
||||
|
||||
#########################################################
|
||||
# Global Assembly flags
|
||||
function(append_asm_flags_common input_asm_flags)
|
||||
set(local_asm_flags)
|
||||
set(${input_asm_flags} "${${input_asm_flags}}" "${local_asm_flags}" "${USER_ASM_FLAGS}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
#########################################################
|
||||
# Global C/C++ Compiler flags
|
||||
function(append_c_and_cxx_flags_common input_c_flags input_cxx_flags)
|
||||
set(local_c_flags)
|
||||
set(local_cxx_flags)
|
||||
set(${input_c_flags} "${${input_c_flags}}" "${local_c_flags}" "${USER_C_FLAGS}" PARENT_SCOPE)
|
||||
set(${input_cxx_flags} "${${input_cxx_flags}}" "${local_cxx_flags}" "${USER_CXX_FLAGS}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
#########################################################
|
||||
# Global Fortran Compiler flags (for creating .mod files)
|
||||
function(append_fort_flags_common input_fort_flags)
|
||||
set(local_fort_flags)
|
||||
set(${input_fort_flags} "${${input_fort_flags}}" "${local_fort_flags}" "${USER_F_FLAGS}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
#########################################################
|
||||
# Linker flags
|
||||
function(append_linker_flags_common input_ld_flags input_ld_flags_libs)
|
||||
set(local_ld_flags)
|
||||
set(local_ld_flags_libs)
|
||||
|
||||
#################################
|
||||
# Windows linker flags
|
||||
if(${WINDOWS})
|
||||
|
||||
##################
|
||||
# MAC linker flags
|
||||
elseif(${MAC})
|
||||
if(${USE_PREDEFINED_LINKER_FLAGS})
|
||||
append_linker_flags("-single_module")
|
||||
append_linker_flags("-current_version ${version}.0")
|
||||
append_linker_flags("-compatibility_version ${version}.0")
|
||||
endif()
|
||||
#####################################################################################
|
||||
# Intel(R) Many Integrated Core Architecture (Intel(R) MIC Architecture) linker flags
|
||||
elseif(${MIC})
|
||||
if(${USE_PREDEFINED_LINKER_FLAGS})
|
||||
append_linker_flags("-Wl,-x")
|
||||
append_linker_flags("-Wl,--warn-shared-textrel") # Warn if the linker adds a DT_TEXTREL to a shared object.
|
||||
append_linker_flags("-Wl,--as-needed")
|
||||
append_linker_flags("-Wl,--version-script=${src_dir}/exports_so.txt") # Use exports_so.txt as version script to create versioned symbols for ELF libraries
|
||||
if(NOT ${STUBS_LIBRARY})
|
||||
append_linker_flags_library("-pthread") # link in pthread library
|
||||
append_linker_flags_library("-ldl") # link in libdl (dynamic loader library)
|
||||
endif()
|
||||
if(${STATS_GATHERING})
|
||||
append_linker_flags_library("-Wl,-lstdc++") # link in standard c++ library (stats-gathering needs it)
|
||||
endif()
|
||||
endif()
|
||||
#########################
|
||||
# Unix based linker flags
|
||||
else()
|
||||
# For now, always include --version-script flag on Unix systems.
|
||||
append_linker_flags("-Wl,--version-script=${src_dir}/exports_so.txt") # Use exports_so.txt as version script to create versioned symbols for ELF libraries
|
||||
if(${USE_PREDEFINED_LINKER_FLAGS})
|
||||
append_linker_flags("-Wl,-z,noexecstack") # Marks the object as not requiring executable stack.
|
||||
append_linker_flags("-Wl,--as-needed") # Only adds library dependencies as they are needed. (if libiomp5 actually uses a function from the library, then add it)
|
||||
if(NOT ${STUBS_LIBRARY})
|
||||
append_linker_flags("-Wl,--warn-shared-textrel") # Warn if the linker adds a DT_TEXTREL to a shared object.
|
||||
append_linker_flags("-Wl,-fini=__kmp_internal_end_fini") # When creating an ELF executable or shared object, call NAME when the
|
||||
# executable or shared object is unloaded, by setting DT_FINI to the
|
||||
# address of the function. By default, the linker uses "_fini" as the function to call.
|
||||
append_linker_flags_library("-pthread") # link pthread library
|
||||
if(NOT ${FREEBSD})
|
||||
append_linker_flags_library("-Wl,-ldl") # link in libdl (dynamic loader library)
|
||||
endif()
|
||||
endif()
|
||||
endif() # if(${USE_PREDEFINED_LINKER_FLAGS})
|
||||
endif() # if(${OPERATING_SYSTEM}) ...
|
||||
|
||||
set(${input_ld_flags} "${${input_ld_flags}}" "${local_ld_flags}" "${USER_LD_FLAGS}" PARENT_SCOPE)
|
||||
set(${input_ld_flags_libs} "${${input_ld_flags_libs}}" "${local_ld_flags_libs}" "${USER_LD_LIB_FLAGS}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
#########################################################
|
||||
# Archiver Flags
|
||||
function(append_archiver_flags_common input_ar_flags)
|
||||
set(local_ar_flags)
|
||||
set(${input_ar_flags} "${${input_ar_flags}}" "${local_ar_flags}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
#
|
||||
#//===----------------------------------------------------------------------===//
|
||||
#//
|
||||
#// 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 append_definitions(string new_flag);
|
||||
# - appends new_flag to cpp_flags list
|
||||
macro(append_definitions new_flag)
|
||||
list(APPEND local_cpp_flags "${new_flag}")
|
||||
endmacro()
|
||||
|
||||
function(append_cpp_flags input_cpp_flags)
|
||||
set(local_cpp_flags)
|
||||
|
||||
append_definitions("-D USE_ITT_BUILD")
|
||||
append_definitions("-D KMP_ARCH_STR=\"\\\\\"${legal_arch}\\\\\"\"")
|
||||
append_definitions("-D BUILD_I8")
|
||||
append_definitions("-D KMP_LIBRARY_FILE=\\\\\"${lib_file}\\\\\"") # yes... you need 5 backslashes...
|
||||
append_definitions("-D KMP_VERSION_MAJOR=${version}")
|
||||
|
||||
# customize to 128 bytes for ppc64
|
||||
if(${PPC64})
|
||||
append_definitions("-D CACHE_LINE=128")
|
||||
else()
|
||||
append_definitions("-D CACHE_LINE=64")
|
||||
endif()
|
||||
|
||||
append_definitions("-D KMP_ADJUST_BLOCKTIME=1")
|
||||
append_definitions("-D BUILD_PARALLEL_ORDERED")
|
||||
append_definitions("-D KMP_ASM_INTRINS")
|
||||
if(${USE_ITT_NOTIFY})
|
||||
append_definitions("-D USE_ITT_NOTIFY=1")
|
||||
else()
|
||||
append_definitions("-D USE_ITT_NOTIFY=0")
|
||||
append_definitions("-D INTEL_NO_ITTNOTIFY_API")
|
||||
endif()
|
||||
append_definitions("-D INTEL_ITTNOTIFY_PREFIX=__kmp_itt_")
|
||||
|
||||
#####################
|
||||
# Windows definitions
|
||||
if(${WINDOWS})
|
||||
append_definitions("-D _CRT_SECURE_NO_WARNINGS")
|
||||
append_definitions("-D _CRT_SECURE_NO_DEPRECATE")
|
||||
append_definitions("-D _WINDOWS")
|
||||
append_definitions("-D _WINNT")
|
||||
append_definitions("-D _WIN32_WINNT=0x0501")
|
||||
append_definitions("-D KMP_WIN_CDECL")
|
||||
append_definitions("-D _USRDLL")
|
||||
if(${DEBUG_BUILD})
|
||||
append_definitions("-D _ITERATOR_DEBUG_LEVEL=0")
|
||||
endif()
|
||||
else() # Other than windows... (Unix based systems, Intel(R) Many Integrated Core Architecture (Intel(R) MIC Architecture), and Mac)
|
||||
append_definitions("-D _GNU_SOURCE")
|
||||
append_definitions("-D _REENTRANT")
|
||||
append_definitions("-D BUILD_TV")
|
||||
append_definitions("-D USE_CBLKDATA")
|
||||
if(NOT "${version}" STREQUAL "4")
|
||||
append_definitions("-D KMP_GOMP_COMPAT")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#######################################
|
||||
# Intel(R) MIC Architecture definitions
|
||||
if(${MIC})
|
||||
append_definitions("-D KMP_TDATA_GTID")
|
||||
else() # Other than Intel(R) MIC Architecture...
|
||||
append_definitions("-D USE_LOAD_BALANCE")
|
||||
endif()
|
||||
|
||||
##################
|
||||
# Unix definitions
|
||||
if(${LINUX})
|
||||
append_definitions("-D KMP_TDATA_GTID")
|
||||
endif()
|
||||
|
||||
##################################
|
||||
# Other conditional definitions
|
||||
append_definitions("-D KMP_USE_ASSERT")
|
||||
append_definitions("-D GUIDEDLL_EXPORTS")
|
||||
if(${STUBS_LIBRARY})
|
||||
append_definitions("-D KMP_STUB")
|
||||
endif()
|
||||
if(${DEBUG_BUILD} OR ${RELWITHDEBINFO_BUILD})
|
||||
append_definitions("-D KMP_DEBUG")
|
||||
endif()
|
||||
if(${DEBUG_BUILD})
|
||||
append_definitions("-D _DEBUG")
|
||||
append_definitions("-D BUILD_DEBUG")
|
||||
endif()
|
||||
if(${STATS_GATHERING})
|
||||
append_definitions("-D KMP_STATS_ENABLED=1")
|
||||
else()
|
||||
append_definitions("-D KMP_STATS_ENABLED=0")
|
||||
endif()
|
||||
|
||||
# OpenMP version flags
|
||||
set(have_omp_50 0)
|
||||
set(have_omp_41 0)
|
||||
set(have_omp_40 0)
|
||||
set(have_omp_30 0)
|
||||
if(${omp_version} EQUAL 50 OR ${omp_version} GREATER 50)
|
||||
set(have_omp_50 1)
|
||||
endif()
|
||||
if(${omp_version} EQUAL 41 OR ${omp_version} GREATER 41)
|
||||
set(have_omp_41 1)
|
||||
endif()
|
||||
if(${omp_version} EQUAL 40 OR ${omp_version} GREATER 40)
|
||||
set(have_omp_40 1)
|
||||
endif()
|
||||
if(${omp_version} EQUAL 30 OR ${omp_version} GREATER 30)
|
||||
set(have_omp_30 1)
|
||||
endif()
|
||||
append_definitions("-D OMP_50_ENABLED=${have_omp_50}")
|
||||
append_definitions("-D OMP_41_ENABLED=${have_omp_41}")
|
||||
append_definitions("-D OMP_40_ENABLED=${have_omp_40}")
|
||||
append_definitions("-D OMP_30_ENABLED=${have_omp_30}")
|
||||
|
||||
# Architectural definitions
|
||||
if(${INTEL64} OR ${IA32})
|
||||
if(${USE_ADAPTIVE_LOCKS})
|
||||
append_definitions("-D KMP_USE_ADAPTIVE_LOCKS=1")
|
||||
else()
|
||||
append_definitions("-D KMP_USE_ADAPTIVE_LOCKS=0")
|
||||
endif()
|
||||
append_definitions("-D KMP_DEBUG_ADAPTIVE_LOCKS=0")
|
||||
else()
|
||||
append_definitions("-D KMP_USE_ADAPTIVE_LOCKS=0")
|
||||
append_definitions("-D KMP_DEBUG_ADAPTIVE_LOCKS=0")
|
||||
endif()
|
||||
set(${input_cpp_flags} "${${input_cpp_flags}}" "${local_cpp_flags}" "${USER_CPP_FLAGS}" "$ENV{CPPFLAGS}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
# This file holds GNU (gcc/g++) specific compiler dependent flags
|
||||
# The flag types are:
|
||||
# 1) Assembly flags
|
||||
|
||||
#########################################################
|
||||
# Assembly flags
|
||||
function(append_assembler_specific_asm_flags input_asm_flags)
|
||||
set(local_asm_flags)
|
||||
append_asm_flags("-x assembler-with-cpp") # Assembly file that needs to be preprocessed
|
||||
if(${IA32})
|
||||
append_asm_flags("-m32") # Generate 32 bit IA-32 architecture code
|
||||
append_asm_flags("-msse2") # Allow use of Streaming SIMD Instructions
|
||||
endif()
|
||||
set(${input_asm_flags} ${${input_asm_flags}} "${local_asm_flags}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
# This file holds GNU (gcc/g++) specific compiler dependent flags
|
||||
# The flag types are:
|
||||
# 2) C/C++ Compiler flags
|
||||
# 4) Linker flags
|
||||
unset(COMPILER_SUPPORTS_QUAD_PRECISION CACHE)
|
||||
set(COMPILER_SUPPORTS_QUAD_PRECISION true CACHE BOOL "Does the compiler support a 128-bit floating point type?")
|
||||
set(COMPILER_QUAD_TYPE __float128)
|
||||
|
||||
#########################################################
|
||||
# C/C++ Compiler flags
|
||||
function(append_compiler_specific_c_and_cxx_flags input_c_flags input_cxx_flags)
|
||||
set(local_c_flags)
|
||||
set(local_cxx_flags)
|
||||
append_c_and_cxx_flags("-std=c++0x") # Enables support for many C++11 (formerly known as C++0x) features. The following are the most recently added features:
|
||||
append_c_and_cxx_flags("-fno-exceptions") # Exception handling table generation is disabled.
|
||||
append_c_and_cxx_flags("-x c++") # Compile C files as C++ files
|
||||
if(${IA32})
|
||||
append_c_and_cxx_flags("-m32") # Generate 32 bit IA-32 architecture code
|
||||
append_c_and_cxx_flags("-msse2") # Allow use of Streaming SIMD Instructions
|
||||
elseif(${ARM})
|
||||
append_c_and_cxx_flags("-marm") # Target the ARM architecture
|
||||
endif()
|
||||
set(${input_c_flags} ${${input_c_flags}} "${local_c_flags}" PARENT_SCOPE)
|
||||
set(${input_cxx_flags} ${${input_cxx_flags}} "${local_cxx_flags}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
#########################################################
|
||||
# Linker flags
|
||||
function(append_compiler_specific_linker_flags input_ld_flags input_ld_flags_libs)
|
||||
set(local_ld_flags)
|
||||
set(local_ld_flags_libs)
|
||||
if(${WINDOWS})
|
||||
elseif(${MAC})
|
||||
elseif(${MIC})
|
||||
else()
|
||||
append_linker_flags("-static-libgcc") # Causes libgcc to be linked in statically
|
||||
endif()
|
||||
if(${IA32})
|
||||
append_linker_flags("-m32")
|
||||
append_linker_flags("-msse2")
|
||||
endif()
|
||||
set(${input_ld_flags} ${${input_ld_flags}} "${local_ld_flags}" PARENT_SCOPE)
|
||||
set(${input_ld_flags_libs} ${${input_ld_flags_libs}} "${local_ld_flags_libs}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
# This file holds GNU (gcc/g++) specific compiler dependent flags
|
||||
# The flag types are:
|
||||
# 1) Fortran Compiler flags
|
||||
|
||||
#########################################################
|
||||
# Fortran Compiler flags (for creating .mod files)
|
||||
function(append_fortran_compiler_specific_fort_flags input_fort_flags)
|
||||
set(local_fort_flags)
|
||||
if(${IA32})
|
||||
append_fort_flags("-m32")
|
||||
append_fort_flags("-msse2")
|
||||
endif()
|
||||
set(${input_fort_flags} ${${input_fort_flags}} "${local_fort_flags}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
@@ -0,0 +1,256 @@
|
||||
#
|
||||
#//===----------------------------------------------------------------------===//
|
||||
#//
|
||||
#// 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.
|
||||
#//
|
||||
#//===----------------------------------------------------------------------===//
|
||||
#
|
||||
|
||||
####################################### FUNCTIONS/MACROS ###########################################
|
||||
# It should be noted that in cmake, functions can only be used on a single line with the return value
|
||||
# stored in a parameter you send to the function. There isn't a true return value. So technically,
|
||||
# all functions would have a C/C++ prototype of:
|
||||
# void function_name(parameter1, parameter2, ...);
|
||||
#
|
||||
# If you want a return value, you have to use a parameter so the function prototype would be:
|
||||
# void function_name(input_parameter1, input_parameter2, ..., return_value)
|
||||
# ##################
|
||||
|
||||
# void say(string message_to_user);
|
||||
# - prints out message_to_user
|
||||
macro(say message_to_user)
|
||||
message("${message_to_user}")
|
||||
endmacro()
|
||||
|
||||
# void warning_say(string message_to_user);
|
||||
# - prints out message_to_user with a warning
|
||||
macro(warning_say message_to_user)
|
||||
message(WARNING "${message_to_user}")
|
||||
endmacro()
|
||||
|
||||
# void error_say(string message_to_user);
|
||||
# - prints out message_to_user with an error and exits cmake
|
||||
macro(error_say message_to_user)
|
||||
message(FATAL_ERROR "${message_to_user}")
|
||||
endmacro()
|
||||
|
||||
# void debug_say(string message_to_developer);
|
||||
# - prints out message when GLOBAL_DEBUG == 1 (for debugging cmake build)
|
||||
macro(debug_say message_to_developer)
|
||||
if(${GLOBAL_DEBUG} STREQUAL "1")
|
||||
say("DEBUG: ${message_to_developer}")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# void debug_say_var(variable var);
|
||||
# - prints the variable name and its value (for debugging cmake build)
|
||||
macro(debug_say_var var)
|
||||
if(${GLOBAL_DEBUG} STREQUAL "1")
|
||||
say("DEBUG: Variable: ${var} = ${${var}} ")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# void set_legal_arch(string* return_arch_string);
|
||||
# - returns (through return_arch_string) the formal architecture
|
||||
# string or warns user of unknown architecture
|
||||
function(set_legal_arch return_arch_string)
|
||||
if(${IA32})
|
||||
set(${return_arch_string} "IA-32" PARENT_SCOPE)
|
||||
elseif(${INTEL64})
|
||||
set(${return_arch_string} "Intel(R) 64" PARENT_SCOPE)
|
||||
elseif(${MIC})
|
||||
set(${return_arch_string} "Intel(R) Many Integrated Core Architecture" PARENT_SCOPE)
|
||||
elseif(${arch} STREQUAL "l1")
|
||||
set(${return_arch_string} "L1OM" PARENT_SCOPE)
|
||||
elseif(${ARM})
|
||||
set(${return_arch_string} "ARM" PARENT_SCOPE)
|
||||
elseif(${PPC64})
|
||||
set(${return_arch_string} "PPC64" PARENT_SCOPE)
|
||||
else()
|
||||
warning_say("set_legal_arch(): Warning: Unknown architecture...")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# void check_variable(string var, string var_name, list<string>values_list);
|
||||
# - runs through values_list checking if ${var} == values_list[i] for any i.
|
||||
# - if the var is found, then just print it out
|
||||
# - if the var is not found, then warn user
|
||||
function(check_variable var values_list)
|
||||
set(valid_flag 0)
|
||||
foreach(value IN LISTS values_list)
|
||||
if("${${var}}" STREQUAL "${value}")
|
||||
set(valid_flag 1)
|
||||
set(the_value "${value}")
|
||||
endif()
|
||||
endforeach()
|
||||
if(${valid_flag} EQUAL 0)
|
||||
error_say("check_variable(): ${var} = ${${var}} is unknown")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# void _export_lib_dir(string export_dir, string platform, string suffix, string* return_value);
|
||||
# - basically a special case for mac platforms where it adds '.thin' to the output lib directory
|
||||
function(_export_lib_dir pltfrm return_value)
|
||||
if(${MAC})
|
||||
set(${return_value} "${export_dir}/${pltfrm}${suffix}/lib.thin" PARENT_SCOPE)
|
||||
else()
|
||||
set(${return_value} "${export_dir}/${pltfrm}${suffix}/lib" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# void _export_lib_fat_dir(string export_dir, string platform, string suffix, string* return_value);
|
||||
# - another mac specialty case for fat libraries.
|
||||
# - this sets export_lib_fat_dir in the MAIN part of CMakeLists.txt
|
||||
function(_export_lib_fat_dir pltfrm return_value)
|
||||
set(${return_value} "${export_dir}/${pltfrm}${suffix}/lib" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# void get_build_number(string src_dir, string* return_build_number);
|
||||
# - grab the eight digit build number (or 00000000) from kmp_version.c
|
||||
function(get_build_number src_dir return_build_number)
|
||||
# sets file_lines_list to a list of all lines in kmp_version.c
|
||||
file(STRINGS "${src_dir}/src/kmp_version.c" file_lines_list)
|
||||
|
||||
# runs through each line in kmp_version.c
|
||||
foreach(line IN LISTS file_lines_list)
|
||||
# if the line begins with "#define KMP_VERSION_BUILD" then we take not of the build number
|
||||
string(REGEX MATCH "^[ \t]*#define[ \t]+KMP_VERSION_BUILD" valid "${line}")
|
||||
if(NOT "${valid}" STREQUAL "") # if we matched "#define KMP_VERSION_BUILD", then grab the build number
|
||||
string(REGEX REPLACE "^[ \t]*#define[ \t]+KMP_VERSION_BUILD[ \t]+([0-9]+)" "\\1"
|
||||
build_number "${line}"
|
||||
)
|
||||
endif()
|
||||
endforeach()
|
||||
set(${return_build_number} "${build_number}" PARENT_SCOPE) # return build number
|
||||
endfunction()
|
||||
|
||||
# void set_legal_type(string* return_legal_type);
|
||||
# - set the legal type name Performance/Profiling/Stub
|
||||
function(set_legal_type return_legal_type)
|
||||
if(${NORMAL_LIBRARY})
|
||||
set(${return_legal_type} "Performance" PARENT_SCOPE)
|
||||
elseif(${PROFILE_LIBRARY})
|
||||
set(${return_legal_type} "Profiling" PARENT_SCOPE)
|
||||
elseif(${STUBS_LIBRARY})
|
||||
set(${return_legal_type} "Stub" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# void set_mac_os_new(bool* return_mac_os_new);
|
||||
# - sets the return_mac_os_new variable to true or false based on macosx version
|
||||
# - no real "cmakey" way to do this. Have to call execute_process()
|
||||
function(set_mac_os_new return_mac_os_new)
|
||||
execute_process(COMMAND "sw_vers" "-productVersion" OUTPUT_VARIABLE mac_osx_version)
|
||||
if("${mac_osx_version}" VERSION_GREATER "10.6")
|
||||
set(${return_mac_os_new} TRUE PARENT_SCOPE)
|
||||
else()
|
||||
set(${return_mac_os_new} FALSE PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# void add_prefix(string prefix, list<string>* list_of_items);
|
||||
# - returns list_of_items with prefix prepended to all items
|
||||
# - original list is modified
|
||||
function(add_prefix prefix list_of_items)
|
||||
set(local_list "")
|
||||
foreach(item IN LISTS "${list_of_items}")
|
||||
if(NOT "${item}" STREQUAL "")
|
||||
list(APPEND local_list "${prefix}${item}")
|
||||
endif()
|
||||
endforeach()
|
||||
set(${list_of_items} "${local_list}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# void add_suffix(string suffix, list<string>* list_of_items);
|
||||
# - returns list_of_items with suffix appended to all items
|
||||
# - original list is modified
|
||||
function(add_suffix suffix list_of_items)
|
||||
set(local_list "")
|
||||
foreach(item IN LISTS "${list_of_items}")
|
||||
if(NOT "${item}" STREQUAL "")
|
||||
list(APPEND local_list "${item}${suffix}")
|
||||
endif()
|
||||
endforeach()
|
||||
set(${list_of_items} "${local_list}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# void strip_suffix(list<string> list_of_items, list<string>* return_list);
|
||||
# - returns a new list with suffix stripped (i.e., foo.c => foo)
|
||||
# - list_of_items is not modified, return_list is modified
|
||||
function(strip_suffix list_of_items return_list)
|
||||
set(local_list "")
|
||||
foreach(item IN LISTS "${list_of_items}")
|
||||
if(NOT "${item}" STREQUAL "")
|
||||
get_filename_component(filename "${item}" NAME_WE)
|
||||
list(APPEND local_list "${filename}")
|
||||
endif()
|
||||
endforeach()
|
||||
set(${return_list} "${local_list}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# void list_to_string(list<string> list_of_things, string* return_string);
|
||||
# - converts a list to a space separated string
|
||||
function(list_to_string list_of_things return_string)
|
||||
string(REPLACE ";" " " output_variable "${list_of_things}")
|
||||
set(${return_string} "${output_variable}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# void string_to_list(string str, list<string>* return_list);
|
||||
# - converts a string to a semicolon separated list
|
||||
# - what it really does is just string_replace all running whitespace to a semicolon
|
||||
# - in cmake, a list is strings separated by semicolons: i.e., list of four items, list = "item1;item2;item3;item4"
|
||||
function(string_to_list str return_list)
|
||||
set(outstr)
|
||||
string(REGEX REPLACE "[ \t]+" ";" outstr "${str}")
|
||||
set(${return_list} "${outstr}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# void get_date(string* return_date);
|
||||
# - returns the current date "yyyy-mm-dd hh:mm:ss UTC"
|
||||
# - this function alone causes the need for CMake v2.8.11 (TIMESTAMP)
|
||||
#function(get_date return_date)
|
||||
# string(TIMESTAMP local_date "%Y-%m-%d %H:%M:%S UTC" UTC)
|
||||
# set(${return_date} ${local_date} PARENT_SCOPE)
|
||||
#endfunction()
|
||||
|
||||
# void find_a_program(string program_name, list<string> extra_paths, bool fail_on_not_found, string return_variable_name);
|
||||
# - returns the full path of a program_name
|
||||
# - first looks in the list of extra_paths
|
||||
# - if not found in extra_paths, then look through system path
|
||||
# - errors out if fail_on_not_found == true and cmake could not find program_name.
|
||||
function(find_a_program program_name extra_paths fail_on_not_found return_variable_name)
|
||||
# first try to find the program in the extra_paths
|
||||
find_program(${return_variable_name} "${program_name}" PATHS "${extra_paths}" DOC "Path to ${program_name}" NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_PATH NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH)
|
||||
if("${${return_variable_name}}" MATCHES NOTFOUND)
|
||||
# if no extra_paths, or couldn't find it, then look in system $PATH
|
||||
find_program(${return_variable_name} "${program_name}" DOC "Path to ${program_name}")
|
||||
if("${${return_variable_name}}" MATCHES NOTFOUND AND ${fail_on_not_found})
|
||||
error_say("Error: Could not find program: ${program_name}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT "${${return_variable_name}}" MATCHES NOTFOUND)
|
||||
say("-- Found ${program_name}: ${${return_variable_name}}")
|
||||
endif()
|
||||
|
||||
set(${return_variable_name} ${${return_variable_name}} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# WINDOWS SPECIFIC
|
||||
# void replace_md_with_mt(string flags_var)
|
||||
# - This macro replaces the /MD compiler flags (Windows specific) with /MT compiler flags
|
||||
# - This does nothing if no /MD flags were replaced.
|
||||
macro(replace_md_with_mt flags_var)
|
||||
set(flags_var_name ${flags_var}) # i.e., CMAKE_C_FLAGS_RELEASE
|
||||
set(flags_var_value ${${flags_var}}) # i.e., "/MD /O2 ..."
|
||||
string(REPLACE /MD /MT temp_out "${flags_var_value}")
|
||||
string(COMPARE NOTEQUAL "${temp_out}" "${flags_var_value}" something_was_replaced)
|
||||
if("${something_was_replaced}")
|
||||
unset(${flags_var_name} CACHE)
|
||||
set(${flags_var_name} ${temp_out} CACHE STRING "Replaced /MD with /MT compiler flags")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
# This file holds Intel(R) C Compiler / Intel(R) C++ Compiler / Intel(R) Fortran Compiler (icc/icpc/icl.exe/ifort) dependent flags
|
||||
# The flag types are:
|
||||
# 1) Assembly flags
|
||||
|
||||
#########################################################
|
||||
# Assembly flags
|
||||
function(append_assembler_specific_asm_flags input_asm_flags)
|
||||
set(local_asm_flags)
|
||||
append_asm_flags("-x assembler-with-cpp") # Assembly file that needs to be preprocessed
|
||||
if(${IA32})
|
||||
append_asm_flags("-safeseh") # Registers exception handlers for safe exception handling.
|
||||
append_asm_flags("-coff") # Generates common object file format (COFF) type of object module.
|
||||
# Generally required for Win32 assembly language development.
|
||||
append_asm_flags("-D _M_IA32")
|
||||
elseif(${INTEL64})
|
||||
append_asm_flags("-D _M_AMD64")
|
||||
endif()
|
||||
if(${MIC})
|
||||
append_asm_flags("-mmic") # Build Intel(R) MIC Architecture native code
|
||||
endif()
|
||||
if(${WINDOWS})
|
||||
# CMake prefers the /MD flags when compiling Windows sources, but libiomp5 needs to use /MT instead
|
||||
# So we replace these /MD instances with /MT within the CMAKE_*_FLAGS variables and put that out to the CACHE.
|
||||
# replace_md_with_mt() is in HelperFunctions.cmake
|
||||
replace_md_with_mt(CMAKE_ASM_MASM_FLAGS)
|
||||
replace_md_with_mt(CMAKE_ASM_MASM_FLAGS_RELEASE)
|
||||
replace_md_with_mt(CMAKE_ASM_MASM_FLAGS_RELWITHDEBINFO)
|
||||
replace_md_with_mt(CMAKE_ASM_MASM_FLAGS_DEBUG)
|
||||
endif()
|
||||
set(${input_asm_flags} ${${input_asm_flags}} "${local_asm_flags}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
@@ -0,0 +1,148 @@
|
||||
# This file holds Intel(R) C Compiler / Intel(R) C++ Compiler / Intel(R) Fortran Compiler (icc/icpc/icl.exe/ifort) dependent flags
|
||||
# The flag types are:
|
||||
# 2) C/C++ Compiler flags
|
||||
# 4) Linker flags
|
||||
|
||||
# icc has a 128-bit floating point type called _Quad. Always compile with 128-bit floating point if it exists.
|
||||
unset(COMPILER_SUPPORTS_QUAD_PRECISION CACHE)
|
||||
set(COMPILER_SUPPORTS_QUAD_PRECISION true CACHE BOOL "Does the compiler support a 128-bit floating point type?")
|
||||
set(COMPILER_QUAD_TYPE _Quad)
|
||||
|
||||
#########################################################
|
||||
# icc C/C++ Compiler flags
|
||||
function(append_compiler_specific_c_and_cxx_flags input_c_flags input_cxx_flags)
|
||||
set(local_c_flags)
|
||||
set(local_cxx_flags)
|
||||
if(${WINDOWS})
|
||||
|
||||
append_c_flags("-TP") # Tells the compiler to process a file as a C++ source file.
|
||||
append_cxx_flags("-EHsc") # Enable C++ exception handling.
|
||||
append_c_and_cxx_flags("-nologo") # Turn off tool banner.
|
||||
append_c_and_cxx_flags("-W3") # Enables diagnostics for remarks, warnings, and errors.
|
||||
# Additional warnings are also enabled above level 2 warnings.
|
||||
append_c_and_cxx_flags("-WX") # Change all Warnings to Errors
|
||||
append_c_and_cxx_flags("-GS") # Lets you control the threshold at which the stack checking routine is called or not called.
|
||||
append_c_and_cxx_flags("-Qoption,cpp,--extended_float_types") # Enabled _Quad type.
|
||||
if(${IA32})
|
||||
append_c_and_cxx_flags("-arch:ia32") # Tells the compiler which features it may target (ia32)
|
||||
append_c_and_cxx_flags("-Oy-") # equivalent to -fno-omit-frame-pointer
|
||||
endif()
|
||||
append_c_and_cxx_flags("-Qlong_double") # enable long double
|
||||
append_c_and_cxx_flags("-Qdiag-disable:177") # Disable warning: "... declared but never referenced"
|
||||
if(${IA32})
|
||||
append_c_and_cxx_flags("-Qsafeseh") # Registers exception handlers for safe exception handling.
|
||||
endif()
|
||||
if(${RELEASE_BUILD} OR ${RELWITHDEBINFO_BUILD})
|
||||
append_c_and_cxx_flags("-Qinline-min-size=1") # Specifies the upper limit for the size of what the inliner considers to be a small routine.
|
||||
else()
|
||||
append_c_and_cxx_flags("-Od") # Disables all optimizations.
|
||||
append_c_and_cxx_flags("-RTC1") # Enables run-time checks of the stack frame, and enables run-time checks for unintialized variables.
|
||||
append_c_and_cxx_flags("-MTd") # Tells the linker to search for unresolved references in a multithreaded, static run-time library.
|
||||
endif()
|
||||
else()
|
||||
append_c_and_cxx_flags("-Wsign-compare") # warn on sign comparisons
|
||||
append_c_and_cxx_flags("-Werror") # Changes all warnings to errors.
|
||||
append_c_and_cxx_flags("-Qoption,cpp,--extended_float_types") # Enabled _Quad type.
|
||||
append_c_and_cxx_flags("-fno-exceptions") # Exception handling table generation is disabled.
|
||||
append_c_and_cxx_flags("-x c++") # Compile C files as C++ files
|
||||
if(${MIC})
|
||||
append_c_and_cxx_flags("-mmic") # Build Intel(R) MIC Architecture native code
|
||||
append_c_and_cxx_flags("-ftls-model=initial-exec") # Changes the thread local storage (TLS) model. Generates a restrictive, optimized TLS code.
|
||||
# To use this setting, the thread-local variables accessed must be defined in one of the
|
||||
# modules available to the program.
|
||||
append_c_and_cxx_flags("-opt-streaming-stores never") # Disables generation of streaming stores for optimization.
|
||||
append_c_and_cxx_flags("-sox") # Tells the compiler to save the compilation options and version number
|
||||
# in the executable file. It also lets you choose whether to include
|
||||
# lists of certain functions.
|
||||
elseif(${LINUX})
|
||||
append_c_and_cxx_flags("-Werror") # Changes all warnings to errors.
|
||||
append_c_and_cxx_flags("-sox")
|
||||
if(${IA32})
|
||||
append_c_and_cxx_flags("-falign-stack=maintain-16-byte") # Tells the compiler the stack alignment to use on entry to routines.
|
||||
append_c_and_cxx_flags("-mia32") # Tells the compiler which features it may target (ia32)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
# CMake prefers the /MD flags when compiling Windows sources, but libiomp5 needs to use /MT instead
|
||||
# So we replace these /MD instances with /MT within the CMAKE_*_FLAGS variables and put that out to the CACHE.
|
||||
# replace_md_with_mt() is in HelperFunctions.cmake
|
||||
if(${WINDOWS})
|
||||
replace_md_with_mt(CMAKE_C_FLAGS)
|
||||
replace_md_with_mt(CMAKE_C_FLAGS_RELEASE)
|
||||
replace_md_with_mt(CMAKE_C_FLAGS_RELWITHDEBINFO)
|
||||
replace_md_with_mt(CMAKE_C_FLAGS_DEBUG)
|
||||
replace_md_with_mt(CMAKE_CXX_FLAGS)
|
||||
replace_md_with_mt(CMAKE_CXX_FLAGS_RELEASE)
|
||||
replace_md_with_mt(CMAKE_CXX_FLAGS_RELWITHDEBINFO)
|
||||
replace_md_with_mt(CMAKE_CXX_FLAGS_DEBUG)
|
||||
endif()
|
||||
set(${input_c_flags} ${${input_c_flags}} "${local_c_flags}" PARENT_SCOPE)
|
||||
set(${input_cxx_flags} ${${input_cxx_flags}} "${local_cxx_flags}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
#########################################################
|
||||
# icc Linker flags
|
||||
function(append_compiler_specific_linker_flags input_ld_flags input_ld_flags_libs)
|
||||
set(local_ld_flags)
|
||||
set(local_ld_flags_libs)
|
||||
if(${WINDOWS})
|
||||
# Have icc use link.exe directly when Windows
|
||||
set(CMAKE_C_CREATE_SHARED_LIBRARY "link.exe /out:<TARGET> <LINK_FLAGS> <OBJECTS> <LINK_LIBRARIES>" PARENT_SCOPE)
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "$ENV{LDFLAGS}" CACHE STRING "Linker Flags" FORCE)
|
||||
append_linker_flags("-nologo") # Turn off tool banner.
|
||||
append_linker_flags("-dll")
|
||||
append_linker_flags("-WX:NO")
|
||||
append_linker_flags("-incremental:no")
|
||||
append_linker_flags("-version:${version}.0")
|
||||
append_linker_flags("-NXCompat")
|
||||
append_linker_flags("-DynamicBase") # This option modifies the header of an executable to indicate
|
||||
# whether the application should be randomly rebased at load time.
|
||||
if(${IA32})
|
||||
append_linker_flags("-machine:i386")
|
||||
append_linker_flags("-safeseh")
|
||||
elseif(${INTEL64})
|
||||
append_linker_flags("-machine:amd64")
|
||||
endif()
|
||||
if(${DEBUG_BUILD} OR ${RELWITHDEBINFO_BUILD})
|
||||
if(NOT "${pdb_file}" STREQUAL "")
|
||||
append_linker_flags("-debug")
|
||||
append_linker_flags("-pdb:${pdb_file}")
|
||||
endif()
|
||||
else()
|
||||
if(NOT "${pdb_file}" STREQUAL "")
|
||||
append_linker_flags("-debug")
|
||||
append_linker_flags("-pdb:${pdb_file}")
|
||||
append_linker_flags("-pdbstripped:${pdb_file}.stripped")
|
||||
endif()
|
||||
endif()
|
||||
if(NOT "${imp_file}" STREQUAL "")
|
||||
append_linker_flags("-implib:${lib_file}${lib}")
|
||||
endif()
|
||||
if(NOT "${def_file}" STREQUAL "")
|
||||
append_linker_flags("-def:${def_file}")
|
||||
endif()
|
||||
elseif(${MAC})
|
||||
append_linker_flags("-no-intel-extensions")
|
||||
if(NOT ${STUBS_LIBRARY})
|
||||
append_linker_flags_library("-pthread") # link in pthread library
|
||||
append_linker_flags_library("-ldl") # link in libdl (dynamic loader library)
|
||||
endif()
|
||||
if(${STATS_GATHERING})
|
||||
append_linker_flags_library("-Wl,-lstdc++") # link in standard c++ library (stats-gathering needs it)
|
||||
endif()
|
||||
elseif(${MIC})
|
||||
append_linker_flags("-mmic") # enable MIC linking
|
||||
append_linker_flags("-static-intel") # Causes Intel-provided libraries to be linked in statically.
|
||||
append_linker_flags("-no-intel-extensions") # Enables or disables all Intel C and Intel C++ language extensions.
|
||||
else()
|
||||
append_linker_flags("-static-intel") # Causes Intel-provided libraries to be linked in statically.
|
||||
append_linker_flags("-Werror") # Warnings become errors
|
||||
if(${IA32})
|
||||
append_linker_flags_library("-lirc_pic") # link in libirc_pic
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(${input_ld_flags} ${${input_ld_flags}} "${local_ld_flags}" PARENT_SCOPE)
|
||||
set(${input_ld_flags_libs} ${${input_ld_flags_libs}} "${local_ld_flags_libs}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
# This file holds Intel(R) C Compiler / Intel(R) C++ Compiler / Intel(R) Fortran Compiler (icc/icpc/icl.exe/ifort) dependent flags
|
||||
# The flag types are:
|
||||
# 1) Fortran Compiler flags
|
||||
|
||||
#########################################################
|
||||
# icc Fortran Compiler flags (for creating .mod files)
|
||||
function(append_fortran_compiler_specific_fort_flags input_fort_flags)
|
||||
set(local_fort_flags)
|
||||
#set(CMAKE_Fortran_FLAGS "$ENV{FFLAGS}" CACHE STRING "Fortran flags" FORCE)
|
||||
#set(CMAKE_Fortran_FLAGS_RELEASE "" CACHE STRING "Fortran flags" FORCE)
|
||||
#set(CMAKE_Fortran_FLAGS_DEBUG "" CACHE STRING "Fortran flags" FORCE)
|
||||
#set(CMAKE_Fortran_FLAGS_RELWITHDEBINFO "" CACHE STRING "Fortran flags" FORCE)
|
||||
if(${WINDOWS})
|
||||
append_fort_flags("-Qdiag-disable:177,5082")
|
||||
append_fort_flags("-Qsox")
|
||||
append_fort_flags("-nologo")
|
||||
append_fort_flags("-GS")
|
||||
append_fort_flags("-DynamicBase")
|
||||
append_fort_flags("-Zi")
|
||||
else()
|
||||
if(${MIC})
|
||||
append_fort_flags("-mmic")
|
||||
endif()
|
||||
if(NOT ${MAC})
|
||||
append_fort_flags("-sox")
|
||||
endif()
|
||||
endif()
|
||||
set(${input_fort_flags} ${${input_fort_flags}} "${local_fort_flags}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
@@ -0,0 +1,26 @@
|
||||
# This file holds Microsoft Visual Studio dependent flags
|
||||
# The flag types are:
|
||||
# 1) Assembly flags
|
||||
|
||||
#########################################################
|
||||
# Assembly flags
|
||||
function(append_assembler_specific_asm_flags input_asm_flags)
|
||||
set(local_asm_flags)
|
||||
append_asm_flags("-nologo") # Turn off tool banner.
|
||||
if(${IA32})
|
||||
append_asm_flags("-safeseh") # Registers exception handlers for safe exception handling.
|
||||
append_asm_flags("-coff") # Generates common object file format (COFF) type of object module.
|
||||
# Generally required for Win32 assembly language development.
|
||||
append_asm_flags("-D _M_IA32")
|
||||
elseif(${INTEL64})
|
||||
append_asm_flags("-D _M_AMD64")
|
||||
endif()
|
||||
# CMake prefers the /MD flags when compiling Windows sources, but libiomp5 needs to use /MT instead
|
||||
# So we replace these /MD instances with /MT within the CMAKE_*_FLAGS variables and put that out to the CACHE.
|
||||
# replace_md_with_mt() is in HelperFunctions.cmake
|
||||
replace_md_with_mt(CMAKE_ASM_MASM_FLAGS)
|
||||
replace_md_with_mt(CMAKE_ASM_MASM_FLAGS_RELEASE)
|
||||
replace_md_with_mt(CMAKE_ASM_MASM_FLAGS_RELWITHDEBINFO)
|
||||
replace_md_with_mt(CMAKE_ASM_MASM_FLAGS_DEBUG)
|
||||
set(${input_asm_flags} ${${input_asm_flags}} "${local_asm_flags}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
@@ -0,0 +1,64 @@
|
||||
# This file holds Microsoft Visual Studio dependent flags
|
||||
# The flag types are:
|
||||
# 1) C/C++ Compiler flags
|
||||
# 2) Fortran Compiler flags
|
||||
|
||||
#########################################################
|
||||
# Visual Studio C/C++ Compiler flags
|
||||
function(append_compiler_specific_c_and_cxx_flags input_c_flags input_cxx_flags)
|
||||
set(local_c_flags)
|
||||
set(local_cxx_flags)
|
||||
append_c_flags("-TP") # Tells the compiler to process a file as a C++ source file.
|
||||
append_cxx_flags("-EHsc") # Enable C++ exception handling.
|
||||
append_c_and_cxx_flags("-W3") # Enables diagnostics for remarks, warnings, and errors.
|
||||
# Additional warnings are also enabled above level 2 warnings.
|
||||
append_c_and_cxx_flags("-GS") # Lets you control the threshold at which the stack checking routine is called or not called.
|
||||
if(${IA32})
|
||||
append_c_and_cxx_flags("-arch:ia32") # Tells the compiler which features it may target (ia32)
|
||||
append_c_and_cxx_flags("-Oy-") # equivalent to -fno-omit-frame-pointer
|
||||
endif()
|
||||
# CMake prefers the /MD flags when compiling Windows sources, but libiomp5 needs to use /MT instead
|
||||
# So we replace these /MD instances with /MT within the CMAKE_*_FLAGS variables and put that out to the CACHE.
|
||||
# replace_md_with_mt() is in HelperFunctions.cmake
|
||||
replace_md_with_mt(CMAKE_C_FLAGS)
|
||||
replace_md_with_mt(CMAKE_C_FLAGS_RELEASE)
|
||||
replace_md_with_mt(CMAKE_C_FLAGS_RELWITHDEBINFO)
|
||||
replace_md_with_mt(CMAKE_C_FLAGS_DEBUG)
|
||||
replace_md_with_mt(CMAKE_CXX_FLAGS)
|
||||
replace_md_with_mt(CMAKE_CXX_FLAGS_RELEASE)
|
||||
replace_md_with_mt(CMAKE_CXX_FLAGS_RELWITHDEBINFO)
|
||||
replace_md_with_mt(CMAKE_CXX_FLAGS_DEBUG)
|
||||
replace_md_with_mt(CMAKE_ASM_MASM_FLAGS)
|
||||
replace_md_with_mt(CMAKE_ASM_MASM_FLAGS_RELEASE)
|
||||
replace_md_with_mt(CMAKE_ASM_MASM_FLAGS_RELWITHDEBINFO)
|
||||
replace_md_with_mt(CMAKE_ASM_MASM_FLAGS_DEBUG)
|
||||
set(${input_c_flags} ${${input_c_flags}} "${local_c_flags}" PARENT_SCOPE)
|
||||
set(${input_cxx_flags} ${${input_cxx_flags}} "${local_cxx_flags}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
#########################################################
|
||||
# Visual Studio Linker flags
|
||||
function(append_compiler_specific_linker_flags input_ld_flags input_ld_flags_libs)
|
||||
set(local_ld_flags)
|
||||
set(local_ld_flags_libs)
|
||||
append_linker_flags("-WX:NO")
|
||||
append_linker_flags("-version:${version}.0")
|
||||
append_linker_flags("-NXCompat")
|
||||
append_linker_flags("-DynamicBase") # This option modifies the header of an executable to indicate
|
||||
# whether the application should be randomly rebased at load time.
|
||||
if(${IA32})
|
||||
append_linker_flags("-machine:i386")
|
||||
append_linker_flags("-safeseh")
|
||||
elseif(${INTEL64})
|
||||
append_linker_flags("-machine:amd64")
|
||||
endif()
|
||||
if(NOT "${def_file}" STREQUAL "")
|
||||
append_linker_flags("-def:${def_file}")
|
||||
endif()
|
||||
# Have Visual Studio use link.exe directly
|
||||
#set(CMAKE_C_CREATE_SHARED_LIBRARY "link.exe /out:<TARGET> <LINK_FLAGS> <OBJECTS> <LINK_LIBRARIES>" PARENT_SCOPE)
|
||||
#set(CMAKE_SHARED_LINKER_FLAGS "$ENV{LDLFAGS}" CACHE STRING "Linker Flags" FORCE)
|
||||
set(${input_ld_flags} ${${input_ld_flags}} "${local_ld_flags}" PARENT_SCOPE)
|
||||
set(${input_ld_flags_libs} ${${input_ld_flags_libs}} "${local_ld_flags_libs}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
@@ -0,0 +1,277 @@
|
||||
######################################################
|
||||
# MICRO TESTS
|
||||
# The following micro-tests are small tests to perform on
|
||||
# the library just created in ${build_dir}/, there are currently
|
||||
# five micro-tests:
|
||||
# (1) test-touch
|
||||
# - Compile and run a small program using newly created libiomp5 library
|
||||
# - Fails if test-touch.c does not compile or if test-touch.c does not run after compilation
|
||||
# - Program dependencies: gcc or g++, grep, bourne shell
|
||||
# - Available for all Linux,Mac,Windows builds. Not availble on Intel(R) MIC Architecture builds.
|
||||
# (2) test-relo
|
||||
# - Tests dynamic libraries for position-dependent code (can not have any position dependent code)
|
||||
# - Fails if TEXTREL is in output of readelf -d libiomp5.so command
|
||||
# - Program dependencies: readelf, grep, bourne shell
|
||||
# - Available for Linux, Intel(R) MIC Architecture dynamic library builds. Not available otherwise.
|
||||
# (3) test-execstack
|
||||
# - Tests if stack is executable
|
||||
# - Fails if stack is executable. Should only be readable and writable. Not exectuable.
|
||||
# - Program dependencies: perl, readelf
|
||||
# - Available for Linux dynamic library builds. Not available otherwise.
|
||||
# (4) test-instr (Intel(R) MIC Architecutre only)
|
||||
# - Tests Intel(R) MIC Architecture libraries for valid instruction set
|
||||
# - Fails if finds invalid instruction for Intel(R) MIC Architecture (wasn't compiled with correct flags)
|
||||
# - Program dependencies: perl, objdump
|
||||
# - Available for Intel(R) MIC Architecture builds. Not available otherwise.
|
||||
# (5) test-deps
|
||||
# - Tests newly created libiomp5 for library dependencies
|
||||
# - Fails if sees a dependence not listed in td_exp variable below
|
||||
# - Program dependencies: perl, (linux)readelf, (mac)otool[64], (windows)link.exe
|
||||
# - Available for Linux,Mac,Windows, Intel(R) MIC Architecture dynamic builds and Windows static builds. Not available otherwise.
|
||||
#
|
||||
# All tests can be turned off by including -Dtests=off when calling cmake
|
||||
# An individual test can be turned off by issuing something like -Dtest_touch=off when calling cmake
|
||||
|
||||
# test-touch
|
||||
if(NOT ${MIC} AND ${test_touch} AND ${tests})
|
||||
if(${WINDOWS})
|
||||
set(do_test_touch_mt TRUE)
|
||||
if(${do_test_touch_mt})
|
||||
set(test_touch_items ${test_touch_items} test-touch-md test-touch-mt)
|
||||
else()
|
||||
set(test_touch_items ${test_touch_items} test-touch-md)
|
||||
endif()
|
||||
else()
|
||||
set(test_touch_items ${test_touch_items} test-touch-rt)
|
||||
endif()
|
||||
set(regular_test_touch_items "${test_touch_items}")
|
||||
add_suffix("/.success" regular_test_touch_items)
|
||||
# test-touch : ${test_touch_items}/.success
|
||||
set(ldeps "${regular_test_touch_items}")
|
||||
add_custom_target( test-touch DEPENDS ${ldeps})
|
||||
|
||||
if(${WINDOWS})
|
||||
# pick test-touch compiler
|
||||
set(tt-c cl)
|
||||
# test-touch compilation flags
|
||||
list(APPEND tt-c-flags -nologo)
|
||||
if(${RELEASE_BUILD} OR ${RELWITHDEBINFO_BUILD})
|
||||
list(APPEND tt-c-flags-mt -MT)
|
||||
list(APPEND tt-c-flags-md -MD)
|
||||
else()
|
||||
list(APPEND tt-c-flags-mt -MTd)
|
||||
list(APPEND tt-c-flags-md -MDd)
|
||||
endif()
|
||||
list(APPEND tt-libs ${build_dir}/${imp_file})
|
||||
list(APPEND tt-ld-flags -link -nodefaultlib:oldnames)
|
||||
if(${IA32})
|
||||
list(APPEND tt-ld-flags -safeseh)
|
||||
endif()
|
||||
list(APPEND tt-ld-flags-v -verbose)
|
||||
else() # (Unix based systems, Intel(R) MIC Architecture, and Mac)
|
||||
# pick test-touch compiler
|
||||
if(${STD_CPP_LIB})
|
||||
set(tt-c ${CMAKE_CXX_COMPILER})
|
||||
else()
|
||||
set(tt-c ${CMAKE_C_COMPILER})
|
||||
endif()
|
||||
# test-touch compilation flags
|
||||
if(${LINUX})
|
||||
list(APPEND tt-c-flags -pthread)
|
||||
endif()
|
||||
if(${IA32})
|
||||
list(APPEND tt-c-flags -m32)
|
||||
elseif(${INTEL64})
|
||||
list(APPEND tt-c-flags -m64)
|
||||
endif()
|
||||
list(APPEND tt-libs ${build_dir}/${lib_file})
|
||||
if(${MAC})
|
||||
list(APPEND tt-ld-flags-v -Wl,-t)
|
||||
set(tt-env "DYLD_LIBRARY_PATH=.:$ENV{DYLD_LIBRARY_PATH}")
|
||||
else()
|
||||
list(APPEND tt-ld-flags-v -Wl,--verbose)
|
||||
set(tt-env LD_LIBRARY_PATH=".:${build_dir}:$ENV{LD_LIBRARY_PATH}")
|
||||
endif()
|
||||
endif()
|
||||
list(APPEND tt-c-flags "${tt-c-flags-rt}")
|
||||
list(APPEND tt-env "KMP_VERSION=1")
|
||||
|
||||
macro(test_touch_recipe test_touch_dir)
|
||||
file(MAKE_DIRECTORY ${build_dir}/${test_touch_dir})
|
||||
set(ldeps ${src_dir}/test-touch.c ${build_dir}/${lib_file})
|
||||
set(tt-exe-file ${test_touch_dir}/test-touch${exe})
|
||||
if(${WINDOWS})
|
||||
# ****** list(APPEND tt-c-flags -Fo$(dir $@)test-touch${obj} -Fe$(dir $@)test-touch${exe}) *******
|
||||
set(tt-c-flags-out -Fo${test_touch_dir}/test-touch${obj} -Fe${test_touch_dir}/test-touch${exe})
|
||||
list(APPEND ldeps ${build_dir}/${imp_file})
|
||||
else()
|
||||
# ****** list(APPEND tt-c-flags -o $(dir $@)test-touch${exe}) ********
|
||||
set(tt-c-flags-out -o ${test_touch_dir}/test-touch${exe})
|
||||
endif()
|
||||
add_custom_command(
|
||||
OUTPUT ${test_touch_dir}/.success
|
||||
COMMAND ${CMAKE_COMMAND} -E remove -f ${test_touch_dir}/*
|
||||
COMMAND ${tt-c} ${tt-c-flags-out} ${tt-c-flags} ${src_dir}/test-touch.c ${tt-libs} ${tt-ld-flags}
|
||||
COMMAND ${CMAKE_COMMAND} -E remove -f ${tt-exe-file}
|
||||
COMMAND ${tt-c} ${tt-c-flags-out} ${tt-c-flags} ${src_dir}/test-touch.c ${tt-libs} ${tt-ld-flags} ${tt-ld-flags-v} > ${test_touch_dir}/build.log 2>&1
|
||||
COMMAND ${tt-env} ${tt-exe-file}
|
||||
#COMMAND grep -i -e \"[^_]libirc\" ${test_touch_dir}/build.log > ${test_touch_dir}/libirc.log \; [ $$? -eq 1 ]
|
||||
COMMAND ${CMAKE_COMMAND} -E touch ${test_touch_dir}/.success
|
||||
DEPENDS ${ldeps}
|
||||
)
|
||||
endmacro()
|
||||
if(${WINDOWS})
|
||||
test_touch_recipe(test-touch-mt)
|
||||
test_touch_recipe(test-touch-md)
|
||||
else()
|
||||
test_touch_recipe(test-touch-rt)
|
||||
endif()
|
||||
else()
|
||||
add_custom_target(test-touch DEPENDS test-touch/.success)
|
||||
macro(test_touch_recipe_skip test_touch_dir)
|
||||
if(${tests} AND ${test_touch})
|
||||
set(test_touch_message 'test-touch is not available for the Intel(R) MIC Architecture. Will not perform it.')
|
||||
else()
|
||||
set(test_touch_message "test-touch is turned off. Will not perform it.")
|
||||
endif()
|
||||
add_custom_command(
|
||||
OUTPUT ${test_touch_dir}/.success
|
||||
COMMAND ${CMAKE_COMMAND} -E echo ${test_touch_message}
|
||||
)
|
||||
endmacro()
|
||||
test_touch_recipe_skip(test-touch-rt)
|
||||
test_touch_recipe_skip(test-touch-mt)
|
||||
test_touch_recipe_skip(test-touch-md)
|
||||
endif()
|
||||
|
||||
# test-relo
|
||||
add_custom_target(test-relo DEPENDS test-relo/.success)
|
||||
if((${LINUX} OR ${MIC}) AND ${test_relo} AND ${tests})
|
||||
file(MAKE_DIRECTORY ${build_dir}/test-relo)
|
||||
add_custom_command(
|
||||
OUTPUT test-relo/.success
|
||||
COMMAND readelf -d ${build_dir}/${lib_file} > test-relo/readelf.log
|
||||
COMMAND grep -e TEXTREL test-relo/readelf.log \; [ $$? -eq 1 ]
|
||||
COMMAND ${CMAKE_COMMAND} -E touch test-relo/.success
|
||||
DEPENDS ${build_dir}/${lib_file}
|
||||
)
|
||||
else()
|
||||
if(${tests} AND ${test_relo})
|
||||
set(test_relo_message 'test-relo is only available for dynamic library on Linux or Intel(R) MIC Architecture. Will not perform it.')
|
||||
else()
|
||||
set(test_relo_message "test-relo is turned off. Will not perform it.")
|
||||
endif()
|
||||
add_custom_command(
|
||||
OUTPUT test-relo/.success
|
||||
COMMAND ${CMAKE_COMMAND} -E echo ${test_relo_message}
|
||||
)
|
||||
endif()
|
||||
|
||||
# test-execstack
|
||||
add_custom_target(test-execstack DEPENDS test-execstack/.success)
|
||||
if(${LINUX} AND ${test_execstack} AND ${tests})
|
||||
file(MAKE_DIRECTORY ${build_dir}/test-execstack)
|
||||
add_custom_command(
|
||||
OUTPUT test-execstack/.success
|
||||
COMMAND ${PERL_EXECUTABLE} ${tools_dir}/check-execstack.pl ${build_dir}/${lib_file}
|
||||
COMMAND ${CMAKE_COMMAND} -E touch test-execstack/.success
|
||||
DEPENDS ${build_dir}/${lib_file}
|
||||
)
|
||||
else()
|
||||
if(${tests} AND ${test_execstack})
|
||||
set(test_execstack_message "test-execstack is only available for dynamic library on Linux. Will not perform it.")
|
||||
else()
|
||||
set(test_execstack_message "test-execstack is turned off. Will not perform it.")
|
||||
endif()
|
||||
add_custom_command(
|
||||
OUTPUT test-execstack/.success
|
||||
COMMAND ${CMAKE_COMMAND} -E echo ${test_execstack_message}
|
||||
)
|
||||
endif()
|
||||
|
||||
# test-instr
|
||||
add_custom_target(test-instr DEPENDS test-instr/.success)
|
||||
if(${MIC} AND ${test_instr} AND ${tests})
|
||||
file(MAKE_DIRECTORY ${build_dir}/test-instr)
|
||||
add_custom_command(
|
||||
OUTPUT test-instr/.success
|
||||
COMMAND ${PERL_EXECUTABLE} ${tools_dir}/check-instruction-set.pl ${oa_opts} --show --mic-arch=${mic_arch} --mic-os=${mic_os} ${build_dir}/${lib_file}
|
||||
COMMAND ${CMAKE_COMMAND} -E touch test-instr/.success
|
||||
DEPENDS ${build_dir}/${lib_file} ${tools_dir}/check-instruction-set.pl
|
||||
)
|
||||
else()
|
||||
if(${tests} AND ${test_instr})
|
||||
set(test_instr_message 'test-instr is only available for Intel(R) MIC Architecture libraries. Will not perform it.')
|
||||
else()
|
||||
set(test_instr_message "test-instr is turned off. Will not perform it.")
|
||||
endif()
|
||||
add_custom_command(
|
||||
OUTPUT test-instr/.success
|
||||
COMMAND ${CMAKE_COMMAND} -E echo ${test_instr_message}
|
||||
)
|
||||
endif()
|
||||
|
||||
# test-deps
|
||||
add_custom_target(test-deps DEPENDS test-deps/.success)
|
||||
if(${test_deps} AND ${tests})
|
||||
set(td_exp)
|
||||
if(${FREEBSD})
|
||||
set(td_exp libc.so.7 libthr.so.3 libunwind.so.5)
|
||||
elseif(${LINUX})
|
||||
set(td_exp libdl.so.2,libgcc_s.so.1)
|
||||
if(NOT ${IA32} AND NOT ${INTEL64})
|
||||
set(td_exp ${td_exp},libffi.so.6,libffi.so.5)
|
||||
endif()
|
||||
if(${IA32})
|
||||
set(td_exp ${td_exp},libc.so.6,ld-linux.so.2)
|
||||
elseif(${INTEL64})
|
||||
set(td_exp ${td_exp},libc.so.6,ld-linux-x86-64.so.2)
|
||||
elseif(${ARM})
|
||||
set(td_exp ${td_exp},libc.so.6,ld-linux-armhf.so.3)
|
||||
endif()
|
||||
if(${STD_CPP_LIB})
|
||||
set(td_exp ${td_exp},libstdc++.so.6)
|
||||
endif()
|
||||
if(NOT ${STUBS_LIBRARY})
|
||||
set(td_exp ${td_exp},libpthread.so.0)
|
||||
endif()
|
||||
elseif(${MIC})
|
||||
if("${mic_os}" STREQUAL "lin")
|
||||
set(td_exp libc.so.6,libpthread.so.0,libdl.so.2)
|
||||
if(${STD_CPP_LIB})
|
||||
set(td_exp ${td_exp},libstdc++.so.6)
|
||||
endif()
|
||||
if("${mic_arch}" STREQUAL "knf")
|
||||
set(td_exp ${td_exp},ld-linux-l1om.so.2,libgcc_s.so.1)
|
||||
elseif("${mic_arch}" STREQUAL "knc")
|
||||
set(td_exp ${td_exp},ld-linux-k1om.so.2)
|
||||
endif()
|
||||
elseif("${mic_os}" STREQUAL "bsd")
|
||||
set(td_exp libc.so.7,libthr.so.3,libunwind.so.5)
|
||||
endif()
|
||||
elseif(${MAC})
|
||||
set(td_exp /usr/lib/libSystem.B.dylib)
|
||||
elseif(${WINDOWS})
|
||||
set(td_exp kernel32.dll)
|
||||
endif()
|
||||
|
||||
file(MAKE_DIRECTORY ${build_dir}/test-deps)
|
||||
add_custom_command(
|
||||
OUTPUT test-deps/.success
|
||||
COMMAND ${PERL_EXECUTABLE} ${tools_dir}/check-depends.pl ${oa_opts} --expected="${td_exp}" ${build_dir}/${lib_file}
|
||||
COMMAND ${CMAKE_COMMAND} -E touch test-deps/.success
|
||||
DEPENDS ${build_dir}/${lib_file} ${tools_dir}/check-depends.pl
|
||||
)
|
||||
else()
|
||||
if(${tests} AND ${test_deps})
|
||||
set(test_deps_message 'test-deps is available for dynamic libraries on Linux, Mac, Intel(R) MIC Architecture, Windows and static libraries on Windows. Will not perform it.')
|
||||
else()
|
||||
set(test_deps_message "test-deps is turned off. Will not perform it.")
|
||||
endif()
|
||||
add_custom_command(
|
||||
OUTPUT test-deps/.success
|
||||
COMMAND ${CMAKE_COMMAND} -E echo ${test_deps_message}
|
||||
)
|
||||
endif()
|
||||
# END OF TESTS
|
||||
######################################################
|
||||
@@ -0,0 +1,90 @@
|
||||
#
|
||||
#//===----------------------------------------------------------------------===//
|
||||
#//
|
||||
#// 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 append_ev_flags(string new_flag);
|
||||
# - appends new_flag to ev_flags list
|
||||
macro(append_ev_flags new_flag)
|
||||
list(APPEND local_ev_flags "${new_flag}")
|
||||
endmacro()
|
||||
|
||||
# void append_gd_flags(string new_flag);
|
||||
# - appends new_flag to gd_flags list
|
||||
macro(append_gd_flags new_flag)
|
||||
list(APPEND local_gd_flags "${new_flag}")
|
||||
endmacro()
|
||||
|
||||
include(HelperFunctions) # for set_legal_type(), set_legal_arch()
|
||||
|
||||
# Perl expand-vars.pl flags
|
||||
function(set_ev_flags input_ev_flags)
|
||||
set(local_ev_flags)
|
||||
set_legal_type("${lib_type}" legal_type)
|
||||
set_legal_arch("${arch}" legal_arch)
|
||||
# need -D Revision="\$Revision" to show up
|
||||
append_ev_flags("-D Revision=\"\\\\$$Revision\"")
|
||||
append_ev_flags("-D Date=\"\\\\$$Date\"")
|
||||
append_ev_flags("-D KMP_TYPE=\"${legal_type}\"")
|
||||
append_ev_flags("-D KMP_ARCH=\"${legal_arch}\"")
|
||||
append_ev_flags("-D KMP_VERSION_MAJOR=${version}")
|
||||
append_ev_flags("-D KMP_VERSION_MINOR=0")
|
||||
append_ev_flags("-D KMP_VERSION_BUILD=${build_number}")
|
||||
append_ev_flags("-D KMP_BUILD_DATE=\"${date}\"")
|
||||
append_ev_flags("-D KMP_TARGET_COMPILER=12")
|
||||
if(${DEBUG_BUILD} OR ${RELWITHDEBINFO_BUILD})
|
||||
append_ev_flags("-D KMP_DIAG=1")
|
||||
append_ev_flags("-D KMP_DEBUG_INFO=1")
|
||||
else()
|
||||
append_ev_flags("-D KMP_DIAG=0")
|
||||
append_ev_flags("-D KMP_DEBUG_INFO=0")
|
||||
endif()
|
||||
if(${omp_version} EQUAL 40)
|
||||
append_ev_flags("-D OMP_VERSION=201307")
|
||||
elseif(${omp_version} EQUAL 30)
|
||||
append_ev_flags("-D OMP_VERSION=201107")
|
||||
else()
|
||||
append_ev_flags("-D OMP_VERSION=200505")
|
||||
endif()
|
||||
set(${input_ev_flags} "${local_ev_flags}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(set_gd_flags input_gd_flags)
|
||||
set(local_gd_flags)
|
||||
if(${IA32})
|
||||
append_gd_flags("-D arch_32")
|
||||
elseif(${INTEL64})
|
||||
append_gd_flags("-D arch_32e")
|
||||
else()
|
||||
append_gd_flags("-D arch_${arch}")
|
||||
endif()
|
||||
if(${NORMAL_LIBRARY})
|
||||
append_gd_flags("-D norm")
|
||||
elseif(${PROFILE_LIBRARY})
|
||||
append_gd_flags("-D prof")
|
||||
elseif(${STUBS_LIBRARY})
|
||||
append_gd_flags("-D stub")
|
||||
endif()
|
||||
if(${omp_version} GREATER 40 OR ${omp_version} EQUAL 40)
|
||||
append_gd_flags("-D OMP_40")
|
||||
endif()
|
||||
if(${omp_version} GREATER 30 OR ${omp_version} EQUAL 30)
|
||||
append_gd_flags("-D OMP_30")
|
||||
endif()
|
||||
if(NOT "${version}" STREQUAL "4")
|
||||
append_gd_flags("-D msvc_compat")
|
||||
endif()
|
||||
if(${DEBUG_BUILD} OR ${RELWITHDEBINFO_BUILD})
|
||||
append_gd_flags("-D KMP_DEBUG")
|
||||
endif()
|
||||
if(${COMPILER_SUPPORTS_QUAD_PRECISION})
|
||||
append_gd_flags("-D HAVE_QUAD")
|
||||
endif()
|
||||
set(${input_gd_flags} "${local_gd_flags}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
@@ -0,0 +1,110 @@
|
||||
#
|
||||
#//===----------------------------------------------------------------------===//
|
||||
#//
|
||||
#// 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.
|
||||
#//
|
||||
#//===----------------------------------------------------------------------===//
|
||||
#
|
||||
|
||||
macro(append_c_source_file new_c_file)
|
||||
list(APPEND local_c_source_files "${new_c_file}")
|
||||
endmacro()
|
||||
|
||||
macro(append_cpp_source_file new_cpp_file)
|
||||
list(APPEND local_cpp_source_files "${new_cpp_file}")
|
||||
endmacro()
|
||||
|
||||
macro(append_asm_source_file new_asm_file)
|
||||
list(APPEND local_asm_source_files "${new_asm_file}")
|
||||
endmacro()
|
||||
|
||||
macro(append_imp_c_source_file new_import_c_file)
|
||||
list(APPEND local_imp_c_files "${new_import_c_file}")
|
||||
endmacro()
|
||||
|
||||
# files are relative to the src directory
|
||||
|
||||
function(set_c_files input_c_source_files)
|
||||
set(local_c_source_files "")
|
||||
append_c_source_file("kmp_ftn_cdecl.c")
|
||||
append_c_source_file("kmp_ftn_extra.c")
|
||||
append_c_source_file("kmp_version.c")
|
||||
if(${STUBS_LIBRARY})
|
||||
append_c_source_file("kmp_stub.c")
|
||||
else()
|
||||
append_c_source_file("kmp_alloc.c")
|
||||
append_c_source_file("kmp_atomic.c")
|
||||
append_c_source_file("kmp_csupport.c")
|
||||
append_c_source_file("kmp_debug.c")
|
||||
append_c_source_file("kmp_itt.c")
|
||||
append_c_source_file("kmp_environment.c")
|
||||
append_c_source_file("kmp_error.c")
|
||||
append_c_source_file("kmp_global.c")
|
||||
append_c_source_file("kmp_i18n.c")
|
||||
append_c_source_file("kmp_io.c")
|
||||
append_c_source_file("kmp_runtime.c")
|
||||
append_c_source_file("kmp_settings.c")
|
||||
append_c_source_file("kmp_str.c")
|
||||
append_c_source_file("kmp_tasking.c")
|
||||
append_c_source_file("kmp_taskq.c")
|
||||
append_c_source_file("kmp_threadprivate.c")
|
||||
append_c_source_file("kmp_utility.c")
|
||||
if(${USE_ITT_NOTIFY})
|
||||
append_c_source_file("thirdparty/ittnotify/ittnotify_static.c")
|
||||
endif()
|
||||
if(${WINDOWS})
|
||||
append_c_source_file("z_Windows_NT_util.c")
|
||||
append_c_source_file("z_Windows_NT-586_util.c")
|
||||
else()
|
||||
append_c_source_file("z_Linux_util.c")
|
||||
append_c_source_file("kmp_gsupport.c")
|
||||
endif()
|
||||
endif()
|
||||
set(${input_c_source_files} "${local_c_source_files}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(set_cpp_files input_cpp_source_files)
|
||||
set(local_cpp_source_files "")
|
||||
if(NOT ${STUBS_LIBRARY})
|
||||
#append_cpp_source_file("kmp_barrier.cpp")
|
||||
append_cpp_source_file("kmp_affinity.cpp")
|
||||
append_cpp_source_file("kmp_dispatch.cpp")
|
||||
append_cpp_source_file("kmp_lock.cpp")
|
||||
append_cpp_source_file("kmp_sched.cpp")
|
||||
if("${omp_version}" STREQUAL "40")
|
||||
append_cpp_source_file("kmp_taskdeps.cpp")
|
||||
append_cpp_source_file("kmp_cancel.cpp")
|
||||
endif()
|
||||
#if(${STATS_GATHERING})
|
||||
# append_cpp_source_file("kmp_stats.cpp")
|
||||
# append_cpp_source_file("kmp_stats_timing.cpp")
|
||||
#endif()
|
||||
endif()
|
||||
|
||||
set(${input_cpp_source_files} "${local_cpp_source_files}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
|
||||
function(set_asm_files input_asm_source_files)
|
||||
set(local_asm_source_files "")
|
||||
if(NOT ${STUBS_LIBRARY})
|
||||
if(${WINDOWS})
|
||||
append_asm_source_file("z_Windows_NT-586_asm.asm")
|
||||
else()
|
||||
append_asm_source_file("z_Linux_asm.s")
|
||||
endif()
|
||||
endif()
|
||||
set(${input_asm_source_files} "${local_asm_source_files}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
|
||||
function(set_imp_c_files input_imp_c_files)
|
||||
set(local_imp_c_files "")
|
||||
if(${WINDOWS})
|
||||
append_imp_c_source_file("kmp_import.c")
|
||||
endif()
|
||||
set(${input_imp_c_files} "${local_imp_c_files}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,92 @@
|
||||
% Latex header for doxygen 1.8.3.1
|
||||
\documentclass{book}
|
||||
\usepackage[a4paper,top=2.5cm,bottom=2.5cm,left=2.5cm,right=2.5cm]{geometry}
|
||||
\usepackage{makeidx}
|
||||
\usepackage{natbib}
|
||||
\usepackage{graphicx}
|
||||
\usepackage{multicol}
|
||||
\usepackage{float}
|
||||
\usepackage{listings}
|
||||
\usepackage{color}
|
||||
\usepackage{ifthen}
|
||||
\usepackage[table]{xcolor}
|
||||
\usepackage{textcomp}
|
||||
\usepackage{alltt}
|
||||
\usepackage{ifpdf}
|
||||
\ifpdf
|
||||
\usepackage[pdftex,
|
||||
pagebackref=true,
|
||||
colorlinks=true,
|
||||
linkcolor=blue,
|
||||
unicode
|
||||
]{hyperref}
|
||||
\else
|
||||
\usepackage[ps2pdf,
|
||||
pagebackref=true,
|
||||
colorlinks=true,
|
||||
linkcolor=blue,
|
||||
unicode
|
||||
]{hyperref}
|
||||
\usepackage{pspicture}
|
||||
\fi
|
||||
\usepackage[utf8]{inputenc}
|
||||
\usepackage{mathptmx}
|
||||
\usepackage[scaled=.90]{helvet}
|
||||
\usepackage{courier}
|
||||
\usepackage{sectsty}
|
||||
\usepackage{amssymb}
|
||||
\usepackage[titles]{tocloft}
|
||||
\usepackage{doxygen}
|
||||
\lstset{language=C++,inputencoding=utf8,basicstyle=\footnotesize,breaklines=true,breakatwhitespace=true,tabsize=4,numbers=left }
|
||||
\makeindex
|
||||
\setcounter{tocdepth}{3}
|
||||
\renewcommand{\footrulewidth}{0.4pt}
|
||||
\renewcommand{\familydefault}{\sfdefault}
|
||||
\hfuzz=15pt
|
||||
\setlength{\emergencystretch}{15pt}
|
||||
\hbadness=750
|
||||
\tolerance=750
|
||||
\begin{document}
|
||||
\hypersetup{pageanchor=false,citecolor=blue}
|
||||
\begin{titlepage}
|
||||
\vspace*{7cm}
|
||||
\begin{center}
|
||||
{\Large Intel\textsuperscript{\textregistered} OpenMP\textsuperscript{*} Runtime Library }\\
|
||||
\vspace*{1cm}
|
||||
{\large Generated by Doxygen $doxygenversion }\\
|
||||
\vspace*{0.5cm}
|
||||
{\small $datetime }\\
|
||||
\end{center}
|
||||
\end{titlepage}
|
||||
|
||||
{\bf FTC Optimization Notice}
|
||||
\\
|
||||
Intel's compilers may or may not optimize to the same degree for non-Intel microprocessors for
|
||||
optimizations that are not unique to Intel microprocessors. These optimizations include SSE2,
|
||||
SSE3, and SSE3 instruction sets and other optimizations. Intel does not guarantee the
|
||||
availability, functionality, or effectiveness of any optimization on microprocessors not
|
||||
manufactured by Intel.
|
||||
|
||||
Microprocessor-dependent optimizations in this product are intended for use with Intel
|
||||
microprocessors. Certain optimizations not specific to Intel microarchitecture are reserved for
|
||||
Intel microprocessors. Please refer to the applicable product User and Reference Guides for
|
||||
more information regarding the specific instruction sets covered by this notice.
|
||||
|
||||
Notice revision \#20110804
|
||||
|
||||
{\bf Trademarks}
|
||||
\\
|
||||
Intel, Xeon, and Intel Xeon Phi are trademarks of Intel Corporation in the U.S. and/or other countries.
|
||||
|
||||
\textsuperscript{*} Other names and brands may be claimed as the property of others.
|
||||
|
||||
The OpenMP name and the OpenMP logo are registered trademarks of the OpenMP Architecture Review Board.
|
||||
|
||||
This document is Copyright \textcopyright 2013, Intel Corporation. All rights reserved.
|
||||
|
||||
\clearemptydoublepage
|
||||
\pagenumbering{roman}
|
||||
\tableofcontents
|
||||
\clearemptydoublepage
|
||||
\pagenumbering{arabic}
|
||||
\hypersetup{pageanchor=true,citecolor=blue}
|
||||
@@ -0,0 +1,326 @@
|
||||
// This file does not contain any code; it just contains additional text and formatting
|
||||
// for doxygen.
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
/*! @mainpage Intel® OpenMP* Runtime Library Interface
|
||||
@section sec_intro Introduction
|
||||
|
||||
This document describes the interface provided by the
|
||||
Intel® OpenMP\other runtime library to the compiler.
|
||||
Routines that are directly called as simple functions by user code are
|
||||
not currently described here, since their definition is in the OpenMP
|
||||
specification available from http://openmp.org
|
||||
|
||||
The aim here is to explain the interface from the compiler to the runtime.
|
||||
|
||||
The overall design is described, and each function in the interface
|
||||
has its own description. (At least, that's the ambition, we may not be there yet).
|
||||
|
||||
@section sec_building Building the Runtime
|
||||
For the impatient, we cover building the runtime as the first topic here.
|
||||
|
||||
A top-level Makefile is provided that attempts to derive a suitable
|
||||
configuration for the most commonly used environments. To see the
|
||||
default settings, type:
|
||||
@code
|
||||
% make info
|
||||
@endcode
|
||||
|
||||
You can change the Makefile's behavior with the following options:
|
||||
|
||||
- <b>omp_root</b>: The path to the top-level directory containing the top-level
|
||||
Makefile. By default, this will take on the value of the
|
||||
current working directory.
|
||||
|
||||
- <b>omp_os</b>: Operating system. By default, the build will attempt to
|
||||
detect this. Currently supports "linux", "macos", and
|
||||
"windows".
|
||||
|
||||
- <b>arch</b>: Architecture. By default, the build will attempt to
|
||||
detect this if not specified by the user. Currently
|
||||
supported values are
|
||||
- "32" for IA-32 architecture
|
||||
- "32e" for Intel® 64 architecture
|
||||
- "mic" for Intel® Many Integrated Core Architecture (
|
||||
If "mic" is specified then "icc" will be used as the
|
||||
compiler, and appropriate k1om binutils will be used. The
|
||||
necessary packages must be installed on the build machine
|
||||
for this to be possible, but an
|
||||
Intel® Xeon Phi™
|
||||
coprocessor is not required to build the library).
|
||||
|
||||
- <b>compiler</b>: Which compiler to use for the build. Defaults to "icc"
|
||||
or "icl" depending on the value of omp_os. Also supports
|
||||
"gcc" when omp_os is "linux" for gcc\other versions
|
||||
4.6.2 and higher. For icc on OS X\other, OS X\other versions
|
||||
greater than 10.6 are not supported currently. Also, icc
|
||||
version 13.0 is not supported. The selected compiler should be
|
||||
installed and in the user's path. The corresponding
|
||||
Fortran compiler should also be in the path.
|
||||
|
||||
- <b>mode</b>: Library mode: default is "release". Also supports "debug".
|
||||
|
||||
To use any of the options above, simple add <option_name>=<value>. For
|
||||
example, if you want to build with gcc instead of icc, type:
|
||||
@code
|
||||
% make compiler=gcc
|
||||
@endcode
|
||||
|
||||
Underneath the hood of the top-level Makefile, the runtime is built by
|
||||
a perl script that in turn drives a detailed runtime system make. The
|
||||
script can be found at <tt>tools/build.pl</tt>, and will print
|
||||
information about all its flags and controls if invoked as
|
||||
@code
|
||||
% tools/build.pl --help
|
||||
@endcode
|
||||
|
||||
If invoked with no arguments, it will try to build a set of libraries
|
||||
that are appropriate for the machine on which the build is happening.
|
||||
There are many options for building out of tree, and configuring library
|
||||
features that can also be used. Consult the <tt>--help</tt> output for details.
|
||||
|
||||
@section sec_supported Supported RTL Build Configurations
|
||||
|
||||
The architectures supported are IA-32 architecture, Intel® 64, and
|
||||
Intel® Many Integrated Core Architecture. The build configurations
|
||||
supported are shown in the table below.
|
||||
|
||||
<table border=1>
|
||||
<tr><th> <th>icc/icl<th>gcc
|
||||
<tr><td>Linux\other OS<td>Yes(1,5)<td>Yes(2,4)
|
||||
<tr><td>OS X\other<td>Yes(1,3,4)<td>No
|
||||
<tr><td>Windows\other OS<td>Yes(1,4)<td>No
|
||||
</table>
|
||||
(1) On IA-32 architecture and Intel® 64, icc/icl versions 12.x
|
||||
are supported (12.1 is recommended).<br>
|
||||
(2) gcc version 4.6.2 is supported.<br>
|
||||
(3) For icc on OS X\other, OS X\other version 10.5.8 is supported.<br>
|
||||
(4) Intel® Many Integrated Core Architecture not supported.<br>
|
||||
(5) On Intel® Many Integrated Core Architecture, icc/icl versions 13.0 or later are required.
|
||||
|
||||
@section sec_frontend Front-end Compilers that work with this RTL
|
||||
|
||||
The following compilers are known to do compatible code generation for
|
||||
this RTL: icc/icl, gcc. Code generation is discussed in more detail
|
||||
later in this document.
|
||||
|
||||
@section sec_outlining Outlining
|
||||
|
||||
The runtime interface is based on the idea that the compiler
|
||||
"outlines" sections of code that are to run in parallel into separate
|
||||
functions that can then be invoked in multiple threads. For instance,
|
||||
simple code like this
|
||||
|
||||
@code
|
||||
void foo()
|
||||
{
|
||||
#pragma omp parallel
|
||||
{
|
||||
... do something ...
|
||||
}
|
||||
}
|
||||
@endcode
|
||||
is converted into something that looks conceptually like this (where
|
||||
the names used are merely illustrative; the real library function
|
||||
names will be used later after we've discussed some more issues...)
|
||||
|
||||
@code
|
||||
static void outlinedFooBody()
|
||||
{
|
||||
... do something ...
|
||||
}
|
||||
|
||||
void foo()
|
||||
{
|
||||
__OMP_runtime_fork(outlinedFooBody, (void*)0); // Not the real function name!
|
||||
}
|
||||
@endcode
|
||||
|
||||
@subsection SEC_SHAREDVARS Addressing shared variables
|
||||
|
||||
In real uses of the OpenMP\other API there are normally references
|
||||
from the outlined code to shared variables that are in scope in the containing function.
|
||||
Therefore the containing function must be able to address
|
||||
these variables. The runtime supports two alternate ways of doing
|
||||
this.
|
||||
|
||||
@subsubsection SEC_SEC_OT Current Technique
|
||||
The technique currently supported by the runtime library is to receive
|
||||
a separate pointer to each shared variable that can be accessed from
|
||||
the outlined function. This is what is shown in the example below.
|
||||
|
||||
We hope soon to provide an alternative interface to support the
|
||||
alternate implementation described in the next section. The
|
||||
alternative implementation has performance advantages for small
|
||||
parallel regions that have many shared variables.
|
||||
|
||||
@subsubsection SEC_SEC_PT Future Technique
|
||||
The idea is to treat the outlined function as though it
|
||||
were a lexically nested function, and pass it a single argument which
|
||||
is the pointer to the parent's stack frame. Provided that the compiler
|
||||
knows the layout of the parent frame when it is generating the outlined
|
||||
function it can then access the up-level variables at appropriate
|
||||
offsets from the parent frame. This is a classical compiler technique
|
||||
from the 1960s to support languages like Algol (and its descendants)
|
||||
that support lexically nested functions.
|
||||
|
||||
The main benefit of this technique is that there is no code required
|
||||
at the fork point to marshal the arguments to the outlined function.
|
||||
Since the runtime knows statically how many arguments must be passed to the
|
||||
outlined function, it can easily copy them to the thread's stack
|
||||
frame. Therefore the performance of the fork code is independent of
|
||||
the number of shared variables that are accessed by the outlined
|
||||
function.
|
||||
|
||||
If it is hard to determine the stack layout of the parent while generating the
|
||||
outlined code, it is still possible to use this approach by collecting all of
|
||||
the variables in the parent that are accessed from outlined functions into
|
||||
a single `struct` which is placed on the stack, and whose address is passed
|
||||
to the outlined functions. In this way the offsets of the shared variables
|
||||
are known (since they are inside the struct) without needing to know
|
||||
the complete layout of the parent stack-frame. From the point of view
|
||||
of the runtime either of these techniques is equivalent, since in either
|
||||
case it only has to pass a single argument to the outlined function to allow
|
||||
it to access shared variables.
|
||||
|
||||
A scheme like this is how gcc\other generates outlined functions.
|
||||
|
||||
@section SEC_INTERFACES Library Interfaces
|
||||
The library functions used for specific parts of the OpenMP\other language implementation
|
||||
are documented in different modules.
|
||||
|
||||
- @ref BASIC_TYPES fundamental types used by the runtime in many places
|
||||
- @ref DEPRECATED functions that are in the library but are no longer required
|
||||
- @ref STARTUP_SHUTDOWN functions for initializing and finalizing the runtime
|
||||
- @ref PARALLEL functions for implementing `omp parallel`
|
||||
- @ref THREAD_STATES functions for supporting thread state inquiries
|
||||
- @ref WORK_SHARING functions for work sharing constructs such as `omp for`, `omp sections`
|
||||
- @ref THREADPRIVATE functions to support thread private data, copyin etc
|
||||
- @ref SYNCHRONIZATION functions to support `omp critical`, `omp barrier`, `omp master`, reductions etc
|
||||
- @ref ATOMIC_OPS functions to support atomic operations
|
||||
- Documentation on tasking has still to be written...
|
||||
|
||||
@section SEC_EXAMPLES Examples
|
||||
@subsection SEC_WORKSHARING_EXAMPLE Work Sharing Example
|
||||
This example shows the code generated for a parallel for with reduction and dynamic scheduling.
|
||||
|
||||
@code
|
||||
extern float foo( void );
|
||||
|
||||
int main () {
|
||||
int i;
|
||||
float r = 0.0;
|
||||
#pragma omp parallel for schedule(dynamic) reduction(+:r)
|
||||
for ( i = 0; i < 10; i ++ ) {
|
||||
r += foo();
|
||||
}
|
||||
}
|
||||
@endcode
|
||||
|
||||
The transformed code looks like this.
|
||||
@code
|
||||
extern float foo( void );
|
||||
|
||||
int main () {
|
||||
static int zero = 0;
|
||||
auto int gtid;
|
||||
auto float r = 0.0;
|
||||
__kmpc_begin( & loc3, 0 );
|
||||
// The gtid is not actually required in this example so could be omitted;
|
||||
// We show its initialization here because it is often required for calls into
|
||||
// the runtime and should be locally cached like this.
|
||||
gtid = __kmpc_global thread num( & loc3 );
|
||||
__kmpc_fork call( & loc7, 1, main_7_parallel_3, & r );
|
||||
__kmpc_end( & loc0 );
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct main_10_reduction_t_5 { float r_10_rpr; };
|
||||
|
||||
static kmp_critical_name lck = { 0 };
|
||||
static ident_t loc10; // loc10.flags should contain KMP_IDENT_ATOMIC_REDUCE bit set
|
||||
// if compiler has generated an atomic reduction.
|
||||
|
||||
void main_7_parallel_3( int *gtid, int *btid, float *r_7_shp ) {
|
||||
auto int i_7_pr;
|
||||
auto int lower, upper, liter, incr;
|
||||
auto struct main_10_reduction_t_5 reduce;
|
||||
reduce.r_10_rpr = 0.F;
|
||||
liter = 0;
|
||||
__kmpc_dispatch_init_4( & loc7,*gtid, 35, 0, 9, 1, 1 );
|
||||
while ( __kmpc_dispatch_next_4( & loc7, *gtid, & liter, & lower, & upper, & incr ) ) {
|
||||
for( i_7_pr = lower; upper >= i_7_pr; i_7_pr ++ )
|
||||
reduce.r_10_rpr += foo();
|
||||
}
|
||||
switch( __kmpc_reduce_nowait( & loc10, *gtid, 1, 4, & reduce, main_10_reduce_5, & lck ) ) {
|
||||
case 1:
|
||||
*r_7_shp += reduce.r_10_rpr;
|
||||
__kmpc_end_reduce_nowait( & loc10, *gtid, & lck );
|
||||
break;
|
||||
case 2:
|
||||
__kmpc_atomic_float4_add( & loc10, *gtid, r_7_shp, reduce.r_10_rpr );
|
||||
break;
|
||||
default:;
|
||||
}
|
||||
}
|
||||
|
||||
void main_10_reduce_5( struct main_10_reduction_t_5 *reduce_lhs,
|
||||
struct main_10_reduction_t_5 *reduce_rhs )
|
||||
{
|
||||
reduce_lhs->r_10_rpr += reduce_rhs->r_10_rpr;
|
||||
}
|
||||
@endcode
|
||||
|
||||
@defgroup BASIC_TYPES Basic Types
|
||||
Types that are used throughout the runtime.
|
||||
|
||||
@defgroup DEPRECATED Deprecated Functions
|
||||
Functions in this group are for backwards compatibility only, and
|
||||
should not be used in new code.
|
||||
|
||||
@defgroup STARTUP_SHUTDOWN Startup and Shutdown
|
||||
These functions are for library initialization and shutdown.
|
||||
|
||||
@defgroup PARALLEL Parallel (fork/join)
|
||||
These functions are used for implementing <tt>\#pragma omp parallel</tt>.
|
||||
|
||||
@defgroup THREAD_STATES Thread Information
|
||||
These functions return information about the currently executing thread.
|
||||
|
||||
@defgroup WORK_SHARING Work Sharing
|
||||
These functions are used for implementing
|
||||
<tt>\#pragma omp for</tt>, <tt>\#pragma omp sections</tt>, <tt>\#pragma omp single</tt> and
|
||||
<tt>\#pragma omp master</tt> constructs.
|
||||
|
||||
When handling loops, there are different functions for each of the signed and unsigned 32 and 64 bit integer types
|
||||
which have the name suffixes `_4`, `_4u`, `_8` and `_8u`. The semantics of each of the functions is the same,
|
||||
so they are only described once.
|
||||
|
||||
Static loop scheduling is handled by @ref __kmpc_for_static_init_4 and friends. Only a single call is needed,
|
||||
since the iterations to be executed by any give thread can be determined as soon as the loop parameters are known.
|
||||
|
||||
Dynamic scheduling is handled by the @ref __kmpc_dispatch_init_4 and @ref __kmpc_dispatch_next_4 functions.
|
||||
The init function is called once in each thread outside the loop, while the next function is called each
|
||||
time that the previous chunk of work has been exhausted.
|
||||
|
||||
@defgroup SYNCHRONIZATION Synchronization
|
||||
These functions are used for implementing barriers.
|
||||
|
||||
@defgroup THREADPRIVATE Thread private data support
|
||||
These functions support copyin/out and thread private data.
|
||||
|
||||
@defgroup TASKING Tasking support
|
||||
These functions support are used to implement tasking constructs.
|
||||
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
set(OMP_SHLIBEXT "${CMAKE_SHARED_LIBRARY_SUFFIX}")
|
||||
|
||||
execute_process(COMMAND "date" "+%Y-%m-%d %H:%M:%S" OUTPUT_VARIABLE BUILD_TIME)
|
||||
string(REGEX REPLACE "\n" "" BUILD_TIME ${BUILD_TIME})
|
||||
|
||||
include_directories(
|
||||
.
|
||||
include
|
||||
include/${OMP_VERSION}
|
||||
i18n
|
||||
thirdparty/ittnotify
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
set(OS_GEN "win")
|
||||
elseif(APPLE)
|
||||
set(OS_GEN "mac")
|
||||
elseif(UNIX)
|
||||
set(OS_GEN "lin")
|
||||
else()
|
||||
message(FATAL_ERROR "Unsupported OS")
|
||||
endif()
|
||||
|
||||
if(arch)
|
||||
set(ARCH ${arch}) #acquire from command line
|
||||
else() #assume default
|
||||
set(ARCH "32e")
|
||||
endif()
|
||||
|
||||
if("${arch}" STREQUAL "32e")
|
||||
set(ARCH_STR "Intel(R) 64")
|
||||
elseif("${arch}" STREQUAL "ppc64")
|
||||
set(ARCH_STR "PPC64")
|
||||
endif()
|
||||
|
||||
set(FEATURE_FLAGS "-D USE_ITT_BUILD")
|
||||
set(FEATURE_FLAGS "${FEATURE_FLAGS} -D NDEBUG")
|
||||
set(FEATURE_FLAGS "${FEATURE_FLAGS} -D KMP_ARCH_STR=\"\\\"${ARCH_STR}\\\"\"")
|
||||
set(FEATURE_FLAGS "${FEATURE_FLAGS} -D _GNU_SOURCE")
|
||||
set(FEATURE_FLAGS "${FEATURE_FLAGS} -D _REENTRANT")
|
||||
set(FEATURE_FLAGS "${FEATURE_FLAGS} -D KMP_USE_ASSERT")
|
||||
set(FEATURE_FLAGS "${FEATURE_FLAGS} -D BUILD_I8")
|
||||
set(FEATURE_FLAGS "${FEATURE_FLAGS} -D BUILD_TV")
|
||||
|
||||
if(APPLE)
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -current_version 5.0")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -compatibility_version 5.0")
|
||||
endif()
|
||||
|
||||
set(FEATURE_FLAGS "${FEATURE_FLAGS} -D KMP_LIBRARY_FILE=\\\"libiomp5.${OMP_SHLIBEXT}\\\"")
|
||||
set(FEATURE_FLAGS "${FEATURE_FLAGS} -D KMP_VERSION_MAJOR=${VERSION}")
|
||||
|
||||
# customize cache line size for ppc64 to 128 bytes: 64 in all other cases
|
||||
if("${arch}" STREQUAL "ppc64")
|
||||
set(FEATURE_FLAGS "${FEATURE_FLAGS} -D CACHE_LINE=128")
|
||||
else()
|
||||
set(FEATURE_FLAGS "${FEATURE_FLAGS} -D CACHE_LINE=64")
|
||||
endif()
|
||||
|
||||
set(FEATURE_FLAGS "${FEATURE_FLAGS} -D KMP_ADJUST_BLOCKTIME=1")
|
||||
set(FEATURE_FLAGS "${FEATURE_FLAGS} -D BUILD_PARALLEL_ORDERED")
|
||||
set(FEATURE_FLAGS "${FEATURE_FLAGS} -D KMP_ASM_INTRINS")
|
||||
set(FEATURE_FLAGS "${FEATURE_FLAGS} -D USE_LOAD_BALANCE")
|
||||
set(FEATURE_FLAGS "${FEATURE_FLAGS} -D USE_CBLKDATA")
|
||||
set(FEATURE_FLAGS "${FEATURE_FLAGS} -D GUIDEDLL_EXPORTS")
|
||||
set(FEATURE_FLAGS "${FEATURE_FLAGS} -D KMP_GOMP_COMPAT")
|
||||
|
||||
#adaptive locks use x86 assembly - disable for ppc64
|
||||
if("${arch}" STREQUAL "32e" OR "${arch}" STREQUAL "32" OR "${arch}" STREQUAL "arm")
|
||||
set(FEATURE_FLAGS "${FEATURE_FLAGS} -D KMP_USE_ADAPTIVE_LOCKS=1")
|
||||
set(FEATURE_FLAGS "${FEATURE_FLAGS} -D KMP_DEBUG_ADAPTIVE_LOCKS=0")
|
||||
endif()
|
||||
|
||||
set(FEATURE_FLAGS "${FEATURE_FLAGS} -D OMP_50_ENABLED=0")
|
||||
set(FEATURE_FLAGS "${FEATURE_FLAGS} -D OMP_41_ENABLED=0")
|
||||
set(FEATURE_FLAGS "${FEATURE_FLAGS} -D OMP_40_ENABLED=1")
|
||||
set(FEATURE_FLAGS "${FEATURE_FLAGS} -D OMP_30_ENABLED=1")
|
||||
set(FEATURE_FLAGS "${FEATURE_FLAGS} -D USE_ITT_NOTIFY=1")
|
||||
set(FEATURE_FLAGS "${FEATURE_FLAGS} -D INTEL_ITTNOTIFY_PREFIX=__kmp_itt_")
|
||||
if (NOT APPLE)
|
||||
set(FEATURE_FLAGS "${FEATURE_FLAGS} -D KMP_TDATA_GTID")
|
||||
endif()
|
||||
set(FEATURE_FLAGS "${FEATURE_FLAGS} -D _KMP_BUILD_TIME=\"\\\"${BUILD_TIME} UTC\\\"\"")
|
||||
|
||||
set(COMMON_FLAGS "-fPIC")
|
||||
set(COMMON_FLAGS "${COMMON_FLAGS} -Wno-unused-value")
|
||||
set(COMMON_FLAGS "${COMMON_FLAGS} -Wno-switch")
|
||||
set(COMMON_FLAGS "${COMMON_FLAGS} -Wno-deprecated-register")
|
||||
set(COMMON_FLAGS "${COMMON_FLAGS} -fno-exceptions")
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FEATURE_FLAGS} ${COMMON_FLAGS}")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FEATURE_FLAGS} ${COMMON_FLAGS}")
|
||||
|
||||
set(ASM_SOURCES
|
||||
z_Linux_asm.s
|
||||
)
|
||||
set(SOURCES
|
||||
thirdparty/ittnotify/ittnotify_static.c
|
||||
kmp_affinity.cpp
|
||||
kmp_alloc.c
|
||||
kmp_atomic.c
|
||||
kmp_cancel.cpp
|
||||
kmp_csupport.c
|
||||
kmp_debug.c
|
||||
kmp_dispatch.cpp
|
||||
kmp_environment.c
|
||||
kmp_error.c
|
||||
kmp_ftn_cdecl.c
|
||||
kmp_ftn_extra.c
|
||||
kmp_global.c
|
||||
kmp_gsupport.c
|
||||
kmp_i18n.c
|
||||
kmp_io.c
|
||||
kmp_itt.c
|
||||
kmp_lock.cpp
|
||||
kmp_runtime.c
|
||||
kmp_sched.cpp
|
||||
kmp_settings.c
|
||||
kmp_str.c
|
||||
kmp_taskdeps.cpp
|
||||
kmp_tasking.c
|
||||
kmp_taskq.c
|
||||
kmp_threadprivate.c
|
||||
kmp_utility.c
|
||||
kmp_version.c
|
||||
z_Linux_util.c
|
||||
)
|
||||
|
||||
set_source_files_properties(${SOURCES} PROPERTIES LANGUAGE CXX)
|
||||
set_source_files_properties(${ASM_SOURCES} PROPERTIES LANGUAGE CXX)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT kmp_i18n_id.inc
|
||||
COMMAND perl ${CMAKE_CURRENT_SOURCE_DIR}/../tools/message-converter.pl --os=${OS_GEN} --arch=${ARCH} --prefix=kmp_i18n --enum=kmp_i18n_id.inc ${CMAKE_CURRENT_SOURCE_DIR}/i18n/en_US.txt
|
||||
)
|
||||
add_custom_command(
|
||||
OUTPUT kmp_i18n_default.inc
|
||||
COMMAND perl ${CMAKE_CURRENT_SOURCE_DIR}/../tools/message-converter.pl --os=${OS_GEN} --arch=${ARCH} --prefix=kmp_i18n --default=kmp_i18n_default.inc ${CMAKE_CURRENT_SOURCE_DIR}/i18n/en_US.txt
|
||||
)
|
||||
add_custom_command(
|
||||
OUTPUT omp.h
|
||||
COMMAND perl ${CMAKE_CURRENT_SOURCE_DIR}/../tools/expand-vars.pl --strict -D Revision=\"\\$$Revision\" -D Date=\"\\$$Date\" -D KMP_TYPE=\"Performance\" -D KMP_ARCH=\"\\\"${ARCH_STR}\\\"\" -D KMP_VERSION_MAJOR=${VERSION} -D KMP_VERSION_MINOR=0 -D KMP_VERSION_BUILD=00000000 -D KMP_BUILD_DATE=\"${BUILD_TIME} UTC\" -D KMP_TARGET_COMPILER=12 -D KMP_DIAG=0 -D KMP_DEBUG_INFO=0 -D OMP_VERSION=${OMP_VERSION} ${CMAKE_CURRENT_SOURCE_DIR}/include/${OMP_VERSION_NUM}/omp.h.var omp.h
|
||||
)
|
||||
|
||||
if("${ARCH}" STREQUAL "ppc64")
|
||||
add_custom_command(
|
||||
OUTPUT z_Linux_asm.o
|
||||
COMMAND ${CMAKE_CXX_COMPILER} -c -o z_Linux_asm.o -D KMP_ASM_INTRINS -D KMP_GOMP_COMPAT -D KMP_ARCH_PPC64 -x assembler-with-cpp ${CMAKE_CURRENT_SOURCE_DIR}/${ASM_SOURCES}
|
||||
)
|
||||
else()
|
||||
add_custom_command(
|
||||
OUTPUT z_Linux_asm.o
|
||||
COMMAND ${CMAKE_CXX_COMPILER} -c -o z_Linux_asm.o -D KMP_ASM_INTRINS -D KMP_GOMP_COMPAT -D KMP_ARCH_X86_64 -x assembler-with-cpp ${CMAKE_CURRENT_SOURCE_DIR}/${ASM_SOURCES}
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
add_custom_target(gen_kmp_i18n DEPENDS kmp_i18n_id.inc kmp_i18n_default.inc omp.h z_Linux_asm.o)
|
||||
|
||||
if(NOT APPLE)
|
||||
if(${ARCH} STREQUAL "ppc64" AND ${OS_GEN} STREQUAL "lin")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/exports_so.txt -ldl")
|
||||
else()
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/exports_so.txt")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_library(iomp5 SHARED ${SOURCES} z_Linux_asm.o)
|
||||
|
||||
# This is a workaround to a known ppc64 issue about libpthread. For more
|
||||
# information see
|
||||
# http://ryanarn.blogspot.com/2011/07/curious-case-of-pthreadatfork-on.html
|
||||
if("${ARCH}" STREQUAL "ppc64")
|
||||
find_library(PTHREAD NAMES pthread)
|
||||
target_link_libraries(iomp5 ${PTHREAD})
|
||||
endif()
|
||||
|
||||
add_dependencies(iomp5 gen_kmp_i18n)
|
||||
@@ -0,0 +1,65 @@
|
||||
# defs.mk
|
||||
# $Revision: 42061 $
|
||||
# $Date: 2013-02-28 16:36:24 -0600 (Thu, 28 Feb 2013) $
|
||||
|
||||
#
|
||||
#//===----------------------------------------------------------------------===//
|
||||
#//
|
||||
#// 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 contains definitions common for OpenMP RTL and DSL makefiles.
|
||||
# --------------------------------------------------------------------------------------------------
|
||||
|
||||
# Include really common definitions.
|
||||
include $(LIBOMP_WORK)tools/src/common-defs.mk
|
||||
|
||||
#
|
||||
# Directories.
|
||||
#
|
||||
|
||||
# Check and normalize LIBOMP_EXPORTS.
|
||||
ifeq "$(LIBOMP_EXPORTS)" ""
|
||||
$(error LIBOMP_EXPORTS environment variable must be set)
|
||||
endif
|
||||
ifneq "$(words $(LIBOMP_EXPORTS))" "1"
|
||||
$(error LIBOMP_EXPORTS must not contain spaces)
|
||||
endif
|
||||
override LIBOMP_EXPORTS := $(subst \,/,$(LIBOMP_EXPORTS))
|
||||
ifeq "$(filter %/,$(LIBOMP_EXPORTS))" ""
|
||||
override LIBOMP_EXPORTS := $(LIBOMP_EXPORTS)/
|
||||
endif
|
||||
# Output directories.
|
||||
out_dir = $(LIBOMP_EXPORTS)
|
||||
out_cmn_dir = $(out_dir)common$(suffix)/
|
||||
out_ptf_dir = $(out_dir)$(platform)$(suffix)/
|
||||
_out_lib_dir = $(out_dir)$(1)$(suffix)/lib$(if $(filter mac_%,$(1)),.thin)/
|
||||
out_lib_dir = $(call _out_lib_dir,$(platform))
|
||||
out_l10n_dir = $(out_lib_dir)$(if $(filter lin mac,$(os)),locale/)
|
||||
ifeq "$(os)" "mac"
|
||||
_out_lib_fat_dir = $(out_dir)$(1)$(suffix)/lib/
|
||||
out_lib_fat_dir = $(call _out_lib_fat_dir,$(platform))
|
||||
out_l10n_fat_dir = $(out_lib_fat_dir)locale/
|
||||
endif
|
||||
|
||||
#
|
||||
# Retrieve build number,
|
||||
#
|
||||
|
||||
ifeq "$(clean)" ""
|
||||
# Parse kmp_version.c file, look for "#define KMP_VERSION_BUILD yyyymmdd" string,
|
||||
# leave only "yyyymmdd". Note: Space after $$1 is important, it helps to detect possible errors.
|
||||
build := $(strip $(shell $(perl) -p -e '$$_ =~ s{^(?:\s*\#define\s+KMP_VERSION_BUILD\s+([0-9]{8})|.*)\s*\n}{$$1 }' $(LIBOMP_WORK)src/kmp_version.c))
|
||||
ifneq "$(words $(build))" "1"
|
||||
$(error Failed to pase "kmp_version.c", cannot extract build number)
|
||||
endif
|
||||
$(call say,Build : $(build)$(if $(filter 00000000,$(build)), (development)))
|
||||
endif
|
||||
|
||||
# end of file #
|
||||
@@ -0,0 +1,945 @@
|
||||
#
|
||||
#//===----------------------------------------------------------------------===//
|
||||
#//
|
||||
#// 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.
|
||||
#//
|
||||
#//===----------------------------------------------------------------------===//
|
||||
#
|
||||
|
||||
# Deprecated entry points (numbers are reserved):
|
||||
- __kmpc_barrier_reduce_master 109
|
||||
- __kmpc_end_barrier_reduce_master 122
|
||||
- __kmpc_for_init_4 131
|
||||
- __kmpc_for_init_8 132
|
||||
- __kmpc_for_next_4 133
|
||||
- __kmpc_for_next_8 134
|
||||
- __kmpc_fork_call_bound 139
|
||||
- __kmpc_reduce_master_nowait 149
|
||||
- __kmpc_omp_task_begin 194
|
||||
- __kmpc_omp_task_complete 195
|
||||
- kmpc_sharable_calloc 218
|
||||
- kmpc_sharable_free 219
|
||||
- kmpc_sharable_malloc 220
|
||||
- kmpc_sharable_realloc 221
|
||||
- kmpc_aligned_sharable_malloc 223
|
||||
- mpai4a 500
|
||||
- mpai8a 501
|
||||
- mpar4a 502
|
||||
- mpar8a 503
|
||||
- mpax4x 504
|
||||
- mpax8x 505
|
||||
- mpobar 506
|
||||
- mpoebr 507
|
||||
- mpofork 508
|
||||
- mpofrk 509
|
||||
- mpojoin 510
|
||||
- mpoxbr 511
|
||||
- mppadj 512
|
||||
- mppaff 513
|
||||
- mppbar 514
|
||||
- mppbeg 515
|
||||
- mppdeo 516
|
||||
- mppdnx 517
|
||||
- mppdnxd 518
|
||||
- mppdon 519
|
||||
- mppdxo 520
|
||||
- mppebr 521
|
||||
- mppecs 522
|
||||
- mppems 523
|
||||
- mppenc 524
|
||||
- mppend 525
|
||||
- mppepa 526
|
||||
- mppesp 527
|
||||
- mppfkd 528
|
||||
- mppfkt 529
|
||||
- mppfork 530
|
||||
- mppfrk 531
|
||||
- mppioa 532
|
||||
- mppiws 533
|
||||
- mppjoin 534
|
||||
- mppnth 535
|
||||
- mpppqa 536
|
||||
- mpppqc 537
|
||||
- mpppqs 538
|
||||
- mpptid 539
|
||||
- mpptpa 540
|
||||
- mpptpc 541
|
||||
- mpptpz 542
|
||||
- mppvsy 543
|
||||
- mppxbr 544
|
||||
- mppxcs 545
|
||||
- mppxms 546
|
||||
- mppxnc 547
|
||||
- mppxpa 548
|
||||
- mppxpr 549
|
||||
- mppxsp 550
|
||||
- mppxth 551
|
||||
- mpsbar 552
|
||||
- mpscpr 597
|
||||
- mpsebr 553
|
||||
- mpserd 554
|
||||
- mpsfd4 555
|
||||
- mpsfd8 556
|
||||
- mpsid4 557
|
||||
- mpsid8 558
|
||||
- mpsnd4 559
|
||||
- mpsnd8 560
|
||||
- mpsont 561
|
||||
- mpsred 562
|
||||
- mpsunt 563
|
||||
- mpsxbr 564
|
||||
- mpsxrd 565
|
||||
- mptadj 566
|
||||
- mptaff 567
|
||||
- mptbar 568
|
||||
- mptdeo 569
|
||||
- mptdin 570
|
||||
- mptdind 571
|
||||
- mptdnx 572
|
||||
- mptdnxd 573
|
||||
- mptdon 574
|
||||
- mptdxo 575
|
||||
- mptebr 576
|
||||
- mptecs 577
|
||||
- mptems 578
|
||||
- mptenc 579
|
||||
- mptepa 580
|
||||
- mptesp 581
|
||||
- mptfkd 582
|
||||
- mptppa 583
|
||||
- mptppc 584
|
||||
- mptpps 585
|
||||
- mpttpa 586
|
||||
- mpttpc 587
|
||||
- mpttpz 588
|
||||
- mptvsy 589
|
||||
- mptxbr 590
|
||||
- mptxcs 591
|
||||
- mptxms 592
|
||||
- mptxnc 593
|
||||
- mptxpa 594
|
||||
- mptxsp 595
|
||||
- mppcpr 596
|
||||
- ftn_set_library_gang 736
|
||||
- kmp_set_library_gang
|
||||
- kmp_sharable_calloc 760
|
||||
- kmp_sharable_free 761
|
||||
- kmp_sharable_malloc 762
|
||||
- kmp_sharable_realloc 763
|
||||
- kmp_aligned_sharable_malloc 764
|
||||
- kmp_deferred_atomic_add_i4 765
|
||||
- kmp_deferred_atomic_add_i8 766
|
||||
- kmp_deferred_atomic_add_r4 767
|
||||
- kmp_deferred_atomic_add_r8 768
|
||||
- kmp_lock_cond_wait 770
|
||||
- kmp_lock_cond_signal 771
|
||||
- kmp_lock_cond_broadcast 772
|
||||
- kmp_nest_lock_cond_wait 773
|
||||
- kmp_nest_lock_cond_signal 774
|
||||
- kmp_nest_lock_cond_broadcast 775
|
||||
- kmp_get_process_num 781
|
||||
- kmp_get_num_processes 782
|
||||
- kmp_get_process_thread_num 783
|
||||
- kmp_private_mmap 784 # not implemented?
|
||||
- kmp_sharable_mmap 785 # not implemented?
|
||||
- kmp_private_munmap 786 # not implemented?
|
||||
- kmp_sharable_munmap 787 # not implemented?
|
||||
- kmp_is_sharable 788 # not implemented?
|
||||
|
||||
%ifndef stub
|
||||
|
||||
|
||||
#
|
||||
# The following entry points are added so that the backtraces from
|
||||
# the tools contain meaningful names for all the functions that might
|
||||
# appear in a backtrace of a thread which is blocked in the RTL.
|
||||
#
|
||||
|
||||
# Regular entry points
|
||||
__kmp_wait_yield_4
|
||||
__kmp_wait_yield_8
|
||||
__kmp_wait_sleep
|
||||
__kmp_fork_call
|
||||
__kmp_invoke_microtask
|
||||
__kmp_release
|
||||
__kmp_launch_monitor
|
||||
__kmp_launch_worker
|
||||
__kmp_reap_monitor
|
||||
__kmp_reap_worker
|
||||
__kmp_acquire_tas_lock
|
||||
__kmp_acquire_nested_tas_lock
|
||||
__kmp_acquire_ticket_lock
|
||||
__kmp_acquire_nested_ticket_lock
|
||||
__kmp_acquire_queuing_lock
|
||||
__kmp_acquire_nested_queuing_lock
|
||||
__kmp_acquire_drdpa_lock
|
||||
__kmp_acquire_nested_drdpa_lock
|
||||
|
||||
%ifdef KMP_DEBUG
|
||||
# allows console output capability for applications those don't have it
|
||||
__kmp_printf
|
||||
%endif
|
||||
|
||||
|
||||
|
||||
# Symbols for MS mutual detection:
|
||||
_You_must_link_with_exactly_one_OpenMP_library DATA
|
||||
_You_must_link_with_Intel_OpenMP_library DATA
|
||||
%ifdef msvc_compat
|
||||
_You_must_link_with_Microsoft_OpenMP_library DATA
|
||||
%endif
|
||||
|
||||
# VT_getthid 1
|
||||
# vtgthid 2
|
||||
|
||||
__kmpc_atomic_4 100
|
||||
__kmpc_atomic_8 101
|
||||
__kmpc_atomic_fixed4_add 102
|
||||
__kmpc_atomic_fixed8_add 103
|
||||
__kmpc_atomic_float4_add 104
|
||||
__kmpc_atomic_float8_add 105
|
||||
__kmpc_barrier 106
|
||||
__kmpc_barrier_master 107
|
||||
__kmpc_barrier_master_nowait 108
|
||||
__kmpc_begin 110
|
||||
__kmpc_bound_num_threads 111
|
||||
__kmpc_bound_thread_num 112
|
||||
__kmpc_critical 113
|
||||
__kmpc_dispatch_fini_4 114
|
||||
__kmpc_dispatch_fini_8 115
|
||||
__kmpc_dispatch_init_4 116
|
||||
__kmpc_dispatch_init_8 117
|
||||
__kmpc_dispatch_next_4 118
|
||||
__kmpc_dispatch_next_8 119
|
||||
__kmpc_end 120
|
||||
__kmpc_end_barrier_master 121
|
||||
__kmpc_end_critical 123
|
||||
__kmpc_end_master 124
|
||||
__kmpc_end_ordered 125
|
||||
__kmpc_end_serialized_parallel 126
|
||||
__kmpc_end_single 127
|
||||
__kmpc_end_taskq 128
|
||||
__kmpc_end_taskq_task 129
|
||||
__kmpc_flush 130
|
||||
__kmpc_for_static_fini 135
|
||||
__kmpc_for_static_init_4 136
|
||||
__kmpc_for_static_init_8 137
|
||||
__kmpc_fork_call 138
|
||||
__kmpc_global_num_threads 140
|
||||
__kmpc_global_thread_num 141
|
||||
__kmpc_in_parallel 142
|
||||
__kmpc_invoke_task_func 143
|
||||
__kmpc_master 144
|
||||
__kmpc_ok_to_fork 145
|
||||
__kmpc_ordered 146
|
||||
__kmpc_pop_num_threads 147
|
||||
__kmpc_push_num_threads 148
|
||||
__kmpc_serialized_parallel 150
|
||||
__kmpc_single 151
|
||||
__kmpc_task 152
|
||||
__kmpc_task_buffer 153
|
||||
__kmpc_taskq 154
|
||||
__kmpc_taskq_task 155
|
||||
__kmpc_threadprivate 156
|
||||
__kmpc_threadprivate_cached 157
|
||||
__kmpc_threadprivate_register 158
|
||||
__kmpc_threadprivate_register_vec 159
|
||||
# __kmpc_ssp_begin 160
|
||||
# __kmpc_ssp_fork 161
|
||||
# __kmpc_ssp_end 162
|
||||
# __kmpc_ssp_post_4 163
|
||||
# __kmpc_ssp_post_8 164
|
||||
# __kmpc_ssp_wait_4 165
|
||||
# __kmpc_ssp_wait_8 166
|
||||
# __kmpc_ssp_distance_4 167
|
||||
# __kmpc_ssp_distance_8 168
|
||||
# __kmpc_in_ssp 169
|
||||
# __kmpc_ssp_thread_num 170
|
||||
# __kmpc_ssp_num_threads 171
|
||||
__kmpc_copyprivate 172
|
||||
# __kmpc_ssp_get_max_threads 173
|
||||
# __kmpc_ssp_set_max_threads 174
|
||||
__kmpc_init_lock 175
|
||||
__kmpc_destroy_lock 176
|
||||
__kmpc_set_lock 177
|
||||
__kmpc_unset_lock 178
|
||||
__kmpc_test_lock 179
|
||||
__kmpc_init_nest_lock 180
|
||||
__kmpc_destroy_nest_lock 181
|
||||
__kmpc_set_nest_lock 182
|
||||
__kmpc_unset_nest_lock 183
|
||||
__kmpc_test_nest_lock 184
|
||||
# __kmpc_ssp_init_thread 185
|
||||
# __kmpc_ssp_set_event 186
|
||||
__kmpc_reduce_nowait 187
|
||||
__kmpc_end_reduce_nowait 188
|
||||
__kmpc_reduce 189
|
||||
__kmpc_end_reduce 190
|
||||
|
||||
# OpenMP 3.0
|
||||
|
||||
%ifdef OMP_30
|
||||
__kmpc_omp_task_alloc 191
|
||||
__kmpc_omp_task 192
|
||||
__kmpc_omp_taskwait 193
|
||||
__kmpc_omp_task_begin_if0 196
|
||||
__kmpc_omp_task_complete_if0 197
|
||||
__kmpc_omp_task_parts 198
|
||||
%endif # OMP_30
|
||||
|
||||
# __omp_collector_api 199
|
||||
|
||||
# These functions are for testing purposes. There is no need in stable ordinal number:
|
||||
__kmp_get_reduce_method
|
||||
|
||||
%endif # not defined stub
|
||||
|
||||
kmpc_calloc 200
|
||||
kmpc_free 201
|
||||
%ifndef stub
|
||||
# These functions are exported from libguide, but declared neither in omp.h not in omp_lib.h.
|
||||
# kmpc_get_banner 202
|
||||
# kmpc_get_poolmode 203
|
||||
# kmpc_get_poolsize 204
|
||||
# kmpc_get_poolstat 205
|
||||
# kmpc_poolprint 207
|
||||
# kmpc_print_banner 208
|
||||
# kmpc_set_poolmode 214
|
||||
# kmpc_set_poolsize 215
|
||||
%endif
|
||||
kmpc_malloc 206
|
||||
kmpc_realloc 209
|
||||
kmpc_set_blocktime 211
|
||||
kmpc_set_library 212
|
||||
# kmpc_set_parallel_name 213
|
||||
kmpc_set_stacksize 216
|
||||
kmpc_set_stacksize_s 222
|
||||
# kmpc_set_stats 217
|
||||
kmpc_set_defaults 224
|
||||
|
||||
# OMP 3.0 entry points for unsigned loop iteration variables
|
||||
%ifndef stub
|
||||
%ifdef OMP_30
|
||||
__kmpc_for_static_init_8u 225
|
||||
__kmpc_dispatch_init_8u 226
|
||||
__kmpc_dispatch_next_8u 227
|
||||
__kmpc_dispatch_fini_8u 228
|
||||
__kmpc_for_static_init_4u 229
|
||||
__kmpc_dispatch_init_4u 230
|
||||
__kmpc_dispatch_next_4u 231
|
||||
__kmpc_dispatch_fini_4u 232
|
||||
%endif # OMP_30
|
||||
%endif
|
||||
|
||||
%ifndef stub
|
||||
__kmpc_get_taskid 233
|
||||
__kmpc_get_parent_taskid 234
|
||||
%endif
|
||||
|
||||
# OpenMP 3.1 entry points
|
||||
%ifndef stub
|
||||
%ifdef OMP_30
|
||||
__kmpc_omp_taskyield 235
|
||||
%endif # OMP_30
|
||||
__kmpc_place_threads 236
|
||||
%endif
|
||||
|
||||
# OpenMP 4.0 entry points
|
||||
%ifndef stub
|
||||
%ifdef OMP_40
|
||||
__kmpc_push_proc_bind 237
|
||||
__kmpc_taskgroup 238
|
||||
__kmpc_end_taskgroup 239
|
||||
__kmpc_push_num_teams 240
|
||||
__kmpc_fork_teams 241
|
||||
__kmpc_omp_task_with_deps 242
|
||||
__kmpc_omp_wait_deps 243
|
||||
__kmpc_cancel 244
|
||||
__kmpc_cancellationpoint 245
|
||||
__kmpc_cancel_barrier 246
|
||||
%endif # OMP_40
|
||||
%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_'.
|
||||
|
||||
omp_destroy_lock 700
|
||||
omp_destroy_nest_lock 701
|
||||
omp_get_dynamic 702
|
||||
omp_get_max_threads 703
|
||||
omp_get_nested 704
|
||||
omp_get_num_procs 705
|
||||
omp_get_num_threads 706
|
||||
omp_get_thread_num 707
|
||||
omp_get_wtick 708
|
||||
omp_get_wtime 709
|
||||
omp_in_parallel 710
|
||||
omp_init_lock 711
|
||||
omp_init_nest_lock 712
|
||||
omp_set_dynamic 713
|
||||
omp_set_lock 714
|
||||
omp_set_nest_lock 715
|
||||
omp_set_nested 716
|
||||
omp_set_num_threads 717
|
||||
omp_test_lock 718
|
||||
omp_test_nest_lock 719
|
||||
omp_unset_lock 720
|
||||
omp_unset_nest_lock 721
|
||||
|
||||
ompc_set_dynamic 722
|
||||
ompc_set_nested 723
|
||||
ompc_set_num_threads 724
|
||||
|
||||
kmp_calloc 725
|
||||
kmp_free 726
|
||||
kmp_get_blocktime 727
|
||||
kmp_get_library 728
|
||||
kmp_get_stacksize 729
|
||||
kmp_malloc 730
|
||||
#kmp_print_banner 731
|
||||
kmp_realloc 732
|
||||
kmp_set_blocktime 734
|
||||
kmp_set_library 735
|
||||
kmp_set_library_serial 737
|
||||
kmp_set_library_throughput 738
|
||||
kmp_set_library_turnaround 739
|
||||
# kmp_set_parallel_name 740
|
||||
kmp_set_stacksize 741
|
||||
# kmp_set_stats 742
|
||||
kmp_get_num_known_threads 743
|
||||
kmp_set_stacksize_s 744
|
||||
kmp_get_stacksize_s 745
|
||||
kmp_set_defaults 746
|
||||
kmp_set_warnings_on 779
|
||||
kmp_set_warnings_off 780
|
||||
|
||||
%ifdef OMP_30
|
||||
omp_get_active_level 789
|
||||
omp_get_level 790
|
||||
omp_get_ancestor_thread_num 791
|
||||
omp_get_team_size 792
|
||||
omp_get_thread_limit 793
|
||||
omp_get_max_active_levels 794
|
||||
omp_set_max_active_levels 795
|
||||
omp_get_schedule 796
|
||||
omp_set_schedule 797
|
||||
ompc_set_max_active_levels 798
|
||||
ompc_set_schedule 799
|
||||
ompc_get_ancestor_thread_num 800
|
||||
ompc_get_team_size 801
|
||||
kmp_set_affinity 850
|
||||
kmp_get_affinity 851
|
||||
kmp_get_affinity_max_proc 852
|
||||
kmp_create_affinity_mask 853
|
||||
kmp_destroy_affinity_mask 854
|
||||
kmp_set_affinity_mask_proc 855
|
||||
kmpc_set_affinity_mask_proc 856
|
||||
kmp_unset_affinity_mask_proc 857
|
||||
kmpc_unset_affinity_mask_proc 858
|
||||
kmp_get_affinity_mask_proc 859
|
||||
kmpc_get_affinity_mask_proc 860
|
||||
%endif # OMP_30
|
||||
|
||||
# OpenMP 3.1
|
||||
|
||||
%ifdef OMP_30
|
||||
omp_in_final 861
|
||||
%endif # OMP_30
|
||||
|
||||
# OpenMP 40
|
||||
|
||||
%ifdef OMP_40
|
||||
omp_get_proc_bind 862
|
||||
#omp_set_proc_bind 863
|
||||
#omp_curr_proc_bind 864
|
||||
omp_get_num_teams 865
|
||||
omp_get_team_num 866
|
||||
omp_get_cancellation 867
|
||||
kmp_get_cancellation_status 868
|
||||
%endif # OMP_40
|
||||
|
||||
%ifndef stub
|
||||
# Ordinals between 900 and 999 are reserved
|
||||
|
||||
# Ordinals between 1000 and 1999 are reserved
|
||||
# for user-callable uppercase Fortran entries.
|
||||
|
||||
|
||||
# ATOMIC entries
|
||||
|
||||
%ifdef HAVE_QUAD
|
||||
__kmpc_atomic_cmplx16_div 2000
|
||||
%endif
|
||||
|
||||
__kmpc_atomic_fixed1_add 2001
|
||||
__kmpc_atomic_fixed1_andb 2002
|
||||
__kmpc_atomic_fixed1_div 2003
|
||||
__kmpc_atomic_fixed1u_div 2004
|
||||
__kmpc_atomic_fixed1_mul 2005
|
||||
__kmpc_atomic_fixed1_orb 2006
|
||||
__kmpc_atomic_fixed1_shl 2007
|
||||
__kmpc_atomic_fixed1_shr 2008
|
||||
__kmpc_atomic_fixed1u_shr 2009
|
||||
__kmpc_atomic_fixed1_sub 2010
|
||||
__kmpc_atomic_fixed1_xor 2011
|
||||
|
||||
__kmpc_atomic_fixed2_add 2012
|
||||
__kmpc_atomic_fixed2_andb 2013
|
||||
__kmpc_atomic_fixed2_div 2014
|
||||
__kmpc_atomic_fixed2u_div 2015
|
||||
__kmpc_atomic_fixed2_mul 2016
|
||||
__kmpc_atomic_fixed2_orb 2017
|
||||
__kmpc_atomic_fixed2_shl 2018
|
||||
__kmpc_atomic_fixed2_shr 2019
|
||||
__kmpc_atomic_fixed2u_shr 2020
|
||||
__kmpc_atomic_fixed2_sub 2021
|
||||
__kmpc_atomic_fixed2_xor 2022
|
||||
|
||||
#__kmpc_atomic_fixed4_add # declared above #102
|
||||
__kmpc_atomic_fixed4_sub 2024
|
||||
#__kmpc_atomic_float4_add # declared above #104
|
||||
__kmpc_atomic_float4_sub 2026
|
||||
#__kmpc_atomic_fixed8_add # declared above #103
|
||||
__kmpc_atomic_fixed8_sub 2028
|
||||
#__kmpc_atomic_float8_add # declared above #105
|
||||
__kmpc_atomic_float8_sub 2030
|
||||
|
||||
__kmpc_atomic_fixed4_andb 2031
|
||||
__kmpc_atomic_fixed4_div 2032
|
||||
__kmpc_atomic_fixed4u_div 2033
|
||||
__kmpc_atomic_fixed4_mul 2034
|
||||
__kmpc_atomic_fixed4_orb 2035
|
||||
__kmpc_atomic_fixed4_shl 2036
|
||||
__kmpc_atomic_fixed4_shr 2037
|
||||
__kmpc_atomic_fixed4u_shr 2038
|
||||
__kmpc_atomic_fixed4_xor 2039
|
||||
__kmpc_atomic_fixed8_andb 2040
|
||||
__kmpc_atomic_fixed8_div 2041
|
||||
__kmpc_atomic_fixed8u_div 2042
|
||||
__kmpc_atomic_fixed8_mul 2043
|
||||
__kmpc_atomic_fixed8_orb 2044
|
||||
__kmpc_atomic_fixed8_shl 2045
|
||||
__kmpc_atomic_fixed8_shr 2046
|
||||
__kmpc_atomic_fixed8u_shr 2047
|
||||
__kmpc_atomic_fixed8_xor 2048
|
||||
__kmpc_atomic_float4_div 2049
|
||||
__kmpc_atomic_float4_mul 2050
|
||||
__kmpc_atomic_float8_div 2051
|
||||
__kmpc_atomic_float8_mul 2052
|
||||
|
||||
__kmpc_atomic_fixed1_andl 2053
|
||||
__kmpc_atomic_fixed1_orl 2054
|
||||
__kmpc_atomic_fixed2_andl 2055
|
||||
__kmpc_atomic_fixed2_orl 2056
|
||||
__kmpc_atomic_fixed4_andl 2057
|
||||
__kmpc_atomic_fixed4_orl 2058
|
||||
__kmpc_atomic_fixed8_andl 2059
|
||||
__kmpc_atomic_fixed8_orl 2060
|
||||
|
||||
__kmpc_atomic_fixed1_max 2061
|
||||
__kmpc_atomic_fixed1_min 2062
|
||||
__kmpc_atomic_fixed2_max 2063
|
||||
__kmpc_atomic_fixed2_min 2064
|
||||
__kmpc_atomic_fixed4_max 2065
|
||||
__kmpc_atomic_fixed4_min 2066
|
||||
__kmpc_atomic_fixed8_max 2067
|
||||
__kmpc_atomic_fixed8_min 2068
|
||||
__kmpc_atomic_float4_max 2069
|
||||
__kmpc_atomic_float4_min 2070
|
||||
__kmpc_atomic_float8_max 2071
|
||||
__kmpc_atomic_float8_min 2072
|
||||
|
||||
__kmpc_atomic_fixed1_neqv 2073
|
||||
__kmpc_atomic_fixed2_neqv 2074
|
||||
__kmpc_atomic_fixed4_neqv 2075
|
||||
__kmpc_atomic_fixed8_neqv 2076
|
||||
__kmpc_atomic_fixed1_eqv 2077
|
||||
__kmpc_atomic_fixed2_eqv 2078
|
||||
__kmpc_atomic_fixed4_eqv 2079
|
||||
__kmpc_atomic_fixed8_eqv 2080
|
||||
|
||||
__kmpc_atomic_float10_add 2081
|
||||
__kmpc_atomic_float10_sub 2082
|
||||
__kmpc_atomic_float10_mul 2083
|
||||
__kmpc_atomic_float10_div 2084
|
||||
|
||||
__kmpc_atomic_cmplx4_add 2085
|
||||
__kmpc_atomic_cmplx4_sub 2086
|
||||
__kmpc_atomic_cmplx4_mul 2087
|
||||
__kmpc_atomic_cmplx4_div 2088
|
||||
__kmpc_atomic_cmplx8_add 2089
|
||||
__kmpc_atomic_cmplx8_sub 2090
|
||||
__kmpc_atomic_cmplx8_mul 2091
|
||||
__kmpc_atomic_cmplx8_div 2092
|
||||
__kmpc_atomic_cmplx10_add 2093
|
||||
__kmpc_atomic_cmplx10_sub 2094
|
||||
__kmpc_atomic_cmplx10_mul 2095
|
||||
__kmpc_atomic_cmplx10_div 2096
|
||||
%ifdef HAVE_QUAD
|
||||
__kmpc_atomic_cmplx16_add 2097
|
||||
__kmpc_atomic_cmplx16_sub 2098
|
||||
__kmpc_atomic_cmplx16_mul 2099
|
||||
#__kmpc_atomic_cmplx16_div 2000 # moved up because of mistake in number (supposed to be 2100)
|
||||
|
||||
__kmpc_atomic_float16_add 2101
|
||||
__kmpc_atomic_float16_sub 2102
|
||||
__kmpc_atomic_float16_mul 2103
|
||||
__kmpc_atomic_float16_div 2104
|
||||
__kmpc_atomic_float16_max 2105
|
||||
__kmpc_atomic_float16_min 2106
|
||||
|
||||
__kmpc_atomic_fixed1_add_fp 2107
|
||||
__kmpc_atomic_fixed1_sub_fp 2108
|
||||
__kmpc_atomic_fixed1_mul_fp 2109
|
||||
__kmpc_atomic_fixed1_div_fp 2110
|
||||
__kmpc_atomic_fixed1u_div_fp 2111
|
||||
|
||||
__kmpc_atomic_fixed2_add_fp 2112
|
||||
__kmpc_atomic_fixed2_sub_fp 2113
|
||||
__kmpc_atomic_fixed2_mul_fp 2114
|
||||
__kmpc_atomic_fixed2_div_fp 2115
|
||||
__kmpc_atomic_fixed2u_div_fp 2116
|
||||
|
||||
__kmpc_atomic_fixed4_add_fp 2117
|
||||
__kmpc_atomic_fixed4_sub_fp 2118
|
||||
__kmpc_atomic_fixed4_mul_fp 2119
|
||||
__kmpc_atomic_fixed4_div_fp 2120
|
||||
__kmpc_atomic_fixed4u_div_fp 2121
|
||||
|
||||
__kmpc_atomic_fixed8_add_fp 2122
|
||||
__kmpc_atomic_fixed8_sub_fp 2123
|
||||
__kmpc_atomic_fixed8_mul_fp 2124
|
||||
__kmpc_atomic_fixed8_div_fp 2125
|
||||
__kmpc_atomic_fixed8u_div_fp 2126
|
||||
|
||||
__kmpc_atomic_float4_add_fp 2127
|
||||
__kmpc_atomic_float4_sub_fp 2128
|
||||
__kmpc_atomic_float4_mul_fp 2129
|
||||
__kmpc_atomic_float4_div_fp 2130
|
||||
|
||||
__kmpc_atomic_float8_add_fp 2131
|
||||
__kmpc_atomic_float8_sub_fp 2132
|
||||
__kmpc_atomic_float8_mul_fp 2133
|
||||
__kmpc_atomic_float8_div_fp 2134
|
||||
|
||||
__kmpc_atomic_float10_add_fp 2135
|
||||
__kmpc_atomic_float10_sub_fp 2136
|
||||
__kmpc_atomic_float10_mul_fp 2137
|
||||
__kmpc_atomic_float10_div_fp 2138
|
||||
%endif
|
||||
|
||||
__kmpc_atomic_fixed1_mul_float8 2169
|
||||
__kmpc_atomic_fixed1_div_float8 2170
|
||||
|
||||
__kmpc_atomic_fixed2_mul_float8 2174
|
||||
__kmpc_atomic_fixed2_div_float8 2175
|
||||
|
||||
__kmpc_atomic_fixed4_mul_float8 2179
|
||||
__kmpc_atomic_fixed4_div_float8 2180
|
||||
|
||||
__kmpc_atomic_fixed8_mul_float8 2184
|
||||
__kmpc_atomic_fixed8_div_float8 2185
|
||||
|
||||
__kmpc_atomic_float4_add_float8 2187
|
||||
__kmpc_atomic_float4_sub_float8 2188
|
||||
__kmpc_atomic_float4_mul_float8 2189
|
||||
__kmpc_atomic_float4_div_float8 2190
|
||||
|
||||
__kmpc_atomic_cmplx4_add_cmplx8 2231
|
||||
__kmpc_atomic_cmplx4_sub_cmplx8 2232
|
||||
__kmpc_atomic_cmplx4_mul_cmplx8 2233
|
||||
__kmpc_atomic_cmplx4_div_cmplx8 2234
|
||||
|
||||
__kmpc_atomic_1 2247
|
||||
__kmpc_atomic_2 2248
|
||||
#__kmpc_atomic_4 # declared above #100
|
||||
#__kmpc_atomic_8 # declared above #101
|
||||
__kmpc_atomic_10 2251
|
||||
__kmpc_atomic_16 2252
|
||||
__kmpc_atomic_20 2253
|
||||
__kmpc_atomic_32 2254
|
||||
|
||||
%ifdef arch_32
|
||||
|
||||
%ifdef HAVE_QUAD
|
||||
__kmpc_atomic_float16_add_a16 2255
|
||||
__kmpc_atomic_float16_sub_a16 2256
|
||||
__kmpc_atomic_float16_mul_a16 2257
|
||||
__kmpc_atomic_float16_div_a16 2258
|
||||
__kmpc_atomic_float16_max_a16 2259
|
||||
__kmpc_atomic_float16_min_a16 2260
|
||||
|
||||
__kmpc_atomic_cmplx16_add_a16 2261
|
||||
__kmpc_atomic_cmplx16_sub_a16 2262
|
||||
__kmpc_atomic_cmplx16_mul_a16 2263
|
||||
__kmpc_atomic_cmplx16_div_a16 2264
|
||||
%endif
|
||||
|
||||
%endif
|
||||
|
||||
%ifndef arch_64
|
||||
|
||||
# ATOMIC extensions for OpenMP 3.1 spec (x86 and x64 only)
|
||||
|
||||
__kmpc_atomic_fixed1_rd 2265
|
||||
__kmpc_atomic_fixed2_rd 2266
|
||||
__kmpc_atomic_fixed4_rd 2267
|
||||
__kmpc_atomic_fixed8_rd 2268
|
||||
__kmpc_atomic_float4_rd 2269
|
||||
__kmpc_atomic_float8_rd 2270
|
||||
__kmpc_atomic_float10_rd 2271
|
||||
%ifdef HAVE_QUAD
|
||||
__kmpc_atomic_float16_rd 2272
|
||||
%endif
|
||||
__kmpc_atomic_cmplx4_rd 2273
|
||||
__kmpc_atomic_cmplx8_rd 2274
|
||||
__kmpc_atomic_cmplx10_rd 2275
|
||||
%ifdef HAVE_QUAD
|
||||
__kmpc_atomic_cmplx16_rd 2276
|
||||
%ifdef arch_32
|
||||
__kmpc_atomic_float16_a16_rd 2277
|
||||
__kmpc_atomic_cmplx16_a16_rd 2278
|
||||
%endif
|
||||
%endif
|
||||
__kmpc_atomic_fixed1_wr 2279
|
||||
__kmpc_atomic_fixed2_wr 2280
|
||||
__kmpc_atomic_fixed4_wr 2281
|
||||
__kmpc_atomic_fixed8_wr 2282
|
||||
__kmpc_atomic_float4_wr 2283
|
||||
__kmpc_atomic_float8_wr 2284
|
||||
__kmpc_atomic_float10_wr 2285
|
||||
%ifdef HAVE_QUAD
|
||||
__kmpc_atomic_float16_wr 2286
|
||||
%endif
|
||||
__kmpc_atomic_cmplx4_wr 2287
|
||||
__kmpc_atomic_cmplx8_wr 2288
|
||||
__kmpc_atomic_cmplx10_wr 2289
|
||||
%ifdef HAVE_QUAD
|
||||
__kmpc_atomic_cmplx16_wr 2290
|
||||
%ifdef arch_32
|
||||
__kmpc_atomic_float16_a16_wr 2291
|
||||
__kmpc_atomic_cmplx16_a16_wr 2292
|
||||
%endif
|
||||
%endif
|
||||
__kmpc_atomic_fixed1_add_cpt 2293
|
||||
__kmpc_atomic_fixed1_andb_cpt 2294
|
||||
__kmpc_atomic_fixed1_div_cpt 2295
|
||||
__kmpc_atomic_fixed1u_div_cpt 2296
|
||||
__kmpc_atomic_fixed1_mul_cpt 2297
|
||||
__kmpc_atomic_fixed1_orb_cpt 2298
|
||||
__kmpc_atomic_fixed1_shl_cpt 2299
|
||||
__kmpc_atomic_fixed1_shr_cpt 2300
|
||||
__kmpc_atomic_fixed1u_shr_cpt 2301
|
||||
__kmpc_atomic_fixed1_sub_cpt 2302
|
||||
__kmpc_atomic_fixed1_xor_cpt 2303
|
||||
__kmpc_atomic_fixed2_add_cpt 2304
|
||||
__kmpc_atomic_fixed2_andb_cpt 2305
|
||||
__kmpc_atomic_fixed2_div_cpt 2306
|
||||
__kmpc_atomic_fixed2u_div_cpt 2307
|
||||
__kmpc_atomic_fixed2_mul_cpt 2308
|
||||
__kmpc_atomic_fixed2_orb_cpt 2309
|
||||
__kmpc_atomic_fixed2_shl_cpt 2310
|
||||
__kmpc_atomic_fixed2_shr_cpt 2311
|
||||
__kmpc_atomic_fixed2u_shr_cpt 2312
|
||||
__kmpc_atomic_fixed2_sub_cpt 2313
|
||||
__kmpc_atomic_fixed2_xor_cpt 2314
|
||||
__kmpc_atomic_fixed4_add_cpt 2315
|
||||
__kmpc_atomic_fixed4_sub_cpt 2316
|
||||
__kmpc_atomic_float4_add_cpt 2317
|
||||
__kmpc_atomic_float4_sub_cpt 2318
|
||||
__kmpc_atomic_fixed8_add_cpt 2319
|
||||
__kmpc_atomic_fixed8_sub_cpt 2320
|
||||
__kmpc_atomic_float8_add_cpt 2321
|
||||
__kmpc_atomic_float8_sub_cpt 2322
|
||||
__kmpc_atomic_fixed4_andb_cpt 2323
|
||||
__kmpc_atomic_fixed4_div_cpt 2324
|
||||
__kmpc_atomic_fixed4u_div_cpt 2325
|
||||
__kmpc_atomic_fixed4_mul_cpt 2326
|
||||
__kmpc_atomic_fixed4_orb_cpt 2327
|
||||
__kmpc_atomic_fixed4_shl_cpt 2328
|
||||
__kmpc_atomic_fixed4_shr_cpt 2329
|
||||
__kmpc_atomic_fixed4u_shr_cpt 2330
|
||||
__kmpc_atomic_fixed4_xor_cpt 2331
|
||||
__kmpc_atomic_fixed8_andb_cpt 2332
|
||||
__kmpc_atomic_fixed8_div_cpt 2333
|
||||
__kmpc_atomic_fixed8u_div_cpt 2334
|
||||
__kmpc_atomic_fixed8_mul_cpt 2335
|
||||
__kmpc_atomic_fixed8_orb_cpt 2336
|
||||
__kmpc_atomic_fixed8_shl_cpt 2337
|
||||
__kmpc_atomic_fixed8_shr_cpt 2338
|
||||
__kmpc_atomic_fixed8u_shr_cpt 2339
|
||||
__kmpc_atomic_fixed8_xor_cpt 2340
|
||||
__kmpc_atomic_float4_div_cpt 2341
|
||||
__kmpc_atomic_float4_mul_cpt 2342
|
||||
__kmpc_atomic_float8_div_cpt 2343
|
||||
__kmpc_atomic_float8_mul_cpt 2344
|
||||
__kmpc_atomic_fixed1_andl_cpt 2345
|
||||
__kmpc_atomic_fixed1_orl_cpt 2346
|
||||
__kmpc_atomic_fixed2_andl_cpt 2347
|
||||
__kmpc_atomic_fixed2_orl_cpt 2348
|
||||
__kmpc_atomic_fixed4_andl_cpt 2349
|
||||
__kmpc_atomic_fixed4_orl_cpt 2350
|
||||
__kmpc_atomic_fixed8_andl_cpt 2351
|
||||
__kmpc_atomic_fixed8_orl_cpt 2352
|
||||
__kmpc_atomic_fixed1_max_cpt 2353
|
||||
__kmpc_atomic_fixed1_min_cpt 2354
|
||||
__kmpc_atomic_fixed2_max_cpt 2355
|
||||
__kmpc_atomic_fixed2_min_cpt 2356
|
||||
__kmpc_atomic_fixed4_max_cpt 2357
|
||||
__kmpc_atomic_fixed4_min_cpt 2358
|
||||
__kmpc_atomic_fixed8_max_cpt 2359
|
||||
__kmpc_atomic_fixed8_min_cpt 2360
|
||||
__kmpc_atomic_float4_max_cpt 2361
|
||||
__kmpc_atomic_float4_min_cpt 2362
|
||||
__kmpc_atomic_float8_max_cpt 2363
|
||||
__kmpc_atomic_float8_min_cpt 2364
|
||||
%ifdef HAVE_QUAD
|
||||
__kmpc_atomic_float16_max_cpt 2365
|
||||
__kmpc_atomic_float16_min_cpt 2366
|
||||
%endif
|
||||
__kmpc_atomic_fixed1_neqv_cpt 2367
|
||||
__kmpc_atomic_fixed2_neqv_cpt 2368
|
||||
__kmpc_atomic_fixed4_neqv_cpt 2369
|
||||
__kmpc_atomic_fixed8_neqv_cpt 2370
|
||||
__kmpc_atomic_fixed1_eqv_cpt 2371
|
||||
__kmpc_atomic_fixed2_eqv_cpt 2372
|
||||
__kmpc_atomic_fixed4_eqv_cpt 2373
|
||||
__kmpc_atomic_fixed8_eqv_cpt 2374
|
||||
__kmpc_atomic_float10_add_cpt 2375
|
||||
__kmpc_atomic_float10_sub_cpt 2376
|
||||
__kmpc_atomic_float10_mul_cpt 2377
|
||||
__kmpc_atomic_float10_div_cpt 2378
|
||||
%ifdef HAVE_QUAD
|
||||
__kmpc_atomic_float16_add_cpt 2379
|
||||
__kmpc_atomic_float16_sub_cpt 2380
|
||||
__kmpc_atomic_float16_mul_cpt 2381
|
||||
__kmpc_atomic_float16_div_cpt 2382
|
||||
%endif
|
||||
__kmpc_atomic_cmplx4_add_cpt 2383
|
||||
__kmpc_atomic_cmplx4_sub_cpt 2384
|
||||
__kmpc_atomic_cmplx4_mul_cpt 2385
|
||||
__kmpc_atomic_cmplx4_div_cpt 2386
|
||||
__kmpc_atomic_cmplx8_add_cpt 2387
|
||||
__kmpc_atomic_cmplx8_sub_cpt 2388
|
||||
__kmpc_atomic_cmplx8_mul_cpt 2389
|
||||
__kmpc_atomic_cmplx8_div_cpt 2390
|
||||
__kmpc_atomic_cmplx10_add_cpt 2391
|
||||
__kmpc_atomic_cmplx10_sub_cpt 2392
|
||||
__kmpc_atomic_cmplx10_mul_cpt 2393
|
||||
__kmpc_atomic_cmplx10_div_cpt 2394
|
||||
%ifdef HAVE_QUAD
|
||||
__kmpc_atomic_cmplx16_add_cpt 2395
|
||||
__kmpc_atomic_cmplx16_sub_cpt 2396
|
||||
__kmpc_atomic_cmplx16_mul_cpt 2397
|
||||
__kmpc_atomic_cmplx16_div_cpt 2398
|
||||
%endif
|
||||
#__kmpc_atomic_cmplx4_add_cpt_tmp 2409
|
||||
|
||||
%ifdef arch_32
|
||||
%ifdef HAVE_QUAD
|
||||
__kmpc_atomic_float16_add_a16_cpt 2399
|
||||
__kmpc_atomic_float16_sub_a16_cpt 2400
|
||||
__kmpc_atomic_float16_mul_a16_cpt 2401
|
||||
__kmpc_atomic_float16_div_a16_cpt 2402
|
||||
__kmpc_atomic_float16_max_a16_cpt 2403
|
||||
__kmpc_atomic_float16_min_a16_cpt 2404
|
||||
__kmpc_atomic_cmplx16_add_a16_cpt 2405
|
||||
__kmpc_atomic_cmplx16_sub_a16_cpt 2406
|
||||
__kmpc_atomic_cmplx16_mul_a16_cpt 2407
|
||||
__kmpc_atomic_cmplx16_div_a16_cpt 2408
|
||||
%endif
|
||||
%endif
|
||||
|
||||
__kmpc_atomic_start 2410
|
||||
__kmpc_atomic_end 2411
|
||||
|
||||
%ifdef OMP_40
|
||||
|
||||
# ATOMIC extensions for OpenMP 4.0 spec (x86 and x64 only)
|
||||
|
||||
__kmpc_atomic_fixed1_swp 2412
|
||||
__kmpc_atomic_fixed2_swp 2413
|
||||
__kmpc_atomic_fixed4_swp 2414
|
||||
__kmpc_atomic_fixed8_swp 2415
|
||||
__kmpc_atomic_float4_swp 2416
|
||||
__kmpc_atomic_float8_swp 2417
|
||||
__kmpc_atomic_float10_swp 2418
|
||||
%ifdef HAVE_QUAD
|
||||
__kmpc_atomic_float16_swp 2419
|
||||
%endif
|
||||
__kmpc_atomic_cmplx4_swp 2420
|
||||
__kmpc_atomic_cmplx8_swp 2421
|
||||
__kmpc_atomic_cmplx10_swp 2422
|
||||
%ifdef HAVE_QUAD
|
||||
__kmpc_atomic_cmplx16_swp 2423
|
||||
|
||||
%ifdef arch_32
|
||||
__kmpc_atomic_float16_a16_swp 2424
|
||||
__kmpc_atomic_cmplx16_a16_swp 2425
|
||||
%endif
|
||||
%endif
|
||||
|
||||
__kmpc_atomic_fixed1_sub_cpt_rev 2426
|
||||
__kmpc_atomic_fixed1_div_cpt_rev 2427
|
||||
__kmpc_atomic_fixed1u_div_cpt_rev 2428
|
||||
__kmpc_atomic_fixed1_shl_cpt_rev 2429
|
||||
__kmpc_atomic_fixed1_shr_cpt_rev 2430
|
||||
__kmpc_atomic_fixed1u_shr_cpt_rev 2431
|
||||
__kmpc_atomic_fixed2_sub_cpt_rev 2432
|
||||
__kmpc_atomic_fixed2_div_cpt_rev 2433
|
||||
__kmpc_atomic_fixed2u_div_cpt_rev 2434
|
||||
__kmpc_atomic_fixed2_shl_cpt_rev 2435
|
||||
__kmpc_atomic_fixed2_shr_cpt_rev 2436
|
||||
__kmpc_atomic_fixed2u_shr_cpt_rev 2437
|
||||
__kmpc_atomic_fixed4_sub_cpt_rev 2438
|
||||
__kmpc_atomic_fixed4_div_cpt_rev 2439
|
||||
__kmpc_atomic_fixed4u_div_cpt_rev 2440
|
||||
__kmpc_atomic_fixed4_shl_cpt_rev 2441
|
||||
__kmpc_atomic_fixed4_shr_cpt_rev 2442
|
||||
__kmpc_atomic_fixed4u_shr_cpt_rev 2443
|
||||
__kmpc_atomic_fixed8_sub_cpt_rev 2444
|
||||
__kmpc_atomic_fixed8_div_cpt_rev 2445
|
||||
__kmpc_atomic_fixed8u_div_cpt_rev 2446
|
||||
__kmpc_atomic_fixed8_shl_cpt_rev 2447
|
||||
__kmpc_atomic_fixed8_shr_cpt_rev 2448
|
||||
__kmpc_atomic_fixed8u_shr_cpt_rev 2449
|
||||
__kmpc_atomic_float4_sub_cpt_rev 2450
|
||||
__kmpc_atomic_float4_div_cpt_rev 2451
|
||||
__kmpc_atomic_float8_sub_cpt_rev 2452
|
||||
__kmpc_atomic_float8_div_cpt_rev 2453
|
||||
__kmpc_atomic_float10_sub_cpt_rev 2454
|
||||
__kmpc_atomic_float10_div_cpt_rev 2455
|
||||
%ifdef HAVE_QUAD
|
||||
__kmpc_atomic_float16_sub_cpt_rev 2456
|
||||
__kmpc_atomic_float16_div_cpt_rev 2457
|
||||
%endif
|
||||
__kmpc_atomic_cmplx4_sub_cpt_rev 2458
|
||||
__kmpc_atomic_cmplx4_div_cpt_rev 2459
|
||||
__kmpc_atomic_cmplx8_sub_cpt_rev 2460
|
||||
__kmpc_atomic_cmplx8_div_cpt_rev 2461
|
||||
__kmpc_atomic_cmplx10_sub_cpt_rev 2462
|
||||
__kmpc_atomic_cmplx10_div_cpt_rev 2463
|
||||
%ifdef HAVE_QUAD
|
||||
__kmpc_atomic_cmplx16_sub_cpt_rev 2464
|
||||
__kmpc_atomic_cmplx16_div_cpt_rev 2465
|
||||
|
||||
%ifdef arch_32
|
||||
__kmpc_atomic_float16_sub_a16_cpt_rev 2466
|
||||
__kmpc_atomic_float16_div_a16_cpt_rev 2467
|
||||
__kmpc_atomic_cmplx16_sub_a16_cpt_rev 2468
|
||||
__kmpc_atomic_cmplx16_div_a16_cpt_rev 2469
|
||||
%endif
|
||||
%endif
|
||||
|
||||
%endif # OMP_40
|
||||
|
||||
|
||||
%endif # arch_64
|
||||
|
||||
%endif
|
||||
|
||||
# end of file #
|
||||
@@ -0,0 +1,105 @@
|
||||
# exports_so.txt #
|
||||
|
||||
#
|
||||
#//===----------------------------------------------------------------------===//
|
||||
#//
|
||||
#// 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 is version script for OMP RTL shared library (libiomp5*.so)
|
||||
|
||||
VERSION {
|
||||
|
||||
global: # Exported symbols.
|
||||
|
||||
#
|
||||
# "Normal" symbols.
|
||||
#
|
||||
omp_*; # Standard OpenMP functions.
|
||||
ompc_*; # omp.h renames some standard functions to ompc_*.
|
||||
kmp_*; # Intel extensions.
|
||||
kmpc_*; # Intel extensions.
|
||||
__kmpc_*; # Functions called by compiler-generated code.
|
||||
GOMP_*; # GNU C compatibility functions.
|
||||
|
||||
_You_must_link_with_*; # Mutual detection/MS compatibility symbols.
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Internal functions exported for testing purposes.
|
||||
#
|
||||
__kmp_get_reduce_method;
|
||||
___kmp_allocate;
|
||||
___kmp_free;
|
||||
__kmp_thread_pool;
|
||||
__kmp_thread_pool_nth;
|
||||
|
||||
#if USE_ITT_BUILD
|
||||
#
|
||||
# ITT support.
|
||||
#
|
||||
# The following entry points are added so that the backtraces from
|
||||
# the tools contain meaningful names for all the functions that might
|
||||
# appear in a backtrace of a thread which is blocked in the RTL.
|
||||
__kmp_acquire_drdpa_lock;
|
||||
__kmp_acquire_nested_drdpa_lock;
|
||||
__kmp_acquire_nested_queuing_lock;
|
||||
__kmp_acquire_nested_tas_lock;
|
||||
__kmp_acquire_nested_ticket_lock;
|
||||
__kmp_acquire_queuing_lock;
|
||||
__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;
|
||||
__kmp_launch_monitor;
|
||||
__kmp_launch_worker;
|
||||
__kmp_reap_monitor;
|
||||
__kmp_reap_worker;
|
||||
__kmp_release;
|
||||
__kmp_wait_sleep;
|
||||
__kmp_wait_yield_4;
|
||||
__kmp_wait_yield_8;
|
||||
|
||||
# ittnotify symbols to be used by debugger
|
||||
__kmp_itt_fini_ittlib;
|
||||
__kmp_itt_init_ittlib;
|
||||
#endif /* USE_ITT_BUILD */
|
||||
|
||||
local: # Non-exported symbols.
|
||||
|
||||
*; # All other symbols are not exported.
|
||||
|
||||
}; # VERSION
|
||||
|
||||
# sets up GCC OMP_ version dependency chain
|
||||
OMP_1.0 {
|
||||
};
|
||||
OMP_2.0 {
|
||||
} OMP_1.0;
|
||||
OMP_3.0 {
|
||||
} OMP_2.0;
|
||||
OMP_3.1 {
|
||||
} OMP_3.0;
|
||||
OMP_4.0 {
|
||||
} OMP_3.1;
|
||||
|
||||
# sets up GCC GOMP_ version dependency chain
|
||||
GOMP_1.0 {
|
||||
};
|
||||
GOMP_2.0 {
|
||||
} GOMP_1.0;
|
||||
GOMP_3.0 {
|
||||
} GOMP_2.0;
|
||||
GOMP_4.0 {
|
||||
} GOMP_3.0;
|
||||
|
||||
# end of file #
|
||||
@@ -0,0 +1,499 @@
|
||||
/*
|
||||
* extractExternal.cpp
|
||||
* $Revision: 42181 $
|
||||
* $Date: 2013-03-26 15:04:45 -0500 (Tue, 26 Mar 2013) $
|
||||
*/
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 <stdlib.h>
|
||||
#include <iostream>
|
||||
#include <strstream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
/* Given a set of n object files h ('external' object files) and a set of m
|
||||
object files o ('internal' object files),
|
||||
1. Determines r, the subset of h that o depends on, directly or indirectly
|
||||
2. Removes the files in h - r from the file system
|
||||
3. For each external symbol defined in some file in r, rename it in r U o
|
||||
by prefixing it with "__kmp_external_"
|
||||
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.
|
||||
*/
|
||||
|
||||
using namespace std;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
class _rstream : public istrstream {
|
||||
private:
|
||||
const char *buf;
|
||||
protected:
|
||||
_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.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
// string table in a .OBJ file
|
||||
class StringTable {
|
||||
private:
|
||||
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;
|
||||
}
|
||||
}
|
||||
// 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;
|
||||
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;
|
||||
|
||||
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();
|
||||
|
||||
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));
|
||||
memcpy(p, str.c_str(), l);
|
||||
p[l] = 0;
|
||||
p += l + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
~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;
|
||||
strncpy((char*)&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;
|
||||
|
||||
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);
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
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
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
// 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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
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];
|
||||
|
||||
// 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 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;
|
||||
}
|
||||
@@ -0,0 +1,464 @@
|
||||
# en_US.txt #
|
||||
# $Revision: 42659 $
|
||||
# $Date: 2013-09-12 09:22:48 -0500 (Thu, 12 Sep 2013) $
|
||||
|
||||
#
|
||||
#//===----------------------------------------------------------------------===//
|
||||
#//
|
||||
#// 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.
|
||||
#//
|
||||
#//===----------------------------------------------------------------------===//
|
||||
#
|
||||
|
||||
# Default messages, embedded into the OpenMP RTL, and source for English catalog.
|
||||
|
||||
|
||||
# Compatible changes (which does not require version bumping):
|
||||
# * Editing message (number and type of placeholders must remain, relative order of
|
||||
# placeholders may be changed, e.g. "File %1$s line %2$d" may be safely edited to
|
||||
# "Line %2$d file %1$s").
|
||||
# * Adding new message to the end of section.
|
||||
# Incompatible changes (version must be bumbed by 1):
|
||||
# * Introducing new placeholders to existing messages.
|
||||
# * Changing type of placeholders (e.g. "line %1$d" -> "line %1$s").
|
||||
# * Rearranging order of messages.
|
||||
# * Deleting messages.
|
||||
# Use special "OBSOLETE" pseudoidentifier for obsolete entries, which is kept only for backward
|
||||
# compatibility. When version is bumped, do not forget to delete all obsolete entries.
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------------------------------
|
||||
-*- META -*-
|
||||
# --------------------------------------------------------------------------------------------------
|
||||
|
||||
# Meta information about message catalog.
|
||||
|
||||
Language "English"
|
||||
Country "USA"
|
||||
LangId "1033"
|
||||
Version "2"
|
||||
Revision "20130911"
|
||||
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------------------------------
|
||||
-*- STRINGS -*-
|
||||
# --------------------------------------------------------------------------------------------------
|
||||
|
||||
# Strings are not complete messages, just fragments. We need to work on it and reduce number of
|
||||
# strings (to zero?).
|
||||
|
||||
Error "Error"
|
||||
UnknownFile "(unknown file)"
|
||||
NotANumber "not a number"
|
||||
BadUnit "bad unit"
|
||||
IllegalCharacters "illegal characters"
|
||||
ValueTooLarge "value too large"
|
||||
ValueTooSmall "value too small"
|
||||
NotMultiple4K "value is not a multiple of 4k"
|
||||
UnknownTopology "Unknown processor topology"
|
||||
CantOpenCpuinfo "Cannot open /proc/cpuinfo"
|
||||
ProcCpuinfo "/proc/cpuinfo"
|
||||
NoProcRecords "cpuinfo file invalid (No processor records)"
|
||||
TooManyProcRecords "cpuinfo file invalid (Too many processor records)"
|
||||
CantRewindCpuinfo "Cannot rewind cpuinfo file"
|
||||
LongLineCpuinfo "cpuinfo file invalid (long line)"
|
||||
TooManyEntries "cpuinfo file contains too many entries"
|
||||
MissingProcField "cpuinfo file missing processor field"
|
||||
MissingPhysicalIDField "cpuinfo file missing physical id field"
|
||||
MissingValCpuinfo "cpuinfo file invalid (missing val)"
|
||||
DuplicateFieldCpuinfo "cpuinfo file invalid (duplicate field)"
|
||||
PhysicalIDsNotUnique "Physical node/pkg/core/thread ids not unique"
|
||||
ApicNotPresent "APIC not present"
|
||||
InvalidCpuidInfo "Invalid cpuid info"
|
||||
OBSOLETE "APIC ids not unique"
|
||||
InconsistentCpuidInfo "Inconsistent cpuid info"
|
||||
OutOfHeapMemory "Out of heap memory"
|
||||
MemoryAllocFailed "Memory allocation failed"
|
||||
Core "core"
|
||||
Thread "thread"
|
||||
Package "package"
|
||||
Node "node"
|
||||
OBSOLETE "<undef>"
|
||||
DecodingLegacyAPIC "decoding legacy APIC ids"
|
||||
OBSOLETE "parsing /proc/cpuinfo"
|
||||
NotDefined "value is not defined"
|
||||
EffectiveSettings "Effective settings:"
|
||||
UserSettings "User settings:"
|
||||
StorageMapWarning "warning: pointers or size don't make sense"
|
||||
OBSOLETE "CPU"
|
||||
OBSOLETE "TPU"
|
||||
OBSOLETE "TPUs per package"
|
||||
OBSOLETE "HT enabled"
|
||||
OBSOLETE "HT disabled"
|
||||
Decodingx2APIC "decoding x2APIC ids"
|
||||
NoLeaf11Support "cpuid leaf 11 not supported"
|
||||
NoLeaf4Support "cpuid leaf 4 not supported"
|
||||
ThreadIDsNotUnique "thread ids not unique"
|
||||
UsingPthread "using pthread info"
|
||||
LegacyApicIDsNotUnique "legacy APIC ids not unique"
|
||||
x2ApicIDsNotUnique "x2APIC ids not unique"
|
||||
DisplayEnvBegin "OPENMP DISPLAY ENVIRONMENT BEGIN"
|
||||
DisplayEnvEnd "OPENMP DISPLAY ENVIRONMENT END"
|
||||
Device "[device]"
|
||||
Host "[host]"
|
||||
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------------------------------
|
||||
-*- FORMATS -*-
|
||||
# --------------------------------------------------------------------------------------------------
|
||||
|
||||
Info "OMP: Info #%1$d: %2$s\n"
|
||||
Warning "OMP: Warning #%1$d: %2$s\n"
|
||||
Fatal "OMP: Error #%1$d: %2$s\n"
|
||||
SysErr "OMP: System error #%1$d: %2$s\n"
|
||||
Hint "OMP: Hint: %2$s\n"
|
||||
|
||||
Pragma "%1$s pragma (at %2$s:%3$s():%4$s)"
|
||||
# %1 is pragma name (like "parallel" or "master",
|
||||
# %2 is file name,
|
||||
# %3 is function (routine) name,
|
||||
# %4 is the line number (as string, so "s" type specifier should be used).
|
||||
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------------------------------
|
||||
-*- MESSAGES -*-
|
||||
# --------------------------------------------------------------------------------------------------
|
||||
|
||||
# Messages of any severity: informational, warning, or fatal.
|
||||
# To maintain message numbers (they are visible to customers), add new messages to the end.
|
||||
|
||||
# Use following prefixes for messages and hints when appropriate:
|
||||
# Aff -- Affinity messages.
|
||||
# Cns -- Consistency check failures (KMP_CONSISTENCY_CHECK).
|
||||
# Itt -- ITT Notify-related messages.
|
||||
# Rml -- RML-related messages.
|
||||
|
||||
LibraryIsSerial "Library is \"serial\"."
|
||||
CantOpenMessageCatalog "Cannot open message catalog \"%1$s\":"
|
||||
WillUseDefaultMessages "Default messages will be used."
|
||||
LockIsUninitialized "%1$s: Lock is uninitialized"
|
||||
LockSimpleUsedAsNestable "%1$s: Lock was initialized as simple, but used as nestable"
|
||||
LockNestableUsedAsSimple "%1$s: Lock was initialized as nestable, but used as simple"
|
||||
LockIsAlreadyOwned "%1$s: Lock is already owned by requesting thread"
|
||||
LockStillOwned "%1$s: Lock is still owned by a thread"
|
||||
LockUnsettingFree "%1$s: Attempt to release a lock not owned by any thread"
|
||||
LockUnsettingSetByAnother "%1$s: Attempt to release a lock owned by another thread"
|
||||
StackOverflow "Stack overflow detected for OpenMP thread #%1$d"
|
||||
StackOverlap "Stack overlap detected. "
|
||||
AssertionFailure "Assertion failure at %1$s(%2$d)."
|
||||
CantRegisterNewThread "Unable to register a new user thread."
|
||||
DuplicateLibrary "Initializing %1$s, but found %2$s already initialized."
|
||||
CantOpenFileForReading "Cannot open file \"%1$s\" for reading:"
|
||||
CantGetEnvVar "Getting environment variable \"%1$s\" failed:"
|
||||
CantSetEnvVar "Setting environment variable \"%1$s\" failed:"
|
||||
CantGetEnvironment "Getting environment failed:"
|
||||
BadBoolValue "%1$s=\"%2$s\": Wrong value, boolean expected."
|
||||
SSPNotBuiltIn "No Helper Thread support built in this OMP library."
|
||||
SPPSotfTerminateFailed "Helper thread failed to soft terminate."
|
||||
BufferOverflow "Buffer overflow detected."
|
||||
RealTimeSchedNotSupported "Real-time scheduling policy is not supported."
|
||||
RunningAtMaxPriority "OMP application is running at maximum priority with real-time scheduling policy. "
|
||||
CantChangeMonitorPriority "Changing priority of the monitor thread failed:"
|
||||
MonitorWillStarve "Deadlocks are highly possible due to monitor thread starvation."
|
||||
CantSetMonitorStackSize "Unable to set monitor thread stack size to %1$lu bytes:"
|
||||
CantSetWorkerStackSize "Unable to set OMP thread stack size to %1$lu bytes:"
|
||||
CantInitThreadAttrs "Thread attribute initialization failed:"
|
||||
CantDestroyThreadAttrs "Thread attribute destroying failed:"
|
||||
CantSetWorkerState "OMP thread joinable state setting failed:"
|
||||
CantSetMonitorState "Monitor thread joinable state setting failed:"
|
||||
NoResourcesForWorkerThread "System unable to allocate necessary resources for OMP thread:"
|
||||
NoResourcesForMonitorThread "System unable to allocate necessary resources for the monitor thread:"
|
||||
CantTerminateWorkerThread "Unable to terminate OMP thread:"
|
||||
ScheduleKindOutOfRange "Wrong schedule type %1$d, see <omp.h> or <omp_lib.h> file for the list of values supported."
|
||||
UnknownSchedulingType "Unknown scheduling type \"%1$d\"."
|
||||
InvalidValue "%1$s value \"%2$s\" is invalid."
|
||||
SmallValue "%1$s value \"%2$s\" is too small."
|
||||
LargeValue "%1$s value \"%2$s\" is too large."
|
||||
StgInvalidValue "%1$s: \"%2$s\" is an invalid value; ignored."
|
||||
BarrReleaseValueInvalid "%1$s release value \"%2$s\" is invalid."
|
||||
BarrGatherValueInvalid "%1$s gather value \"%2$s\" is invalid."
|
||||
OBSOLETE "%1$s supported only on debug builds; ignored."
|
||||
ParRangeSyntax "Syntax error: Usage: %1$s=[ routine=<func> | filename=<file> | range=<lb>:<ub> "
|
||||
"| excl_range=<lb>:<ub> ],..."
|
||||
UnbalancedQuotes "Unbalanced quotes in %1$s."
|
||||
EmptyString "Empty string specified for %1$s; ignored."
|
||||
LongValue "%1$s value is too long; ignored."
|
||||
InvalidClause "%1$s: Invalid clause in \"%2$s\"."
|
||||
EmptyClause "Empty clause in %1$s."
|
||||
InvalidChunk "%1$s value \"%2$s\" is invalid chunk size."
|
||||
LargeChunk "%1$s value \"%2$s\" is to large chunk size."
|
||||
IgnoreChunk "%1$s value \"%2$s\" is ignored."
|
||||
CantGetProcFreq "Cannot get processor frequency, using zero KMP_ITT_PREPARE_DELAY."
|
||||
EnvParallelWarn "%1$s must be set prior to first parallel region; ignored."
|
||||
AffParamDefined "%1$s: parameter has been specified already, ignoring \"%2$s\"."
|
||||
AffInvalidParam "%1$s: parameter invalid, ignoring \"%2$s\"."
|
||||
AffManyParams "%1$s: too many integer parameters specified, ignoring \"%2$s\"."
|
||||
AffManyParamsForLogic "%1$s: too many integer parameters specified for logical or physical type, ignoring \"%2$d\"."
|
||||
AffNoParam "%1$s: '%2$s' type does not take any integer parameters, ignoring them."
|
||||
AffNoProcList "%1$s: proclist not specified with explicit affinity type, using \"none\"."
|
||||
AffProcListNoType "%1$s: proclist specified, setting affinity type to \"explicit\"."
|
||||
AffProcListNotExplicit "%1$s: proclist specified without \"explicit\" affinity type, proclist ignored."
|
||||
AffSyntaxError "%1$s: syntax error, not using affinity."
|
||||
AffZeroStride "%1$s: range error (zero stride), not using affinity."
|
||||
AffStartGreaterEnd "%1$s: range error (%2$d > %3$d), not using affinity."
|
||||
AffStrideLessZero "%1$s: range error (%2$d < %3$d & stride < 0), not using affinity."
|
||||
AffRangeTooBig "%1$s: range error ((%2$d-%3$d)/%4$d too big), not using affinity."
|
||||
OBSOLETE "%1$s: %2$s is defined. %3$s will be ignored."
|
||||
AffNotSupported "%1$s: affinity not supported, using \"disabled\"."
|
||||
OBSOLETE "%1$s: affinity only supported for Intel(R) processors."
|
||||
GetAffSysCallNotSupported "%1$s: getaffinity system call not supported."
|
||||
SetAffSysCallNotSupported "%1$s: setaffinity system call not supported."
|
||||
OBSOLETE "%1$s: pthread_aff_set_np call not found."
|
||||
OBSOLETE "%1$s: pthread_get_num_resources_np call not found."
|
||||
OBSOLETE "%1$s: the OS kernel does not support affinity."
|
||||
OBSOLETE "%1$s: pthread_get_num_resources_np returned %2$d."
|
||||
AffCantGetMaskSize "%1$s: cannot determine proper affinity mask size."
|
||||
ParseSizeIntWarn "%1$s=\"%2$s\": %3$s."
|
||||
ParseExtraCharsWarn "%1$s: extra trailing characters ignored: \"%2$s\"."
|
||||
UnknownForceReduction "%1$s: unknown method \"%2$s\"."
|
||||
TimerUseGettimeofday "KMP_STATS_TIMER: clock_gettime is undefined, using gettimeofday."
|
||||
TimerNeedMoreParam "KMP_STATS_TIMER: \"%1$s\" needs additional parameter, e.g. 'clock_gettime,2'. Using gettimeofday."
|
||||
TimerInvalidParam "KMP_STATS_TIMER: clock_gettime parameter \"%1$s\" is invalid, using gettimeofday."
|
||||
TimerGettimeFailed "KMP_STATS_TIMER: clock_gettime failed, using gettimeofday."
|
||||
TimerUnknownFunction "KMP_STATS_TIMER: clock function unknown (ignoring value \"%1$s\")."
|
||||
UnknownSchedTypeDetected "Unknown scheduling type detected."
|
||||
DispatchManyThreads "Too many threads to use analytical guided scheduling - switching to iterative guided scheduling."
|
||||
IttLookupFailed "ittnotify: Lookup of \"%1$s\" function in \"%2$s\" library failed."
|
||||
IttLoadLibFailed "ittnotify: Loading \"%1$s\" library failed."
|
||||
IttAllNotifDisabled "ittnotify: All itt notifications disabled."
|
||||
IttObjNotifDisabled "ittnotify: Object state itt notifications disabled."
|
||||
IttMarkNotifDisabled "ittnotify: Mark itt notifications disabled."
|
||||
IttUnloadLibFailed "ittnotify: Unloading \"%1$s\" library failed."
|
||||
CantFormThrTeam "Cannot form a team with %1$d threads, using %2$d instead."
|
||||
ActiveLevelsNegative "Requested number of active parallel levels \"%1$d\" is negative; ignored."
|
||||
ActiveLevelsExceedLimit "Requested number of active parallel levels \"%1$d\" exceeds supported limit; "
|
||||
"the following limit value will be used: \"%1$d\"."
|
||||
SetLibraryIncorrectCall "kmp_set_library must only be called from the top level serial thread; ignored."
|
||||
FatalSysError "Fatal system error detected."
|
||||
OutOfHeapMemory "Out of heap memory."
|
||||
OBSOLETE "Clearing __KMP_REGISTERED_LIB env var failed."
|
||||
OBSOLETE "Registering library with env var failed."
|
||||
Using_int_Value "%1$s value \"%2$d\" will be used."
|
||||
Using_uint_Value "%1$s value \"%2$u\" will be used."
|
||||
Using_uint64_Value "%1$s value \"%2$s\" will be used."
|
||||
Using_str_Value "%1$s value \"%2$s\" will be used."
|
||||
MaxValueUsing "%1$s maximum value \"%2$d\" will be used."
|
||||
MinValueUsing "%1$s minimum value \"%2$d\" will be used."
|
||||
MemoryAllocFailed "Memory allocation failed."
|
||||
FileNameTooLong "File name too long."
|
||||
OBSOLETE "Lock table overflow."
|
||||
ManyThreadsForTPDirective "Too many threads to use threadprivate directive."
|
||||
AffinityInvalidMask "%1$s: invalid mask."
|
||||
WrongDefinition "Wrong definition."
|
||||
TLSSetValueFailed "Windows* OS: TLS Set Value failed."
|
||||
TLSOutOfIndexes "Windows* OS: TLS out of indexes."
|
||||
OBSOLETE "PDONE directive must be nested within a DO directive."
|
||||
CantGetNumAvailCPU "Cannot get number of available CPUs."
|
||||
AssumedNumCPU "Assumed number of CPUs is 2."
|
||||
ErrorInitializeAffinity "Error initializing affinity - not using affinity."
|
||||
AffThreadsMayMigrate "Threads may migrate across all available OS procs (granularity setting too coarse)."
|
||||
AffIgnoreInvalidProcID "Ignoring invalid OS proc ID %1$d."
|
||||
AffNoValidProcID "No valid OS proc IDs specified - not using affinity."
|
||||
UsingFlatOS "%1$s - using \"flat\" OS <-> physical proc mapping."
|
||||
UsingFlatOSFile "%1$s: %2$s - using \"flat\" OS <-> physical proc mapping."
|
||||
UsingFlatOSFileLine "%1$s, line %2$d: %3$s - using \"flat\" OS <-> physical proc mapping."
|
||||
FileMsgExiting "%1$s: %2$s - exiting."
|
||||
FileLineMsgExiting "%1$s, line %2$d: %3$s - exiting."
|
||||
ConstructIdentInvalid "Construct identifier invalid."
|
||||
ThreadIdentInvalid "Thread identifier invalid."
|
||||
RTLNotInitialized "runtime library not initialized."
|
||||
TPCommonBlocksInconsist "Inconsistent THREADPRIVATE common block declarations are non-conforming "
|
||||
"and are unsupported. Either all threadprivate common blocks must be declared "
|
||||
"identically, or the largest instance of each threadprivate common block "
|
||||
"must be referenced first during the run."
|
||||
CantSetThreadAffMask "Cannot set thread affinity mask."
|
||||
CantSetThreadPriority "Cannot set thread priority."
|
||||
CantCreateThread "Cannot create thread."
|
||||
CantCreateEvent "Cannot create event."
|
||||
CantSetEvent "Cannot set event."
|
||||
CantCloseHandle "Cannot close handle."
|
||||
UnknownLibraryType "Unknown library type: %1$d."
|
||||
ReapMonitorError "Monitor did not reap properly."
|
||||
ReapWorkerError "Worker thread failed to join."
|
||||
ChangeThreadAffMaskError "Cannot change thread affinity mask."
|
||||
ThreadsMigrate "%1$s: Threads may migrate across %2$d innermost levels of machine"
|
||||
DecreaseToThreads "%1$s: decrease to %2$d threads"
|
||||
IncreaseToThreads "%1$s: increase to %2$d threads"
|
||||
BoundToOSProcSet "%1$s: Internal thread %2$d bound to OS proc set %3$s"
|
||||
AffCapableUseCpuinfo "%1$s: Affinity capable, using cpuinfo file"
|
||||
AffUseGlobCpuid "%1$s: Affinity capable, using global cpuid info"
|
||||
AffCapableUseFlat "%1$s: Affinity capable, using default \"flat\" topology"
|
||||
AffNotCapableUseLocCpuid "%1$s: Affinity not capable, using local cpuid info"
|
||||
AffNotCapableUseCpuinfo "%1$s: Affinity not capable, using cpuinfo file"
|
||||
AffFlatTopology "%1$s: Affinity not capable, assumming \"flat\" topology"
|
||||
InitOSProcSetRespect "%1$s: Initial OS proc set respected: %2$s"
|
||||
InitOSProcSetNotRespect "%1$s: Initial OS proc set not respected: %2$s"
|
||||
AvailableOSProc "%1$s: %2$d available OS procs"
|
||||
Uniform "%1$s: Uniform topology"
|
||||
NonUniform "%1$s: Nonuniform topology"
|
||||
Topology "%1$s: %2$d packages x %3$d cores/pkg x %4$d threads/core (%5$d total cores)"
|
||||
OBSOLETE "%1$s: OS proc to physical thread map ([] => level not in map):"
|
||||
OSProcToPackage "%1$s: OS proc <n> maps to <n>th package core 0"
|
||||
OBSOLETE "%1$s: OS proc %2$d maps to package %3$d [core %4$d] [thread %5$d]"
|
||||
OBSOLETE "%1$s: OS proc %2$d maps to [package %3$d] [core %4$d] [thread %5$d]"
|
||||
OBSOLETE "%1$s: OS proc %2$d maps to [package %3$d] [core %4$d] thread %5$d"
|
||||
OBSOLETE "%1$s: OS proc %2$d maps to [package %3$d] core %4$d [thread %5$d]"
|
||||
OBSOLETE "%1$s: OS proc %2$d maps to package %3$d [core %4$d] [thread %5$d]"
|
||||
OBSOLETE "%1$s: OS proc %2$d maps to [package %3$d] core %4$d thread %5$d"
|
||||
OBSOLETE "%1$s: OS proc %2$d maps to package %3$d core %4$d [thread %5$d]"
|
||||
OBSOLETE "%1$s: OS proc %2$d maps to package %3$d [core %4$d] thread %5$d"
|
||||
OBSOLETE "%1$s: OS proc %2$d maps to package %3$d core %4$d thread %5$d"
|
||||
OSProcMapToPack "%1$s: OS proc %2$d maps to %3$s"
|
||||
ChangeAffMask "%1$s: Internal thread %2$d changed affinity mask from %3$s to %4$s"
|
||||
OBSOLETE "%1$s: OS proc %2$d maps to package %3$d, CPU %4$d, TPU %5$d"
|
||||
OBSOLETE "%1$s: OS proc %2$d maps to package %3$d, CPU %4$d"
|
||||
OBSOLETE "%1$s: HT enabled; %2$d packages; %3$d TPU; %4$d TPUs per package"
|
||||
OBSOLETE "%1$s: HT disabled; %2$d packages"
|
||||
BarriersInDifferentOrder "Threads encountered barriers in different order. "
|
||||
FunctionError "Function %1$s failed:"
|
||||
TopologyExtra "%1$s: %2$s packages x %3$d cores/pkg x %4$d threads/core (%5$d total cores)"
|
||||
WrongMessageCatalog "Incompatible message catalog \"%1$s\": Version \"%2$s\" found, version \"%3$s\" expected."
|
||||
StgIgnored "%1$s: ignored because %3$s has been defined"
|
||||
# %1, %2 -- name and value of ignored variable, %3 -- name of variable with higher priority.
|
||||
OBSOLETE "%1$s: overrides %3$s specified before"
|
||||
# %1, %2 -- name and value of the overriding variable, %3 -- name of overriden variable.
|
||||
|
||||
# --- OpenMP errors detected at runtime ---
|
||||
#
|
||||
# %1 is the name of OpenMP construct (formatted with "Pragma" format).
|
||||
#
|
||||
CnsBoundToWorksharing "%1$s must be bound to a work-sharing or work-queuing construct with an \"ordered\" clause"
|
||||
CnsDetectedEnd "Detected end of %1$s without first executing a corresponding beginning."
|
||||
CnsIterationRangeTooLarge "Iteration range too large in %1$s."
|
||||
CnsLoopIncrZeroProhibited "%1$s must not have a loop increment that evaluates to zero."
|
||||
#
|
||||
# %1 is the name of the first OpenMP construct, %2 -- the name of the second one (both formatted with "Pragma" format).
|
||||
#
|
||||
CnsExpectedEnd "Expected end of %1$s; %2$s, however, has most recently begun execution."
|
||||
CnsInvalidNesting "%1$s is incorrectly nested within %2$s"
|
||||
CnsMultipleNesting "%1$s cannot be executed multiple times during execution of one parallel iteration/section of %2$s"
|
||||
CnsNestingSameName "%1$s is incorrectly nested within %2$s of the same name"
|
||||
CnsNoOrderedClause "%1$s is incorrectly nested within %2$s that does not have an \"ordered\" clause"
|
||||
CnsNotInTaskConstruct "%1$s is incorrectly nested within %2$s but not within any of its \"task\" constructs"
|
||||
CnsThreadsAtBarrier "One thread at %1$s while another thread is at %2$s."
|
||||
|
||||
# New errors
|
||||
CantConnect "Cannot connect to %1$s"
|
||||
CantConnectUsing "Cannot connect to %1$s - Using %2$s"
|
||||
LibNotSupport "%1$s does not support %2$s. Continuing without using %2$s."
|
||||
LibNotSupportFor "%1$s does not support %2$s for %3$s. Continuing without using %2$s."
|
||||
StaticLibNotSupport "Static %1$s does not support %2$s. Continuing without using %2$s."
|
||||
DynIRMLwoUseIrml "KMP_DYNAMIC_MODE=irml cannot be used with KMP_USE_IRML=0"
|
||||
IttUnknownGroup "ittnotify: Unknown group \"%2$s\" specified in environment variable \"%1$s\"."
|
||||
IttEnvVarTooLong "ittnotify: Environment variable \"%1$s\" too long: Actual lengths is %2$lu, max allowed length is %3$lu."
|
||||
AffUseGlobCpuidL11 "%1$s: Affinity capable, using global cpuid leaf 11 info"
|
||||
AffNotCapableUseLocCpuidL11 "%1$s: Affinity not capable, using local cpuid leaf 11 info"
|
||||
AffInfoStr "%1$s: %2$s."
|
||||
AffInfoStrStr "%1$s: %2$s - %3$s."
|
||||
OSProcToPhysicalThreadMap "%1$s: OS proc to physical thread map:"
|
||||
AffUsingFlatOS "%1$s: using \"flat\" OS <-> physical proc mapping."
|
||||
AffParseFilename "%1$s: parsing %2$s."
|
||||
MsgExiting "%1$s - exiting."
|
||||
IncompatibleLibrary "Incompatible %1$s library with version %2$s found."
|
||||
IttFunctionError "ittnotify: Function %1$s failed:"
|
||||
IttUnknownError "ittnofify: Error #%1$d."
|
||||
EnvMiddleWarn "%1$s must be set prior to first parallel region or certain API calls; ignored."
|
||||
CnsLockNotDestroyed "Lock initialized at %1$s(%3$d) was not destroyed"
|
||||
# %1, %2, %3, %4 -- file, func, line, col
|
||||
CantLoadBalUsing "Cannot determine machine load balance - Using %1$s"
|
||||
AffNotCapableUsePthread "%1$s: Affinity not capable, using pthread info"
|
||||
AffUsePthread "%1$s: Affinity capable, using pthread info"
|
||||
RmlLoadLibFailed "Loading \"%1$s\" library failed:"
|
||||
RmlLookupFailed "Lookup of \"%1$s\" function failed:"
|
||||
RmlBufferTooSmall "Buffer too small."
|
||||
RmlUnknownError "Error #%1$d."
|
||||
NthSyntaxError "%1$s: Invalid symbols found. Check the value \"%2$s\"."
|
||||
NthSpacesNotAllowed "%1$s: Spaces between digits are not allowed \"%2$s\"."
|
||||
AffStrParseFilename "%1$s: %2$s - parsing %3$s."
|
||||
OBSOLETE "%1$s cannot be specified via kmp_set_defaults() on this machine because it has more than one processor group."
|
||||
AffTypeCantUseMultGroups "Cannot use affinity type \"%1$s\" with multiple Windows* OS processor groups, using \"%2$s\"."
|
||||
AffGranCantUseMultGroups "Cannot use affinity granularity \"%1$s\" with multiple Windows* OS processor groups, using \"%2$s\"."
|
||||
AffWindowsProcGroupMap "%1$s: Mapping Windows* OS processor group <i> proc <j> to OS proc 64*<i>+<j>."
|
||||
AffOSProcToGroup "%1$s: OS proc %2$d maps to Windows* OS processor group %3$d proc %4$d"
|
||||
AffBalancedNotAvail "%1$s: Affinity balanced is not available."
|
||||
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."
|
||||
AffThrPlaceInvalid "%1$s: invalid value \"%2$s\", valid format is \"nC,mT[,kO]\"."
|
||||
AffThrPlaceUnsupported "KMP_PLACE_THREADS ignored: unsupported architecture."
|
||||
AffThrPlaceManyCores "KMP_PLACE_THREADS 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\"."
|
||||
|
||||
# --------------------------------------------------------------------------------------------------
|
||||
-*- HINTS -*-
|
||||
# --------------------------------------------------------------------------------------------------
|
||||
|
||||
# Hints. Hint may be printed after a message. Usually it is longer explanation text or suggestion.
|
||||
# To maintain hint numbers (they are visible to customers), add new hints to the end.
|
||||
|
||||
SubmitBugReport "Please submit a bug report with this message, compile and run "
|
||||
"commands used, and machine configuration info including native "
|
||||
"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/."
|
||||
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."
|
||||
Unset_ALL_THREADS "Consider unsetting KMP_ALL_THREADS and OMP_THREAD_LIMIT (if either is set)."
|
||||
Set_ALL_THREADPRIVATE "Consider setting KMP_ALL_THREADPRIVATE to a value larger than %1$d."
|
||||
PossibleSystemLimitOnThreads "This could also be due to a system-related limit on the number of threads."
|
||||
DuplicateLibrary "This means that multiple copies of the OpenMP runtime have been "
|
||||
"linked into the program. That is dangerous, since it can degrade "
|
||||
"performance or cause incorrect results. "
|
||||
"The best thing to do is to ensure that only a single OpenMP runtime is "
|
||||
"linked into the process, e.g. by avoiding static linking of the OpenMP "
|
||||
"runtime in any library. As an unsafe, unsupported, undocumented workaround "
|
||||
"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/."
|
||||
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, "
|
||||
"\"1\", \"TRUE\", \".T.\", \"on\", \"yes\" as true values."
|
||||
BufferOverflow "Perhaps too many threads."
|
||||
RunningAtMaxPriority "Decrease priority of application. "
|
||||
"This will allow the monitor thread run at higher priority than other threads."
|
||||
ChangeMonitorStackSize "Try changing KMP_MONITOR_STACKSIZE or the shell stack limit."
|
||||
ChangeWorkerStackSize "Try changing OMP_STACKSIZE and/or the shell stack limit."
|
||||
IncreaseWorkerStackSize "Try increasing OMP_STACKSIZE or the shell stack limit."
|
||||
DecreaseWorkerStackSize "Try decreasing OMP_STACKSIZE."
|
||||
Decrease_NUM_THREADS "Try decreasing the value of OMP_NUM_THREADS."
|
||||
IncreaseMonitorStackSize "Try increasing KMP_MONITOR_STACKSIZE."
|
||||
DecreaseMonitorStackSize "Try decreasing KMP_MONITOR_STACKSIZE."
|
||||
DecreaseNumberOfThreadsInUse "Try decreasing the number of threads in use simultaneously."
|
||||
DefaultScheduleKindUsed "Will use default schedule type (%1$s)."
|
||||
GetNewerLibrary "It could be a result of using an older OMP library with a newer "
|
||||
"compiler or memory corruption. You may check the proper OMP library "
|
||||
"is linked to the application."
|
||||
CheckEnvVar "Check %1$s environment variable, its value is \"%2$s\"."
|
||||
GetNewerIOMPLibrary "You may want to use an %1$s library that supports %2$s interface with version %3$s."
|
||||
GetNewerIRMLLibrary "You may want to use an %1$s library with version %2$s."
|
||||
BadExeFormat "System error #193 is \"Bad format of EXE or DLL file\". "
|
||||
"Usually it means the file is found, but it is corrupted or "
|
||||
"a file for another architecture. "
|
||||
"Check whether \"%1$s\" is a file for %2$s architecture."
|
||||
SystemLimitOnThreads "System-related limit on the number of threads."
|
||||
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------------------------------
|
||||
# end of file #
|
||||
# --------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* include/25/iomp.h.var
|
||||
* $Revision: 42061 $
|
||||
* $Date: 2013-02-28 16:36:24 -0600 (Thu, 28 Feb 2013) $
|
||||
*/
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 __IOMP_H
|
||||
# define __IOMP_H
|
||||
|
||||
# define KMP_VERSION_MAJOR $KMP_VERSION_MAJOR
|
||||
# define KMP_VERSION_MINOR $KMP_VERSION_MINOR
|
||||
# define KMP_VERSION_BUILD $KMP_VERSION_BUILD
|
||||
# define KMP_BUILD_DATE "$KMP_BUILD_DATE"
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif
|
||||
|
||||
# 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_malloc kmpc_malloc
|
||||
# define kmp_calloc kmpc_calloc
|
||||
# define kmp_realloc kmpc_realloc
|
||||
# define kmp_free kmpc_free
|
||||
|
||||
# if defined(_WIN32)
|
||||
# define __KAI_KMPC_CONVENTION __cdecl
|
||||
# else
|
||||
# define __KAI_KMPC_CONVENTION
|
||||
# endif
|
||||
|
||||
# include <stdlib.h>
|
||||
/* 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_malloc (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 /* __IOMP_H */
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
! include/25/iomp_lib.h.var
|
||||
! $Revision: 42061 $
|
||||
! $Date: 2013-02-28 16:36:24 -0600 (Thu, 28 Feb 2013) $
|
||||
|
||||
!
|
||||
!//===----------------------------------------------------------------------===//
|
||||
!//
|
||||
!// 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.
|
||||
!//
|
||||
!//===----------------------------------------------------------------------===//
|
||||
!
|
||||
|
||||
!***
|
||||
!*** omp_integer_kind and omp_logical_kind appear to be predefined by gcc and
|
||||
!*** gfortran (definitions do not appear in the omp.h / omp_lib.h /omp_lib.f).
|
||||
!*** omp_real_kind is not predefined, however.
|
||||
!***
|
||||
|
||||
integer, parameter :: kmp_version_major = $KMP_VERSION_MAJOR
|
||||
integer, parameter :: kmp_version_minor = $KMP_VERSION_MINOR
|
||||
integer, parameter :: kmp_version_build = $KMP_VERSION_BUILD
|
||||
character(*) kmp_build_date
|
||||
parameter( kmp_build_date = '$KMP_BUILD_DATE' )
|
||||
|
||||
integer, parameter :: omp_real_kind = 4
|
||||
|
||||
!***
|
||||
!*** kmp_* type extensions
|
||||
!***
|
||||
|
||||
integer, parameter :: kmp_pointer_kind = $KMP_INT_PTR_KIND
|
||||
integer, parameter :: kmp_size_t_kind = $KMP_INT_PTR_KIND
|
||||
|
||||
!***
|
||||
!*** kmp_* entry points
|
||||
!***
|
||||
|
||||
external kmp_set_stacksize
|
||||
external kmp_set_stacksize_s
|
||||
external kmp_set_blocktime
|
||||
external kmp_set_library_serial
|
||||
external kmp_set_library_turnaround
|
||||
external kmp_set_library_throughput
|
||||
external kmp_set_library
|
||||
external kmp_set_defaults
|
||||
external kmp_get_stacksize
|
||||
integer kmp_get_stacksize
|
||||
external kmp_get_stacksize_s
|
||||
integer (kind = kmp_size_t_kind) kmp_get_stacksize_s
|
||||
external kmp_get_blocktime
|
||||
integer kmp_get_blocktime
|
||||
external kmp_get_library
|
||||
integer kmp_get_library
|
||||
external kmp_malloc
|
||||
integer (kind = kmp_pointer_kind) kmp_malloc
|
||||
external kmp_calloc
|
||||
integer (kind = kmp_pointer_kind) kmp_calloc
|
||||
external kmp_realloc
|
||||
integer (kind = kmp_pointer_kind) kmp_realloc
|
||||
external kmp_free
|
||||
external kmp_set_warnings_on
|
||||
external kmp_set_warnings_off
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* include/25/omp.h.var
|
||||
* $Revision: 42061 $
|
||||
* $Date: 2013-02-28 16:36:24 -0600 (Thu, 28 Feb 2013) $
|
||||
*/
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 $KMP_VERSION_MAJOR
|
||||
# define KMP_VERSION_MINOR $KMP_VERSION_MINOR
|
||||
# define KMP_VERSION_BUILD $KMP_VERSION_BUILD
|
||||
# define KMP_BUILD_DATE "$KMP_BUILD_DATE"
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif
|
||||
|
||||
# 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_malloc kmpc_malloc
|
||||
# define kmp_calloc kmpc_calloc
|
||||
# define kmp_realloc kmpc_realloc
|
||||
# define kmp_free kmpc_free
|
||||
|
||||
|
||||
# if defined(_WIN32)
|
||||
# define __KAI_KMPC_CONVENTION __cdecl
|
||||
# else
|
||||
# define __KAI_KMPC_CONVENTION
|
||||
# endif
|
||||
|
||||
/* 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);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* 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 *);
|
||||
|
||||
/* time API functions */
|
||||
extern double __KAI_KMPC_CONVENTION omp_get_wtime (void);
|
||||
extern double __KAI_KMPC_CONVENTION omp_get_wtick (void);
|
||||
|
||||
# include <stdlib.h>
|
||||
/* 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_malloc (size_t);
|
||||
extern void * __KAI_KMPC_CONVENTION kmp_calloc (size_t, size_t);
|
||||
extern void * __KAI_KMPC_CONVENTION kmp_realloc (void *, size_t);
|
||||
extern void __KAI_KMPC_CONVENTION kmp_free (void *);
|
||||
|
||||
extern void __KAI_KMPC_CONVENTION kmp_set_warnings_on(void);
|
||||
extern void __KAI_KMPC_CONVENTION kmp_set_warnings_off(void);
|
||||
|
||||
# undef __KAI_KMPC_CONVENTION
|
||||
|
||||
/* Warning:
|
||||
The following typedefs are not standard, deprecated and will be removed in a future release.
|
||||
*/
|
||||
typedef int omp_int_t;
|
||||
typedef double omp_wtime_t;
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
|
||||
#endif /* __OMP_H */
|
||||
|
||||
@@ -0,0 +1,472 @@
|
||||
! include/25/omp_lib.f.var
|
||||
! $Revision: 42181 $
|
||||
! $Date: 2013-03-26 15:04:45 -0500 (Tue, 26 Mar 2013) $
|
||||
|
||||
!
|
||||
!//===----------------------------------------------------------------------===//
|
||||
!//
|
||||
!// 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 :: kmp_pointer_kind = int_ptr_kind()
|
||||
integer, parameter :: kmp_size_t_kind = int_ptr_kind()
|
||||
|
||||
end module omp_lib_kinds
|
||||
|
||||
module omp_lib
|
||||
|
||||
use omp_lib_kinds
|
||||
|
||||
integer, parameter :: kmp_version_major = $KMP_VERSION_MAJOR
|
||||
integer, parameter :: kmp_version_minor = $KMP_VERSION_MINOR
|
||||
integer, parameter :: kmp_version_build = $KMP_VERSION_BUILD
|
||||
character(*), parameter :: kmp_build_date = '$KMP_BUILD_DATE'
|
||||
integer, parameter :: openmp_version = 200505
|
||||
|
||||
interface
|
||||
|
||||
! ***
|
||||
! *** omp_* entry points
|
||||
! ***
|
||||
|
||||
subroutine omp_set_num_threads(nthreads)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) nthreads
|
||||
end subroutine omp_set_num_threads
|
||||
|
||||
subroutine omp_set_dynamic(enable)
|
||||
use omp_lib_kinds
|
||||
logical (kind=omp_logical_kind) enable
|
||||
end subroutine omp_set_dynamic
|
||||
|
||||
subroutine omp_set_nested(enable)
|
||||
use omp_lib_kinds
|
||||
logical (kind=omp_logical_kind) enable
|
||||
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_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_wtime()
|
||||
use omp_lib_kinds
|
||||
double precision omp_get_wtime
|
||||
end function omp_get_wtime
|
||||
|
||||
function omp_get_wtick ()
|
||||
use omp_lib_kinds
|
||||
double precision omp_get_wtick
|
||||
end function omp_get_wtick
|
||||
|
||||
subroutine omp_init_lock(lockvar)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_lock_kind) lockvar
|
||||
end subroutine omp_init_lock
|
||||
|
||||
subroutine omp_destroy_lock(lockvar)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_lock_kind) lockvar
|
||||
end subroutine omp_destroy_lock
|
||||
|
||||
subroutine omp_set_lock(lockvar)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_lock_kind) lockvar
|
||||
end subroutine omp_set_lock
|
||||
|
||||
subroutine omp_unset_lock(lockvar)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_lock_kind) lockvar
|
||||
end subroutine omp_unset_lock
|
||||
|
||||
function omp_test_lock(lockvar)
|
||||
use omp_lib_kinds
|
||||
logical (kind=omp_logical_kind) omp_test_lock
|
||||
integer (kind=omp_lock_kind) lockvar
|
||||
end function omp_test_lock
|
||||
|
||||
subroutine omp_init_nest_lock(lockvar)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_nest_lock_kind) lockvar
|
||||
end subroutine omp_init_nest_lock
|
||||
|
||||
subroutine omp_destroy_nest_lock(lockvar)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_nest_lock_kind) lockvar
|
||||
end subroutine omp_destroy_nest_lock
|
||||
|
||||
subroutine omp_set_nest_lock(lockvar)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_nest_lock_kind) lockvar
|
||||
end subroutine omp_set_nest_lock
|
||||
|
||||
subroutine omp_unset_nest_lock(lockvar)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_nest_lock_kind) lockvar
|
||||
end subroutine omp_unset_nest_lock
|
||||
|
||||
function omp_test_nest_lock(lockvar)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_test_nest_lock
|
||||
integer (kind=omp_nest_lock_kind) lockvar
|
||||
end function omp_test_nest_lock
|
||||
|
||||
! ***
|
||||
! *** 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()
|
||||
use omp_lib_kinds
|
||||
end subroutine kmp_set_library_serial
|
||||
|
||||
subroutine kmp_set_library_turnaround()
|
||||
use omp_lib_kinds
|
||||
end subroutine kmp_set_library_turnaround
|
||||
|
||||
subroutine kmp_set_library_throughput()
|
||||
use omp_lib_kinds
|
||||
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
|
||||
|
||||
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_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()
|
||||
use omp_lib_kinds
|
||||
end subroutine kmp_set_warnings_on
|
||||
|
||||
subroutine kmp_set_warnings_off()
|
||||
use omp_lib_kinds
|
||||
end subroutine kmp_set_warnings_off
|
||||
|
||||
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_WTIME' :: omp_get_wtime
|
||||
!dec$ attributes alias:'OMP_GET_WTICK' :: omp_get_wtick
|
||||
|
||||
!dec$ attributes alias:'omp_init_lock' :: omp_init_lock
|
||||
!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_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_MALLOC'::kmp_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$ 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_WTIME' :: omp_get_wtime
|
||||
!dec$ attributes alias:'_OMP_GET_WTICK' :: omp_get_wtick
|
||||
|
||||
!dec$ attributes alias:'_omp_init_lock' :: omp_init_lock
|
||||
!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_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_MALLOC'::kmp_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$ 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_wtime_'::omp_get_wtime
|
||||
!dec$ attributes alias:'omp_get_wtick_'::omp_get_wtick
|
||||
|
||||
!dec$ attributes alias:'omp_init_lock_'::omp_init_lock
|
||||
!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_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_malloc_'::kmp_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$ 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_wtime_'::omp_get_wtime
|
||||
!dec$ attributes alias:'_omp_get_wtick_'::omp_get_wtick
|
||||
|
||||
!dec$ attributes alias:'_omp_init_lock_'::omp_init_lock
|
||||
!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_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_malloc_'::kmp_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$ endif
|
||||
|
||||
end module omp_lib
|
||||
|
||||
|
||||
@@ -0,0 +1,256 @@
|
||||
! include/25/omp_lib.f90.var
|
||||
! $Revision: 42061 $
|
||||
! $Date: 2013-02-28 16:36:24 -0600 (Thu, 28 Feb 2013) $
|
||||
|
||||
!
|
||||
!//===----------------------------------------------------------------------===//
|
||||
!//
|
||||
!// 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 :: kmp_pointer_kind = c_intptr_t
|
||||
integer, parameter :: kmp_size_t_kind = c_size_t
|
||||
|
||||
end module omp_lib_kinds
|
||||
|
||||
module omp_lib
|
||||
|
||||
use omp_lib_kinds
|
||||
|
||||
integer, parameter :: openmp_version = 200505
|
||||
integer, parameter :: kmp_version_major = $KMP_VERSION_MAJOR
|
||||
integer, parameter :: kmp_version_minor = $KMP_VERSION_MINOR
|
||||
integer, parameter :: kmp_version_build = $KMP_VERSION_BUILD
|
||||
character(*) kmp_build_date
|
||||
parameter( kmp_build_date = '$KMP_BUILD_DATE' )
|
||||
|
||||
interface
|
||||
|
||||
! ***
|
||||
! *** omp_* entry points
|
||||
! ***
|
||||
|
||||
subroutine omp_set_num_threads(nthreads) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind), value :: nthreads
|
||||
end subroutine omp_set_num_threads
|
||||
|
||||
subroutine omp_set_dynamic(enable) bind(c)
|
||||
use omp_lib_kinds
|
||||
logical (kind=omp_logical_kind), value :: enable
|
||||
end subroutine omp_set_dynamic
|
||||
|
||||
subroutine omp_set_nested(enable) bind(c)
|
||||
use omp_lib_kinds
|
||||
logical (kind=omp_logical_kind), value :: enable
|
||||
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_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_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
|
||||
|
||||
subroutine omp_init_lock(lockvar) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_lock_kind) lockvar
|
||||
end subroutine omp_init_lock
|
||||
|
||||
subroutine omp_destroy_lock(lockvar) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_lock_kind) lockvar
|
||||
end subroutine omp_destroy_lock
|
||||
|
||||
subroutine omp_set_lock(lockvar) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_lock_kind) lockvar
|
||||
end subroutine omp_set_lock
|
||||
|
||||
subroutine omp_unset_lock(lockvar) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_lock_kind) lockvar
|
||||
end subroutine omp_unset_lock
|
||||
|
||||
function omp_test_lock(lockvar) bind(c)
|
||||
use omp_lib_kinds
|
||||
logical (kind=omp_logical_kind) omp_test_lock
|
||||
integer (kind=omp_lock_kind) lockvar
|
||||
end function omp_test_lock
|
||||
|
||||
subroutine omp_init_nest_lock(lockvar) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_nest_lock_kind) lockvar
|
||||
end subroutine omp_init_nest_lock
|
||||
|
||||
subroutine omp_destroy_nest_lock(lockvar) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_nest_lock_kind) lockvar
|
||||
end subroutine omp_destroy_nest_lock
|
||||
|
||||
subroutine omp_set_nest_lock(lockvar) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_nest_lock_kind) lockvar
|
||||
end subroutine omp_set_nest_lock
|
||||
|
||||
subroutine omp_unset_nest_lock(lockvar) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_nest_lock_kind) lockvar
|
||||
end subroutine omp_unset_nest_lock
|
||||
|
||||
function omp_test_nest_lock(lockvar) bind(c)
|
||||
use omp_lib_kinds
|
||||
integer (kind=omp_integer_kind) omp_test_nest_lock
|
||||
integer (kind=omp_nest_lock_kind) lockvar
|
||||
end function omp_test_nest_lock
|
||||
|
||||
! ***
|
||||
! *** 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)
|
||||
use omp_lib_kinds
|
||||
end subroutine kmp_set_library_serial
|
||||
|
||||
subroutine kmp_set_library_turnaround() bind(c)
|
||||
use omp_lib_kinds
|
||||
end subroutine kmp_set_library_turnaround
|
||||
|
||||
subroutine kmp_set_library_throughput() bind(c)
|
||||
use omp_lib_kinds
|
||||
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
|
||||
|
||||
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_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)
|
||||
use omp_lib_kinds
|
||||
end subroutine kmp_set_warnings_on
|
||||
|
||||
subroutine kmp_set_warnings_off() bind(c)
|
||||
use omp_lib_kinds
|
||||
end subroutine kmp_set_warnings_off
|
||||
|
||||
end interface
|
||||
|
||||
end module omp_lib
|
||||
@@ -0,0 +1,460 @@
|
||||
! include/25/omp_lib.h.var
|
||||
! $Revision: 42181 $
|
||||
! $Date: 2013-03-26 15:04:45 -0500 (Tue, 26 Mar 2013) $
|
||||
|
||||
!
|
||||
!//===----------------------------------------------------------------------===//
|
||||
!//
|
||||
!// 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
|
||||
|
||||
include 'omp_lib_kinds.h'
|
||||
|
||||
integer, parameter :: kmp_version_major = $KMP_VERSION_MAJOR
|
||||
integer, parameter :: kmp_version_minor = $KMP_VERSION_MINOR
|
||||
integer, parameter :: kmp_version_build = $KMP_VERSION_BUILD
|
||||
character(*), parameter :: kmp_build_date = '$KMP_BUILD_DATE'
|
||||
integer, parameter :: openmp_version = 200505
|
||||
|
||||
interface
|
||||
|
||||
! ***
|
||||
! *** omp_* entry points
|
||||
! ***
|
||||
|
||||
subroutine omp_set_num_threads(nthreads)
|
||||
include 'omp_lib_kinds.h'
|
||||
integer (kind=omp_integer_kind) nthreads
|
||||
end subroutine omp_set_num_threads
|
||||
|
||||
subroutine omp_set_dynamic(enable)
|
||||
include 'omp_lib_kinds.h'
|
||||
logical (kind=omp_logical_kind) enable
|
||||
end subroutine omp_set_dynamic
|
||||
|
||||
subroutine omp_set_nested(enable)
|
||||
include 'omp_lib_kinds.h'
|
||||
logical (kind=omp_logical_kind) enable
|
||||
end subroutine omp_set_nested
|
||||
|
||||
function omp_get_num_threads()
|
||||
include 'omp_lib_kinds.h'
|
||||
integer (kind=omp_integer_kind) omp_get_num_threads
|
||||
end function omp_get_num_threads
|
||||
|
||||
function omp_get_max_threads()
|
||||
include 'omp_lib_kinds.h'
|
||||
integer (kind=omp_integer_kind) omp_get_max_threads
|
||||
end function omp_get_max_threads
|
||||
|
||||
function omp_get_thread_num()
|
||||
include 'omp_lib_kinds.h'
|
||||
integer (kind=omp_integer_kind) omp_get_thread_num
|
||||
end function omp_get_thread_num
|
||||
|
||||
function omp_get_num_procs()
|
||||
include 'omp_lib_kinds.h'
|
||||
integer (kind=omp_integer_kind) omp_get_num_procs
|
||||
end function omp_get_num_procs
|
||||
|
||||
function omp_in_parallel()
|
||||
include 'omp_lib_kinds.h'
|
||||
logical (kind=omp_logical_kind) omp_in_parallel
|
||||
end function omp_in_parallel
|
||||
|
||||
function omp_get_dynamic()
|
||||
include 'omp_lib_kinds.h'
|
||||
logical (kind=omp_logical_kind) omp_get_dynamic
|
||||
end function omp_get_dynamic
|
||||
|
||||
function omp_get_nested()
|
||||
include 'omp_lib_kinds.h'
|
||||
logical (kind=omp_logical_kind) omp_get_nested
|
||||
end function omp_get_nested
|
||||
|
||||
function omp_get_wtime()
|
||||
include 'omp_lib_kinds.h'
|
||||
double precision omp_get_wtime
|
||||
end function omp_get_wtime
|
||||
|
||||
function omp_get_wtick ()
|
||||
include 'omp_lib_kinds.h'
|
||||
double precision omp_get_wtick
|
||||
end function omp_get_wtick
|
||||
|
||||
subroutine omp_init_lock(lockvar)
|
||||
include 'omp_lib_kinds.h'
|
||||
integer (kind=omp_lock_kind) lockvar
|
||||
end subroutine omp_init_lock
|
||||
|
||||
subroutine omp_destroy_lock(lockvar)
|
||||
include 'omp_lib_kinds.h'
|
||||
integer (kind=omp_lock_kind) lockvar
|
||||
end subroutine omp_destroy_lock
|
||||
|
||||
subroutine omp_set_lock(lockvar)
|
||||
include 'omp_lib_kinds.h'
|
||||
integer (kind=omp_lock_kind) lockvar
|
||||
end subroutine omp_set_lock
|
||||
|
||||
subroutine omp_unset_lock(lockvar)
|
||||
include 'omp_lib_kinds.h'
|
||||
integer (kind=omp_lock_kind) lockvar
|
||||
end subroutine omp_unset_lock
|
||||
|
||||
function omp_test_lock(lockvar)
|
||||
include 'omp_lib_kinds.h'
|
||||
logical (kind=omp_logical_kind) omp_test_lock
|
||||
integer (kind=omp_lock_kind) lockvar
|
||||
end function omp_test_lock
|
||||
|
||||
subroutine omp_init_nest_lock(lockvar)
|
||||
include 'omp_lib_kinds.h'
|
||||
integer (kind=omp_nest_lock_kind) lockvar
|
||||
end subroutine omp_init_nest_lock
|
||||
|
||||
subroutine omp_destroy_nest_lock(lockvar)
|
||||
include 'omp_lib_kinds.h'
|
||||
integer (kind=omp_nest_lock_kind) lockvar
|
||||
end subroutine omp_destroy_nest_lock
|
||||
|
||||
subroutine omp_set_nest_lock(lockvar)
|
||||
include 'omp_lib_kinds.h'
|
||||
integer (kind=omp_nest_lock_kind) lockvar
|
||||
end subroutine omp_set_nest_lock
|
||||
|
||||
subroutine omp_unset_nest_lock(lockvar)
|
||||
include 'omp_lib_kinds.h'
|
||||
integer (kind=omp_nest_lock_kind) lockvar
|
||||
end subroutine omp_unset_nest_lock
|
||||
|
||||
function omp_test_nest_lock(lockvar)
|
||||
include 'omp_lib_kinds.h'
|
||||
integer (kind=omp_integer_kind) omp_test_nest_lock
|
||||
integer (kind=omp_nest_lock_kind) lockvar
|
||||
end function omp_test_nest_lock
|
||||
|
||||
! ***
|
||||
! *** kmp_* entry points
|
||||
! ***
|
||||
|
||||
subroutine kmp_set_stacksize(size)
|
||||
include 'omp_lib_kinds.h'
|
||||
integer (kind=omp_integer_kind) size
|
||||
end subroutine kmp_set_stacksize
|
||||
|
||||
subroutine kmp_set_stacksize_s(size)
|
||||
include 'omp_lib_kinds.h'
|
||||
integer (kind=kmp_size_t_kind) size
|
||||
end subroutine kmp_set_stacksize_s
|
||||
|
||||
subroutine kmp_set_blocktime(msec)
|
||||
include 'omp_lib_kinds.h'
|
||||
integer (kind=omp_integer_kind) msec
|
||||
end subroutine kmp_set_blocktime
|
||||
|
||||
subroutine kmp_set_library_serial()
|
||||
include 'omp_lib_kinds.h'
|
||||
end subroutine kmp_set_library_serial
|
||||
|
||||
subroutine kmp_set_library_turnaround()
|
||||
include 'omp_lib_kinds.h'
|
||||
end subroutine kmp_set_library_turnaround
|
||||
|
||||
subroutine kmp_set_library_throughput()
|
||||
include 'omp_lib_kinds.h'
|
||||
end subroutine kmp_set_library_throughput
|
||||
|
||||
subroutine kmp_set_library(libnum)
|
||||
include 'omp_lib_kinds.h'
|
||||
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()
|
||||
include 'omp_lib_kinds.h'
|
||||
integer (kind=omp_integer_kind) kmp_get_stacksize
|
||||
end function kmp_get_stacksize
|
||||
|
||||
function kmp_get_stacksize_s()
|
||||
include 'omp_lib_kinds.h'
|
||||
integer (kind=kmp_size_t_kind) kmp_get_stacksize_s
|
||||
end function kmp_get_stacksize_s
|
||||
|
||||
function kmp_get_blocktime()
|
||||
include 'omp_lib_kinds.h'
|
||||
integer (kind=omp_integer_kind) kmp_get_blocktime
|
||||
end function kmp_get_blocktime
|
||||
|
||||
function kmp_get_library()
|
||||
include 'omp_lib_kinds.h'
|
||||
integer (kind=omp_integer_kind) kmp_get_library
|
||||
end function kmp_get_library
|
||||
|
||||
function kmp_malloc(size)
|
||||
include 'omp_lib_kinds.h'
|
||||
integer (kind=kmp_pointer_kind) kmp_malloc
|
||||
integer (kind=kmp_size_t_kind) size
|
||||
end function kmp_malloc
|
||||
|
||||
function kmp_calloc(nelem, elsize)
|
||||
include 'omp_lib_kinds.h'
|
||||
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)
|
||||
include 'omp_lib_kinds.h'
|
||||
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)
|
||||
include 'omp_lib_kinds.h'
|
||||
integer (kind=kmp_pointer_kind) ptr
|
||||
end subroutine kmp_free
|
||||
|
||||
subroutine kmp_set_warnings_on()
|
||||
include 'omp_lib_kinds.h'
|
||||
end subroutine kmp_set_warnings_on
|
||||
|
||||
subroutine kmp_set_warnings_off()
|
||||
include 'omp_lib_kinds.h'
|
||||
end subroutine kmp_set_warnings_off
|
||||
|
||||
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_WTIME'::omp_get_wtime
|
||||
!dec$ attributes alias:'OMP_GET_WTICK'::omp_get_wtick
|
||||
|
||||
!dec$ attributes alias:'omp_init_lock'::omp_init_lock
|
||||
!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_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_SET_DEFAULTS'::kmp_set_defaults
|
||||
!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_MALLOC'::kmp_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$ 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_WTIME'::omp_get_wtime
|
||||
!dec$ attributes alias:'_OMP_GET_WTICK'::omp_get_wtick
|
||||
|
||||
!dec$ attributes alias:'_omp_init_lock'::omp_init_lock
|
||||
!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_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_SET_DEFAULTS'::kmp_set_defaults
|
||||
!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_MALLOC'::kmp_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$ 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_wtime_'::omp_get_wtime
|
||||
!dec$ attributes alias:'omp_get_wtick_'::omp_get_wtick
|
||||
|
||||
!dec$ attributes alias:'omp_init_lock_'::omp_init_lock
|
||||
!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_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_set_defaults_'::kmp_set_defaults
|
||||
!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_malloc_'::kmp_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$ 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_wtime_'::omp_get_wtime
|
||||
!dec$ attributes alias:'_omp_get_wtick_'::omp_get_wtick
|
||||
|
||||
!dec$ attributes alias:'_omp_init_lock_'::omp_init_lock
|
||||
!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_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_set_defaults_'::kmp_set_defaults
|
||||
!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_malloc_'::kmp_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$ endif
|
||||
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* include/30/iomp.h.var
|
||||
* $Revision: 42061 $
|
||||
* $Date: 2013-02-28 16:36:24 -0600 (Thu, 28 Feb 2013) $
|
||||
*/
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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 __IOMP_H
|
||||
# define __IOMP_H
|
||||
|
||||
# define KMP_VERSION_MAJOR $KMP_VERSION_MAJOR
|
||||
# define KMP_VERSION_MINOR $KMP_VERSION_MINOR
|
||||
# define KMP_VERSION_BUILD $KMP_VERSION_BUILD
|
||||
# define KMP_BUILD_DATE "$KMP_BUILD_DATE"
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif
|
||||
|
||||
# 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_affinity_mask_proc kmpc_set_affinity_mask_proc
|
||||
# define kmp_unset_affinity_mask_proc kmpc_unset_affinity_mask_proc
|
||||
# define kmp_get_affinity_mask_proc kmpc_get_affinity_mask_proc
|
||||
|
||||
# define kmp_malloc kmpc_malloc
|
||||
# define kmp_calloc kmpc_calloc
|
||||
# define kmp_realloc kmpc_realloc
|
||||
# define kmp_free kmpc_free
|
||||
|
||||
# if defined(_WIN32)
|
||||
# define __KAI_KMPC_CONVENTION __cdecl
|
||||
# else
|
||||
# define __KAI_KMPC_CONVENTION
|
||||
# endif
|
||||
|
||||
# include <stdlib.h>
|
||||
/* 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 *);
|
||||
|
||||
/* affinity API functions */
|
||||
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 *);
|
||||
|
||||
extern void * __KAI_KMPC_CONVENTION kmp_malloc (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 /* __IOMP_H */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user