[PATCH 2/4] OpenMP 4.0 offloading to Intel MIC: liboffloadmic.

* Makefile.def: Add liboffloadmic to target_modules.  Make
	liboffloadmic depend on libgomp's configure, libstdc++ and libgcc.
	* Makefile.in: Regenerate.
	* configure: Regenerate.
	* configure.ac: Add liboffloadmic to target binaries.
	Restrict liboffloadmic for POSIX and i*86, and x86_64 architectures.
	Add liboffloadmic to noconfig list when C++ is not supported.

config/
	* target-posix: New file.

libcilkrts/
	* configure.tgt: Use config/target-posix.

liboffloadmic/
	Initial commit.  Imported from upstream:
	https://www.openmprtl.org/sites/default/files/liboffload_oss.tgz
	* Makefile.am: New file.
	* Makefile.in: New file, generated by automake.
	* aclocal.m4: New file, generated by aclocal.
	* configure: New file, generated by autoconf.
	* configure.ac: New file.
	* configure.tgt: Ditto.
	* doc/doxygen/config: Ditto.
	* doc/doxygen/header.tex: Ditto.
	* include/coi/common/COIEngine_common.h: Ditto.
	* include/coi/common/COIMacros_common.h: Ditto.
	* include/coi/common/COIPerf_common.h : Ditto.
	* include/coi/common/COIResult_common.h : Ditto.
	* include/coi/common/COITypes_common.h: Ditto.
	* include/coi/sink/COIBuffer_sink.h: Ditto.
	* include/coi/sink/COIPipeline_sink.h: Ditto.
	* include/coi/sink/COIProcess_sink.h: Ditto.
	* include/coi/source/COIBuffer_source.h: Ditto.
	* include/coi/source/COIEngine_source.h: Ditto.
	* include/coi/source/COIEvent_source.h: Ditto.
	* include/coi/source/COIPipeline_source.h: Ditto.
	* include/coi/source/COIProcess_source.h: Ditto.
	* include/myo/myo.h: Ditto.
	* include/myo/myoimpl.h: Ditto.
	* include/myo/myotypes.h: Ditto.
	* liboffloadmic_host.spec.in: Ditto.
	* liboffloadmic_target.spec.in: Ditto.
	* runtime/cean_util.cpp: Ditto.
	* runtime/cean_util.h: Ditto.
	* runtime/coi/coi_client.cpp: Ditto.
	* runtime/coi/coi_client.h: Ditto.
	* runtime/coi/coi_server.cpp: Ditto.
	* runtime/coi/coi_server.h: Ditto.
	* runtime/compiler_if_host.cpp: Ditto.
	* runtime/compiler_if_host.h: Ditto.
	* runtime/compiler_if_target.cpp: Ditto.
	* runtime/compiler_if_target.h: Ditto.
	* runtime/dv_util.cpp: Ditto.
	* runtime/dv_util.h: Ditto.
	* runtime/emulator/coi_common.h: Ditto.
	* runtime/emulator/coi_device.cpp: Ditto.
	* runtime/emulator/coi_device.h: Ditto.
	* runtime/emulator/coi_host.cpp: Ditto.
	* runtime/emulator/coi_host.h: Ditto.
	* runtime/emulator/coi_version_asm.h: Ditto.
	* runtime/emulator/coi_version_linker_script.map: Ditto.
	* runtime/emulator/myo_client.cpp: Ditto.
	* runtime/emulator/myo_service.cpp: Ditto.
	* runtime/emulator/myo_service.h: Ditto.
	* runtime/emulator/myo_version_asm.h: Ditto.
	* runtime/emulator/myo_version_linker_script.map: Ditto.
	* runtime/liboffload_error.c: Ditto.
	* runtime/liboffload_error_codes.h: Ditto.
	* runtime/liboffload_msg.c: Ditto.
	* runtime/liboffload_msg.h: Ditto.
	* runtime/mic_lib.f90: Ditto.
	* runtime/offload.h: Ditto.
	* runtime/offload_common.cpp: Ditto.
	* runtime/offload_common.h: Ditto.
	* runtime/offload_engine.cpp: Ditto.
	* runtime/offload_engine.h: Ditto.
	* runtime/offload_env.cpp: Ditto.
	* runtime/offload_env.h: Ditto.
	* runtime/offload_host.cpp: Ditto.
	* runtime/offload_host.h: Ditto.
	* runtime/offload_myo_host.cpp: Ditto.
	* runtime/offload_myo_host.h: Ditto.
	* runtime/offload_myo_target.cpp: Ditto.
	* runtime/offload_myo_target.h: Ditto.
	* runtime/offload_omp_host.cpp: Ditto.
	* runtime/offload_omp_target.cpp: Ditto.
	* runtime/offload_orsl.cpp: Ditto.
	* runtime/offload_orsl.h: Ditto.
	* runtime/offload_table.cpp: Ditto.
	* runtime/offload_table.h: Ditto.
	* runtime/offload_target.cpp: Ditto.
	* runtime/offload_target.h: Ditto.
	* runtime/offload_target_main.cpp: Ditto.
	* runtime/offload_timer.h: Ditto.
	* runtime/offload_timer_host.cpp: Ditto.
	* runtime/offload_timer_target.cpp: Ditto.
	* runtime/offload_trace.cpp: Ditto.
	* runtime/offload_trace.h: Ditto.
	* runtime/offload_util.cpp: Ditto.
	* runtime/offload_util.h: Ditto.
	* runtime/ofldbegin.cpp: Ditto.
	* runtime/ofldend.cpp: Ditto.
	* runtime/orsl-lite/include/orsl-lite.h: Ditto.
	* runtime/orsl-lite/lib/orsl-lite.c: Ditto.
	* runtime/orsl-lite/version.txt: Ditto.
	* runtime/use_mpss2.txt: Ditto.

From-SVN: r217498
This commit is contained in:
Kirill Yukhin 2014-11-13 14:03:17 +00:00 committed by Kirill Yukhin
parent f84e7fd6cb
commit 5f52081962
100 changed files with 47533 additions and 21 deletions

View File

@ -1,3 +1,13 @@
2014-11-13 Kirill Yukhin <kirill.yukhin@intel.com>
* Makefile.def: Add liboffloadmic to target_modules. Make
liboffloadmic depend on libgomp's configure, libstdc++ and libgcc.
* Makefile.in: Regenerate.
* configure: Regenerate.
* configure.ac: Add liboffloadmic to target binaries.
Restrict liboffloadmic for POSIX and i*86, and x86_64 architectures.
Add liboffloadmic to noconfig list when C++ is not supported.
2014-11-13 Bernd Schmidt <bernds@codesourcery.com>
Thomas Schwinge <thomas@codesourcery.com>
Ilya Verbin <ilya.verbin@intel.com>

View File

@ -134,6 +134,9 @@ target_modules = { module= libvtv;
raw_cxx=true; };
target_modules = { module= libcilkrts;
lib_path=.libs; };
target_modules = { module= liboffloadmic;
lib_path=.libs;
extra_configure_flags='@extra_liboffloadmic_configure_flags@'; };
target_modules = { module= libssp; lib_path=.libs; };
target_modules = { module= newlib; };
target_modules = { module= libgcc; bootstrap=true; no_check=true; };
@ -509,6 +512,7 @@ dependencies = { module=all-m4; on=all-build-texinfo; };
lang_env_dependencies = { module=libjava; cxx=true; };
lang_env_dependencies = { module=libitm; cxx=true; };
lang_env_dependencies = { module=libcilkrts; cxx=true; };
lang_env_dependencies = { module=liboffloadmic; cxx=true; };
lang_env_dependencies = { module=newlib; no_c=true; };
lang_env_dependencies = { module=libgloss; no_c=true; };
lang_env_dependencies = { module=libgcc; no_gcc=true; no_c=true; };
@ -535,12 +539,14 @@ dependencies = { module=all-target-libjava; on=all-target-libffi; };
dependencies = { module=configure-target-libobjc; on=configure-target-boehm-gc; };
dependencies = { module=all-target-libobjc; on=all-target-boehm-gc; };
dependencies = { module=configure-target-libstdc++-v3; on=configure-target-libgomp; };
dependencies = { module=configure-target-liboffloadmic; on=configure-target-libgomp; };
dependencies = { module=configure-target-libsanitizer; on=all-target-libstdc++-v3; };
dependencies = { module=configure-target-libvtv; on=all-target-libstdc++-v3; };
// parallel_list.o and parallel_settings.o depend on omp.h, which is
// generated by the libgomp configure. Unfortunately, due to the use of
// recursive make, we can't be that specific.
dependencies = { module=all-target-libstdc++-v3; on=configure-target-libgomp; };
dependencies = { module=all-target-liboffloadmic; on=configure-target-libgomp; };
dependencies = { module=install-target-libgo; on=install-target-libatomic; };
dependencies = { module=install-target-libgfortran; on=install-target-libquadmath; };
@ -551,6 +557,8 @@ dependencies = { module=install-target-libvtv; on=install-target-libstdc++-v3; }
dependencies = { module=install-target-libvtv; on=install-target-libgcc; };
dependencies = { module=install-target-libcilkrts; on=install-target-libstdc++-v3; };
dependencies = { module=install-target-libcilkrts; on=install-target-libgcc; };
dependencies = { module=install-target-liboffloadmic; on=install-target-libstdc++-v3; };
dependencies = { module=install-target-liboffloadmic; on=install-target-libgcc; };
dependencies = { module=install-target-libjava; on=install-target-libgcc; };
dependencies = { module=install-target-libitm; on=install-target-libgcc; };
dependencies = { module=install-target-libobjc; on=install-target-libgcc; };

View File

@ -574,7 +574,7 @@ all:
# This is the list of directories that may be needed in RPATH_ENVVAR
# so that programs built for the target machine work.
TARGET_LIB_PATH = $(TARGET_LIB_PATH_libstdc++-v3)$(TARGET_LIB_PATH_libsanitizer)$(TARGET_LIB_PATH_libvtv)$(TARGET_LIB_PATH_libcilkrts)$(TARGET_LIB_PATH_libssp)$(TARGET_LIB_PATH_libgomp)$(TARGET_LIB_PATH_libitm)$(TARGET_LIB_PATH_libatomic)$(HOST_LIB_PATH_gcc)
TARGET_LIB_PATH = $(TARGET_LIB_PATH_libstdc++-v3)$(TARGET_LIB_PATH_libsanitizer)$(TARGET_LIB_PATH_libvtv)$(TARGET_LIB_PATH_libcilkrts)$(TARGET_LIB_PATH_liboffloadmic)$(TARGET_LIB_PATH_libssp)$(TARGET_LIB_PATH_libgomp)$(TARGET_LIB_PATH_libitm)$(TARGET_LIB_PATH_libatomic)$(HOST_LIB_PATH_gcc)
@if target-libstdc++-v3
TARGET_LIB_PATH_libstdc++-v3 = $$r/$(TARGET_SUBDIR)/libstdc++-v3/src/.libs:
@ -592,6 +592,10 @@ TARGET_LIB_PATH_libvtv = $$r/$(TARGET_SUBDIR)/libvtv/.libs:
TARGET_LIB_PATH_libcilkrts = $$r/$(TARGET_SUBDIR)/libcilkrts/.libs:
@endif target-libcilkrts
@if target-liboffloadmic
TARGET_LIB_PATH_liboffloadmic = $$r/$(TARGET_SUBDIR)/liboffloadmic/.libs:
@endif target-liboffloadmic
@if target-libssp
TARGET_LIB_PATH_libssp = $$r/$(TARGET_SUBDIR)/libssp/.libs:
@endif target-libssp
@ -926,6 +930,7 @@ configure-target: \
maybe-configure-target-libsanitizer \
maybe-configure-target-libvtv \
maybe-configure-target-libcilkrts \
maybe-configure-target-liboffloadmic \
maybe-configure-target-libssp \
maybe-configure-target-newlib \
maybe-configure-target-libgcc \
@ -1084,6 +1089,7 @@ all-target: maybe-all-target-libsanitizer
all-target: maybe-all-target-libvtv
@endif target-libvtv-no-bootstrap
all-target: maybe-all-target-libcilkrts
all-target: maybe-all-target-liboffloadmic
all-target: maybe-all-target-libssp
all-target: maybe-all-target-newlib
@if target-libgcc-no-bootstrap
@ -1177,6 +1183,7 @@ info-target: maybe-info-target-libstdc++-v3
info-target: maybe-info-target-libsanitizer
info-target: maybe-info-target-libvtv
info-target: maybe-info-target-libcilkrts
info-target: maybe-info-target-liboffloadmic
info-target: maybe-info-target-libssp
info-target: maybe-info-target-newlib
info-target: maybe-info-target-libgcc
@ -1261,6 +1268,7 @@ dvi-target: maybe-dvi-target-libstdc++-v3
dvi-target: maybe-dvi-target-libsanitizer
dvi-target: maybe-dvi-target-libvtv
dvi-target: maybe-dvi-target-libcilkrts
dvi-target: maybe-dvi-target-liboffloadmic
dvi-target: maybe-dvi-target-libssp
dvi-target: maybe-dvi-target-newlib
dvi-target: maybe-dvi-target-libgcc
@ -1345,6 +1353,7 @@ pdf-target: maybe-pdf-target-libstdc++-v3
pdf-target: maybe-pdf-target-libsanitizer
pdf-target: maybe-pdf-target-libvtv
pdf-target: maybe-pdf-target-libcilkrts
pdf-target: maybe-pdf-target-liboffloadmic
pdf-target: maybe-pdf-target-libssp
pdf-target: maybe-pdf-target-newlib
pdf-target: maybe-pdf-target-libgcc
@ -1429,6 +1438,7 @@ html-target: maybe-html-target-libstdc++-v3
html-target: maybe-html-target-libsanitizer
html-target: maybe-html-target-libvtv
html-target: maybe-html-target-libcilkrts
html-target: maybe-html-target-liboffloadmic
html-target: maybe-html-target-libssp
html-target: maybe-html-target-newlib
html-target: maybe-html-target-libgcc
@ -1513,6 +1523,7 @@ TAGS-target: maybe-TAGS-target-libstdc++-v3
TAGS-target: maybe-TAGS-target-libsanitizer
TAGS-target: maybe-TAGS-target-libvtv
TAGS-target: maybe-TAGS-target-libcilkrts
TAGS-target: maybe-TAGS-target-liboffloadmic
TAGS-target: maybe-TAGS-target-libssp
TAGS-target: maybe-TAGS-target-newlib
TAGS-target: maybe-TAGS-target-libgcc
@ -1597,6 +1608,7 @@ install-info-target: maybe-install-info-target-libstdc++-v3
install-info-target: maybe-install-info-target-libsanitizer
install-info-target: maybe-install-info-target-libvtv
install-info-target: maybe-install-info-target-libcilkrts
install-info-target: maybe-install-info-target-liboffloadmic
install-info-target: maybe-install-info-target-libssp
install-info-target: maybe-install-info-target-newlib
install-info-target: maybe-install-info-target-libgcc
@ -1681,6 +1693,7 @@ install-pdf-target: maybe-install-pdf-target-libstdc++-v3
install-pdf-target: maybe-install-pdf-target-libsanitizer
install-pdf-target: maybe-install-pdf-target-libvtv
install-pdf-target: maybe-install-pdf-target-libcilkrts
install-pdf-target: maybe-install-pdf-target-liboffloadmic
install-pdf-target: maybe-install-pdf-target-libssp
install-pdf-target: maybe-install-pdf-target-newlib
install-pdf-target: maybe-install-pdf-target-libgcc
@ -1765,6 +1778,7 @@ install-html-target: maybe-install-html-target-libstdc++-v3
install-html-target: maybe-install-html-target-libsanitizer
install-html-target: maybe-install-html-target-libvtv
install-html-target: maybe-install-html-target-libcilkrts
install-html-target: maybe-install-html-target-liboffloadmic
install-html-target: maybe-install-html-target-libssp
install-html-target: maybe-install-html-target-newlib
install-html-target: maybe-install-html-target-libgcc
@ -1849,6 +1863,7 @@ installcheck-target: maybe-installcheck-target-libstdc++-v3
installcheck-target: maybe-installcheck-target-libsanitizer
installcheck-target: maybe-installcheck-target-libvtv
installcheck-target: maybe-installcheck-target-libcilkrts
installcheck-target: maybe-installcheck-target-liboffloadmic
installcheck-target: maybe-installcheck-target-libssp
installcheck-target: maybe-installcheck-target-newlib
installcheck-target: maybe-installcheck-target-libgcc
@ -1933,6 +1948,7 @@ mostlyclean-target: maybe-mostlyclean-target-libstdc++-v3
mostlyclean-target: maybe-mostlyclean-target-libsanitizer
mostlyclean-target: maybe-mostlyclean-target-libvtv
mostlyclean-target: maybe-mostlyclean-target-libcilkrts
mostlyclean-target: maybe-mostlyclean-target-liboffloadmic
mostlyclean-target: maybe-mostlyclean-target-libssp
mostlyclean-target: maybe-mostlyclean-target-newlib
mostlyclean-target: maybe-mostlyclean-target-libgcc
@ -2017,6 +2033,7 @@ clean-target: maybe-clean-target-libstdc++-v3
clean-target: maybe-clean-target-libsanitizer
clean-target: maybe-clean-target-libvtv
clean-target: maybe-clean-target-libcilkrts
clean-target: maybe-clean-target-liboffloadmic
clean-target: maybe-clean-target-libssp
clean-target: maybe-clean-target-newlib
clean-target: maybe-clean-target-libgcc
@ -2101,6 +2118,7 @@ distclean-target: maybe-distclean-target-libstdc++-v3
distclean-target: maybe-distclean-target-libsanitizer
distclean-target: maybe-distclean-target-libvtv
distclean-target: maybe-distclean-target-libcilkrts
distclean-target: maybe-distclean-target-liboffloadmic
distclean-target: maybe-distclean-target-libssp
distclean-target: maybe-distclean-target-newlib
distclean-target: maybe-distclean-target-libgcc
@ -2185,6 +2203,7 @@ maintainer-clean-target: maybe-maintainer-clean-target-libstdc++-v3
maintainer-clean-target: maybe-maintainer-clean-target-libsanitizer
maintainer-clean-target: maybe-maintainer-clean-target-libvtv
maintainer-clean-target: maybe-maintainer-clean-target-libcilkrts
maintainer-clean-target: maybe-maintainer-clean-target-liboffloadmic
maintainer-clean-target: maybe-maintainer-clean-target-libssp
maintainer-clean-target: maybe-maintainer-clean-target-newlib
maintainer-clean-target: maybe-maintainer-clean-target-libgcc
@ -2324,6 +2343,7 @@ check-target: \
maybe-check-target-libsanitizer \
maybe-check-target-libvtv \
maybe-check-target-libcilkrts \
maybe-check-target-liboffloadmic \
maybe-check-target-libssp \
maybe-check-target-newlib \
maybe-check-target-libgcc \
@ -2482,6 +2502,7 @@ install-target: \
maybe-install-target-libsanitizer \
maybe-install-target-libvtv \
maybe-install-target-libcilkrts \
maybe-install-target-liboffloadmic \
maybe-install-target-libssp \
maybe-install-target-newlib \
maybe-install-target-libgcc \
@ -2586,6 +2607,7 @@ install-strip-target: \
maybe-install-strip-target-libsanitizer \
maybe-install-strip-target-libvtv \
maybe-install-strip-target-libcilkrts \
maybe-install-strip-target-liboffloadmic \
maybe-install-strip-target-libssp \
maybe-install-strip-target-newlib \
maybe-install-strip-target-libgcc \
@ -35188,6 +35210,469 @@ maintainer-clean-target-libcilkrts:
.PHONY: configure-target-liboffloadmic maybe-configure-target-liboffloadmic
maybe-configure-target-liboffloadmic:
@if gcc-bootstrap
configure-target-liboffloadmic: stage_current
@endif gcc-bootstrap
@if target-liboffloadmic
maybe-configure-target-liboffloadmic: configure-target-liboffloadmic
configure-target-liboffloadmic:
@: $(MAKE); $(unstage)
@r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
echo "Checking multilib configuration for liboffloadmic..."; \
$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/liboffloadmic ; \
$(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/liboffloadmic/multilib.tmp 2> /dev/null ; \
if test -r $(TARGET_SUBDIR)/liboffloadmic/multilib.out; then \
if cmp -s $(TARGET_SUBDIR)/liboffloadmic/multilib.tmp $(TARGET_SUBDIR)/liboffloadmic/multilib.out; then \
rm -f $(TARGET_SUBDIR)/liboffloadmic/multilib.tmp; \
else \
rm -f $(TARGET_SUBDIR)/liboffloadmic/Makefile; \
mv $(TARGET_SUBDIR)/liboffloadmic/multilib.tmp $(TARGET_SUBDIR)/liboffloadmic/multilib.out; \
fi; \
else \
mv $(TARGET_SUBDIR)/liboffloadmic/multilib.tmp $(TARGET_SUBDIR)/liboffloadmic/multilib.out; \
fi; \
test ! -f $(TARGET_SUBDIR)/liboffloadmic/Makefile || exit 0; \
$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/liboffloadmic ; \
$(NORMAL_TARGET_EXPORTS) \
echo Configuring in $(TARGET_SUBDIR)/liboffloadmic; \
\
this_target="${target_alias}"; \
\
cd "$(TARGET_SUBDIR)/liboffloadmic" || exit 1; \
case $(srcdir) in \
/* | [A-Za-z]:[\\/]*) topdir=$(srcdir) ;; \
*) topdir=`echo $(TARGET_SUBDIR)/liboffloadmic/ | \
sed -e 's,\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \
esac; \
module_srcdir=liboffloadmic; \
srcdiroption="--srcdir=$${topdir}/liboffloadmic"; \
libsrcdir="$$s/liboffloadmic"; \
rm -f no-such-file || : ; \
CONFIG_SITE=no-such-file $(SHELL) \
$$s/$$module_srcdir/configure \
--srcdir=$${topdir}/$$module_srcdir \
$(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \
--target=$${this_target} $${srcdiroption} @extra_liboffloadmic_configure_flags@ \
|| exit 1
@endif target-liboffloadmic
.PHONY: all-target-liboffloadmic maybe-all-target-liboffloadmic
maybe-all-target-liboffloadmic:
@if gcc-bootstrap
all-target-liboffloadmic: stage_current
@endif gcc-bootstrap
@if target-liboffloadmic
TARGET-target-liboffloadmic=all
maybe-all-target-liboffloadmic: all-target-liboffloadmic
all-target-liboffloadmic: configure-target-liboffloadmic
@: $(MAKE); $(unstage)
@r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
$(NORMAL_TARGET_EXPORTS) \
(cd $(TARGET_SUBDIR)/liboffloadmic && \
$(MAKE) $(BASE_FLAGS_TO_PASS) $(EXTRA_TARGET_FLAGS) \
$(TARGET-target-liboffloadmic))
@endif target-liboffloadmic
.PHONY: check-target-liboffloadmic maybe-check-target-liboffloadmic
maybe-check-target-liboffloadmic:
@if target-liboffloadmic
maybe-check-target-liboffloadmic: check-target-liboffloadmic
check-target-liboffloadmic:
@: $(MAKE); $(unstage)
@r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
$(NORMAL_TARGET_EXPORTS) \
(cd $(TARGET_SUBDIR)/liboffloadmic && \
$(MAKE) $(TARGET_FLAGS_TO_PASS) check)
@endif target-liboffloadmic
.PHONY: install-target-liboffloadmic maybe-install-target-liboffloadmic
maybe-install-target-liboffloadmic:
@if target-liboffloadmic
maybe-install-target-liboffloadmic: install-target-liboffloadmic
install-target-liboffloadmic: installdirs
@: $(MAKE); $(unstage)
@r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
$(NORMAL_TARGET_EXPORTS) \
(cd $(TARGET_SUBDIR)/liboffloadmic && \
$(MAKE) $(TARGET_FLAGS_TO_PASS) install)
@endif target-liboffloadmic
.PHONY: install-strip-target-liboffloadmic maybe-install-strip-target-liboffloadmic
maybe-install-strip-target-liboffloadmic:
@if target-liboffloadmic
maybe-install-strip-target-liboffloadmic: install-strip-target-liboffloadmic
install-strip-target-liboffloadmic: installdirs
@: $(MAKE); $(unstage)
@r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
$(NORMAL_TARGET_EXPORTS) \
(cd $(TARGET_SUBDIR)/liboffloadmic && \
$(MAKE) $(TARGET_FLAGS_TO_PASS) install-strip)
@endif target-liboffloadmic
# Other targets (info, dvi, pdf, etc.)
.PHONY: maybe-info-target-liboffloadmic info-target-liboffloadmic
maybe-info-target-liboffloadmic:
@if target-liboffloadmic
maybe-info-target-liboffloadmic: info-target-liboffloadmic
info-target-liboffloadmic: \
configure-target-liboffloadmic
@: $(MAKE); $(unstage)
@[ -f $(TARGET_SUBDIR)/liboffloadmic/Makefile ] || exit 0 ; \
r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
$(NORMAL_TARGET_EXPORTS) \
echo "Doing info in $(TARGET_SUBDIR)/liboffloadmic" ; \
for flag in $(EXTRA_TARGET_FLAGS); do \
eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
done; \
(cd $(TARGET_SUBDIR)/liboffloadmic && \
$(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
"CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
"RANLIB=$${RANLIB}" \
"DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
info) \
|| exit 1
@endif target-liboffloadmic
.PHONY: maybe-dvi-target-liboffloadmic dvi-target-liboffloadmic
maybe-dvi-target-liboffloadmic:
@if target-liboffloadmic
maybe-dvi-target-liboffloadmic: dvi-target-liboffloadmic
dvi-target-liboffloadmic: \
configure-target-liboffloadmic
@: $(MAKE); $(unstage)
@[ -f $(TARGET_SUBDIR)/liboffloadmic/Makefile ] || exit 0 ; \
r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
$(NORMAL_TARGET_EXPORTS) \
echo "Doing dvi in $(TARGET_SUBDIR)/liboffloadmic" ; \
for flag in $(EXTRA_TARGET_FLAGS); do \
eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
done; \
(cd $(TARGET_SUBDIR)/liboffloadmic && \
$(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
"CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
"RANLIB=$${RANLIB}" \
"DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
dvi) \
|| exit 1
@endif target-liboffloadmic
.PHONY: maybe-pdf-target-liboffloadmic pdf-target-liboffloadmic
maybe-pdf-target-liboffloadmic:
@if target-liboffloadmic
maybe-pdf-target-liboffloadmic: pdf-target-liboffloadmic
pdf-target-liboffloadmic: \
configure-target-liboffloadmic
@: $(MAKE); $(unstage)
@[ -f $(TARGET_SUBDIR)/liboffloadmic/Makefile ] || exit 0 ; \
r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
$(NORMAL_TARGET_EXPORTS) \
echo "Doing pdf in $(TARGET_SUBDIR)/liboffloadmic" ; \
for flag in $(EXTRA_TARGET_FLAGS); do \
eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
done; \
(cd $(TARGET_SUBDIR)/liboffloadmic && \
$(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
"CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
"RANLIB=$${RANLIB}" \
"DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
pdf) \
|| exit 1
@endif target-liboffloadmic
.PHONY: maybe-html-target-liboffloadmic html-target-liboffloadmic
maybe-html-target-liboffloadmic:
@if target-liboffloadmic
maybe-html-target-liboffloadmic: html-target-liboffloadmic
html-target-liboffloadmic: \
configure-target-liboffloadmic
@: $(MAKE); $(unstage)
@[ -f $(TARGET_SUBDIR)/liboffloadmic/Makefile ] || exit 0 ; \
r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
$(NORMAL_TARGET_EXPORTS) \
echo "Doing html in $(TARGET_SUBDIR)/liboffloadmic" ; \
for flag in $(EXTRA_TARGET_FLAGS); do \
eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
done; \
(cd $(TARGET_SUBDIR)/liboffloadmic && \
$(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
"CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
"RANLIB=$${RANLIB}" \
"DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
html) \
|| exit 1
@endif target-liboffloadmic
.PHONY: maybe-TAGS-target-liboffloadmic TAGS-target-liboffloadmic
maybe-TAGS-target-liboffloadmic:
@if target-liboffloadmic
maybe-TAGS-target-liboffloadmic: TAGS-target-liboffloadmic
TAGS-target-liboffloadmic: \
configure-target-liboffloadmic
@: $(MAKE); $(unstage)
@[ -f $(TARGET_SUBDIR)/liboffloadmic/Makefile ] || exit 0 ; \
r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
$(NORMAL_TARGET_EXPORTS) \
echo "Doing TAGS in $(TARGET_SUBDIR)/liboffloadmic" ; \
for flag in $(EXTRA_TARGET_FLAGS); do \
eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
done; \
(cd $(TARGET_SUBDIR)/liboffloadmic && \
$(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
"CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
"RANLIB=$${RANLIB}" \
"DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
TAGS) \
|| exit 1
@endif target-liboffloadmic
.PHONY: maybe-install-info-target-liboffloadmic install-info-target-liboffloadmic
maybe-install-info-target-liboffloadmic:
@if target-liboffloadmic
maybe-install-info-target-liboffloadmic: install-info-target-liboffloadmic
install-info-target-liboffloadmic: \
configure-target-liboffloadmic \
info-target-liboffloadmic
@: $(MAKE); $(unstage)
@[ -f $(TARGET_SUBDIR)/liboffloadmic/Makefile ] || exit 0 ; \
r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
$(NORMAL_TARGET_EXPORTS) \
echo "Doing install-info in $(TARGET_SUBDIR)/liboffloadmic" ; \
for flag in $(EXTRA_TARGET_FLAGS); do \
eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
done; \
(cd $(TARGET_SUBDIR)/liboffloadmic && \
$(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
"CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
"RANLIB=$${RANLIB}" \
"DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
install-info) \
|| exit 1
@endif target-liboffloadmic
.PHONY: maybe-install-pdf-target-liboffloadmic install-pdf-target-liboffloadmic
maybe-install-pdf-target-liboffloadmic:
@if target-liboffloadmic
maybe-install-pdf-target-liboffloadmic: install-pdf-target-liboffloadmic
install-pdf-target-liboffloadmic: \
configure-target-liboffloadmic \
pdf-target-liboffloadmic
@: $(MAKE); $(unstage)
@[ -f $(TARGET_SUBDIR)/liboffloadmic/Makefile ] || exit 0 ; \
r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
$(NORMAL_TARGET_EXPORTS) \
echo "Doing install-pdf in $(TARGET_SUBDIR)/liboffloadmic" ; \
for flag in $(EXTRA_TARGET_FLAGS); do \
eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
done; \
(cd $(TARGET_SUBDIR)/liboffloadmic && \
$(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
"CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
"RANLIB=$${RANLIB}" \
"DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
install-pdf) \
|| exit 1
@endif target-liboffloadmic
.PHONY: maybe-install-html-target-liboffloadmic install-html-target-liboffloadmic
maybe-install-html-target-liboffloadmic:
@if target-liboffloadmic
maybe-install-html-target-liboffloadmic: install-html-target-liboffloadmic
install-html-target-liboffloadmic: \
configure-target-liboffloadmic \
html-target-liboffloadmic
@: $(MAKE); $(unstage)
@[ -f $(TARGET_SUBDIR)/liboffloadmic/Makefile ] || exit 0 ; \
r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
$(NORMAL_TARGET_EXPORTS) \
echo "Doing install-html in $(TARGET_SUBDIR)/liboffloadmic" ; \
for flag in $(EXTRA_TARGET_FLAGS); do \
eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
done; \
(cd $(TARGET_SUBDIR)/liboffloadmic && \
$(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
"CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
"RANLIB=$${RANLIB}" \
"DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
install-html) \
|| exit 1
@endif target-liboffloadmic
.PHONY: maybe-installcheck-target-liboffloadmic installcheck-target-liboffloadmic
maybe-installcheck-target-liboffloadmic:
@if target-liboffloadmic
maybe-installcheck-target-liboffloadmic: installcheck-target-liboffloadmic
installcheck-target-liboffloadmic: \
configure-target-liboffloadmic
@: $(MAKE); $(unstage)
@[ -f $(TARGET_SUBDIR)/liboffloadmic/Makefile ] || exit 0 ; \
r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
$(NORMAL_TARGET_EXPORTS) \
echo "Doing installcheck in $(TARGET_SUBDIR)/liboffloadmic" ; \
for flag in $(EXTRA_TARGET_FLAGS); do \
eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
done; \
(cd $(TARGET_SUBDIR)/liboffloadmic && \
$(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
"CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
"RANLIB=$${RANLIB}" \
"DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
installcheck) \
|| exit 1
@endif target-liboffloadmic
.PHONY: maybe-mostlyclean-target-liboffloadmic mostlyclean-target-liboffloadmic
maybe-mostlyclean-target-liboffloadmic:
@if target-liboffloadmic
maybe-mostlyclean-target-liboffloadmic: mostlyclean-target-liboffloadmic
mostlyclean-target-liboffloadmic:
@: $(MAKE); $(unstage)
@[ -f $(TARGET_SUBDIR)/liboffloadmic/Makefile ] || exit 0 ; \
r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
$(NORMAL_TARGET_EXPORTS) \
echo "Doing mostlyclean in $(TARGET_SUBDIR)/liboffloadmic" ; \
for flag in $(EXTRA_TARGET_FLAGS); do \
eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
done; \
(cd $(TARGET_SUBDIR)/liboffloadmic && \
$(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
"CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
"RANLIB=$${RANLIB}" \
"DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
mostlyclean) \
|| exit 1
@endif target-liboffloadmic
.PHONY: maybe-clean-target-liboffloadmic clean-target-liboffloadmic
maybe-clean-target-liboffloadmic:
@if target-liboffloadmic
maybe-clean-target-liboffloadmic: clean-target-liboffloadmic
clean-target-liboffloadmic:
@: $(MAKE); $(unstage)
@[ -f $(TARGET_SUBDIR)/liboffloadmic/Makefile ] || exit 0 ; \
r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
$(NORMAL_TARGET_EXPORTS) \
echo "Doing clean in $(TARGET_SUBDIR)/liboffloadmic" ; \
for flag in $(EXTRA_TARGET_FLAGS); do \
eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
done; \
(cd $(TARGET_SUBDIR)/liboffloadmic && \
$(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
"CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
"RANLIB=$${RANLIB}" \
"DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
clean) \
|| exit 1
@endif target-liboffloadmic
.PHONY: maybe-distclean-target-liboffloadmic distclean-target-liboffloadmic
maybe-distclean-target-liboffloadmic:
@if target-liboffloadmic
maybe-distclean-target-liboffloadmic: distclean-target-liboffloadmic
distclean-target-liboffloadmic:
@: $(MAKE); $(unstage)
@[ -f $(TARGET_SUBDIR)/liboffloadmic/Makefile ] || exit 0 ; \
r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
$(NORMAL_TARGET_EXPORTS) \
echo "Doing distclean in $(TARGET_SUBDIR)/liboffloadmic" ; \
for flag in $(EXTRA_TARGET_FLAGS); do \
eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
done; \
(cd $(TARGET_SUBDIR)/liboffloadmic && \
$(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
"CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
"RANLIB=$${RANLIB}" \
"DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
distclean) \
|| exit 1
@endif target-liboffloadmic
.PHONY: maybe-maintainer-clean-target-liboffloadmic maintainer-clean-target-liboffloadmic
maybe-maintainer-clean-target-liboffloadmic:
@if target-liboffloadmic
maybe-maintainer-clean-target-liboffloadmic: maintainer-clean-target-liboffloadmic
maintainer-clean-target-liboffloadmic:
@: $(MAKE); $(unstage)
@[ -f $(TARGET_SUBDIR)/liboffloadmic/Makefile ] || exit 0 ; \
r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
$(NORMAL_TARGET_EXPORTS) \
echo "Doing maintainer-clean in $(TARGET_SUBDIR)/liboffloadmic" ; \
for flag in $(EXTRA_TARGET_FLAGS); do \
eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
done; \
(cd $(TARGET_SUBDIR)/liboffloadmic && \
$(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
"CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
"RANLIB=$${RANLIB}" \
"DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
maintainer-clean) \
|| exit 1
@endif target-liboffloadmic
.PHONY: configure-target-libssp maybe-configure-target-libssp
maybe-configure-target-libssp:
@if gcc-bootstrap
@ -47511,6 +47996,7 @@ configure-stage4-target-libvtv: maybe-all-stage4-gcc
configure-stageprofile-target-libvtv: maybe-all-stageprofile-gcc
configure-stagefeedback-target-libvtv: maybe-all-stagefeedback-gcc
configure-target-libcilkrts: stage_last
configure-target-liboffloadmic: stage_last
configure-target-libssp: stage_last
configure-target-newlib: stage_last
configure-stage1-target-libgcc: maybe-all-stage1-gcc
@ -47548,6 +48034,7 @@ configure-target-libstdc++-v3: maybe-all-gcc
configure-target-libsanitizer: maybe-all-gcc
configure-target-libvtv: maybe-all-gcc
configure-target-libcilkrts: maybe-all-gcc
configure-target-liboffloadmic: maybe-all-gcc
configure-target-libssp: maybe-all-gcc
configure-target-newlib: maybe-all-gcc
configure-target-libgcc: maybe-all-gcc
@ -48341,6 +48828,7 @@ configure-stage3-target-libstdc++-v3: maybe-configure-stage3-target-libgomp
configure-stage4-target-libstdc++-v3: maybe-configure-stage4-target-libgomp
configure-stageprofile-target-libstdc++-v3: maybe-configure-stageprofile-target-libgomp
configure-stagefeedback-target-libstdc++-v3: maybe-configure-stagefeedback-target-libgomp
configure-target-liboffloadmic: maybe-configure-target-libgomp
configure-target-libsanitizer: maybe-all-target-libstdc++-v3
configure-stage1-target-libsanitizer: maybe-all-stage1-target-libstdc++-v3
@ -48365,6 +48853,7 @@ all-stage3-target-libstdc++-v3: maybe-configure-stage3-target-libgomp
all-stage4-target-libstdc++-v3: maybe-configure-stage4-target-libgomp
all-stageprofile-target-libstdc++-v3: maybe-configure-stageprofile-target-libgomp
all-stagefeedback-target-libstdc++-v3: maybe-configure-stagefeedback-target-libgomp
all-target-liboffloadmic: maybe-configure-target-libgomp
install-target-libgo: maybe-install-target-libatomic
install-target-libgfortran: maybe-install-target-libquadmath
install-target-libgfortran: maybe-install-target-libgcc
@ -48374,6 +48863,8 @@ install-target-libvtv: maybe-install-target-libstdc++-v3
install-target-libvtv: maybe-install-target-libgcc
install-target-libcilkrts: maybe-install-target-libstdc++-v3
install-target-libcilkrts: maybe-install-target-libgcc
install-target-liboffloadmic: maybe-install-target-libstdc++-v3
install-target-liboffloadmic: maybe-install-target-libgcc
install-target-libjava: maybe-install-target-libgcc
install-target-libitm: maybe-install-target-libgcc
install-target-libobjc: maybe-install-target-libgcc
@ -48422,6 +48913,7 @@ configure-target-libstdc++-v3: maybe-all-target-libgcc
configure-target-libsanitizer: maybe-all-target-libgcc
configure-target-libvtv: maybe-all-target-libgcc
configure-target-libcilkrts: maybe-all-target-libgcc
configure-target-liboffloadmic: maybe-all-target-libgcc
configure-target-libssp: maybe-all-target-libgcc
configure-target-newlib: maybe-all-target-libgcc
configure-target-libbacktrace: maybe-all-target-libgcc
@ -48453,6 +48945,9 @@ configure-target-libvtv: maybe-all-target-newlib maybe-all-target-libgloss
configure-target-libcilkrts: maybe-all-target-newlib maybe-all-target-libgloss
configure-target-libcilkrts: maybe-all-target-libstdc++-v3
configure-target-liboffloadmic: maybe-all-target-newlib maybe-all-target-libgloss
configure-target-liboffloadmic: maybe-all-target-libstdc++-v3
configure-target-libssp: maybe-all-target-newlib maybe-all-target-libgloss

View File

@ -1,3 +1,7 @@
2014-11-13 Kirill Yukhin <kirill.yukhin@intel.com>
* target-posix: New file.
2014-10-27 Tom Tromey <tromey@redhat.com>
* gcc-plugin.m4: New file.

12
config/target-posix Normal file
View File

@ -0,0 +1,12 @@
case "${target}" in
*-*-linux* | *-*-gnu* | *-*-k*bsd*-gnu | *-*-kopensolaris*-gnu)
;;
*-*-netbsd* | *-*-freebsd* | *-*-openbsd* | *-*-dragonfly*)
;;
*-*-solaris2* | *-*-hpux11*)
;;
*-*-darwin* | *-*-aix*)
;;
*)
UNSUPPORTED=1 ;;
esac

66
configure vendored
View File

@ -672,6 +672,7 @@ LDFLAGS
CFLAGS
CC
EXTRA_CONFIGARGS_LIBJAVA
extra_liboffloadmic_configure_flags
target_subdir
host_subdir
build_subdir
@ -754,6 +755,7 @@ enable_libquadmath_support
enable_libada
enable_libssp
enable_libstdcxx
enable_liboffloadmic
enable_static_libjava
enable_bootstrap
with_mpc
@ -1477,6 +1479,8 @@ Optional Features:
--enable-libada build libada directory
--enable-libssp build libssp directory
--disable-libstdcxx do not build libstdc++-v3 directory
--enable-liboffloadmic=ARG
build liboffloadmic [ARG={no,host,target}]
--enable-static-libjava[=ARG]
build static libjava [default=no]
--enable-bootstrap enable bootstrapping [yes if native build]
@ -2737,6 +2741,7 @@ target_libraries="target-libgcc \
target-newlib \
target-libgomp \
target-libcilkrts \
target-liboffloadmic \
target-libatomic \
target-libitm \
target-libstdc++-v3 \
@ -3076,6 +3081,44 @@ if test "${ENABLE_LIBSTDCXX}" = "no" ; then
noconfigdirs="$noconfigdirs target-libstdc++-v3"
fi
# If this is accelerator compiler and its target is intelmic we enable
# target liboffloadmic by default. If this is compiler with offloading
# for intelmic we enable host liboffloadmic by default. Otherwise
# liboffloadmic is disabled by default.
# Check whether --enable-liboffloadmic was given.
if test "${enable_liboffloadmic+set}" = set; then :
enableval=$enable_liboffloadmic; case "$enableval" in
no | host | target)
enable_liboffloadmic=$enableval ;;
*)
as_fn_error "--enable-liboffloadmic=no/host/target" "$LINENO" 5 ;;
esac
else
if test "${ENABLE_AS_ACCELERATOR_FOR}" != "no"; then
case "${target}" in
*-intelmic-* | *-intelmicemul-*)
enable_liboffloadmic=target
extra_liboffloadmic_configure_flags="--enable-liboffloadmic=target"
;;
*)
enable_liboffloadmic=no
;;
esac
else
case "${enable_offload_targets}" in
*-intelmic-* | *-intelmicemul-*)
enable_liboffloadmic=host
extra_liboffloadmic_configure_flags="--enable-liboffloadmic=host"
;;
*)
enable_liboffloadmic=no
;;
esac
fi
fi
# Save it here so that, even in case of --enable-libgcj, if the Java
# front-end isn't enabled, we still get libgcj disabled.
libgcj_saved=$libgcj
@ -3169,6 +3212,25 @@ $as_echo "yes" >&6; }
fi
fi
# Disable liboffloadmic on unsupported systems.
if test -d ${srcdir}/liboffloadmic; then
if test x$enable_liboffloadmic != xno; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for liboffloadmic support" >&5
$as_echo_n "checking for liboffloadmic support... " >&6; }
if (srcdir=${srcdir}/liboffloadmic; \
. ${srcdir}/configure.tgt; \
test -n "$UNSUPPORTED")
then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
noconfigdirs="$noconfigdirs target-liboffloadmic"
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
fi
fi
fi
# Disable libitm on unsupported systems.
if test -d ${srcdir}/libitm; then
if test x$enable_libitm = x; then
@ -6350,7 +6412,7 @@ case ,${enable_languages},:${enable_objc_gc} in
;;
esac
# Disable libcilkrts, libitm, libsanitizer, libvtv if we're not building C++
# Disable libcilkrts, libitm, libsanitizer, libvtv, liboffloadmic if we're not building C++
case ,${enable_languages}, in
*,c++,*)
# Disable libcilkrts, libitm, libsanitizer if we're not building libstdc++
@ -6362,7 +6424,7 @@ case ,${enable_languages}, in
esac
;;
*)
noconfigdirs="$noconfigdirs target-libcilkrts target-libitm target-libsanitizer target-libvtv"
noconfigdirs="$noconfigdirs target-libcilkrts target-liboffloadmic target-libitm target-libsanitizer target-libvtv"
;;
esac

View File

@ -156,6 +156,7 @@ target_libraries="target-libgcc \
target-newlib \
target-libgomp \
target-libcilkrts \
target-liboffloadmic \
target-libatomic \
target-libitm \
target-libstdc++-v3 \
@ -456,6 +457,42 @@ ENABLE_LIBSTDCXX=default)
noconfigdirs="$noconfigdirs target-libstdc++-v3"
fi]
# If this is accelerator compiler and its target is intelmic we enable
# target liboffloadmic by default. If this is compiler with offloading
# for intelmic we enable host liboffloadmic by default. Otherwise
# liboffloadmic is disabled by default.
AC_ARG_ENABLE([liboffloadmic],
AC_HELP_STRING([[--enable-liboffloadmic[=ARG]]],
[build liboffloadmic @<:@ARG={no,host,target}@:>@]),
[case "$enableval" in
no | host | target)
enable_liboffloadmic=$enableval ;;
*)
AC_MSG_ERROR([--enable-liboffloadmic=no/host/target]) ;;
esac],
[if test "${ENABLE_AS_ACCELERATOR_FOR}" != "no"; then
case "${target}" in
*-intelmic-* | *-intelmicemul-*)
enable_liboffloadmic=target
extra_liboffloadmic_configure_flags="--enable-liboffloadmic=target"
;;
*)
enable_liboffloadmic=no
;;
esac
else
case "${enable_offload_targets}" in
*-intelmic-* | *-intelmicemul-*)
enable_liboffloadmic=host
extra_liboffloadmic_configure_flags="--enable-liboffloadmic=host"
;;
*)
enable_liboffloadmic=no
;;
esac
fi])
AC_SUBST(extra_liboffloadmic_configure_flags)
# Save it here so that, even in case of --enable-libgcj, if the Java
# front-end isn't enabled, we still get libgcj disabled.
libgcj_saved=$libgcj
@ -541,6 +578,22 @@ if test -d ${srcdir}/libcilkrts; then
fi
fi
# Disable liboffloadmic on unsupported systems.
if test -d ${srcdir}/liboffloadmic; then
if test x$enable_liboffloadmic != xno; then
AC_MSG_CHECKING([for liboffloadmic support])
if (srcdir=${srcdir}/liboffloadmic; \
. ${srcdir}/configure.tgt; \
test -n "$UNSUPPORTED")
then
AC_MSG_RESULT([no])
noconfigdirs="$noconfigdirs target-liboffloadmic"
else
AC_MSG_RESULT([yes])
fi
fi
fi
# Disable libitm on unsupported systems.
if test -d ${srcdir}/libitm; then
if test x$enable_libitm = x; then
@ -2063,7 +2116,7 @@ case ,${enable_languages},:${enable_objc_gc} in
;;
esac
# Disable libcilkrts, libitm, libsanitizer, libvtv if we're not building C++
# Disable libcilkrts, libitm, libsanitizer, libvtv, liboffloadmic if we're not building C++
case ,${enable_languages}, in
*,c++,*)
# Disable libcilkrts, libitm, libsanitizer if we're not building libstdc++
@ -2075,7 +2128,7 @@ case ,${enable_languages}, in
esac
;;
*)
noconfigdirs="$noconfigdirs target-libcilkrts target-libitm target-libsanitizer target-libvtv"
noconfigdirs="$noconfigdirs target-libcilkrts target-liboffloadmic target-libitm target-libsanitizer target-libvtv"
;;
esac

View File

@ -1,3 +1,7 @@
2014-11-13 Kirill Yukhin <kirill.yukhin@intel.com>
* configure.tgt: Use config/target-posix.
2014-11-11 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
PR target/63610

View File

@ -43,19 +43,4 @@ case "${target}" in
esac
# Disable libcilkrts on non POSIX hosted systems.
if test x$enable_libcilkrts = x ; then
# Enable libcilkrts by default on hosted POSIX systems.
case "${target}" in
*-*-linux* | *-*-gnu* | *-*-k*bsd*-gnu | *-*-kopensolaris*-gnu)
;;
*-*-netbsd* | *-*-freebsd* | *-*-openbsd* | *-*-dragonfly*)
;;
*-*-solaris2* | *-*-hpux11*)
;;
*-*-darwin* | *-*-aix*)
;;
*)
UNSUPPORTED=1
;;
esac
fi
. ${srcdir}/../config/target-posix

94
liboffloadmic/ChangeLog Normal file
View File

@ -0,0 +1,94 @@
2014-11-13 Kirill Yukhin <kirill.yukhin@intel.com>
Initial commit. Imported from upstream:
https://www.openmprtl.org/sites/default/files/liboffload_oss.tgz
* Makefile.am: New file.
* Makefile.in: New file, generated by automake.
* aclocal.m4: New file, generated by aclocal.
* configure: New file, generated by autoconf.
* configure.ac: New file.
* configure.tgt: Ditto.
* doc/doxygen/config: Ditto.
* doc/doxygen/header.tex: Ditto.
* include/coi/common/COIEngine_common.h: Ditto.
* include/coi/common/COIMacros_common.h: Ditto.
* include/coi/common/COIPerf_common.h : Ditto.
* include/coi/common/COIResult_common.h : Ditto.
* include/coi/common/COITypes_common.h: Ditto.
* include/coi/sink/COIBuffer_sink.h: Ditto.
* include/coi/sink/COIPipeline_sink.h: Ditto.
* include/coi/sink/COIProcess_sink.h: Ditto.
* include/coi/source/COIBuffer_source.h: Ditto.
* include/coi/source/COIEngine_source.h: Ditto.
* include/coi/source/COIEvent_source.h: Ditto.
* include/coi/source/COIPipeline_source.h: Ditto.
* include/coi/source/COIProcess_source.h: Ditto.
* include/myo/myo.h: Ditto.
* include/myo/myoimpl.h: Ditto.
* include/myo/myotypes.h: Ditto.
* liboffloadmic_host.spec.in: Ditto.
* liboffloadmic_target.spec.in: Ditto.
* runtime/cean_util.cpp: Ditto.
* runtime/cean_util.h: Ditto.
* runtime/coi/coi_client.cpp: Ditto.
* runtime/coi/coi_client.h: Ditto.
* runtime/coi/coi_server.cpp: Ditto.
* runtime/coi/coi_server.h: Ditto.
* runtime/compiler_if_host.cpp: Ditto.
* runtime/compiler_if_host.h: Ditto.
* runtime/compiler_if_target.cpp: Ditto.
* runtime/compiler_if_target.h: Ditto.
* runtime/dv_util.cpp: Ditto.
* runtime/dv_util.h: Ditto.
* runtime/emulator/coi_common.h: Ditto.
* runtime/emulator/coi_device.cpp: Ditto.
* runtime/emulator/coi_device.h: Ditto.
* runtime/emulator/coi_host.cpp: Ditto.
* runtime/emulator/coi_host.h: Ditto.
* runtime/emulator/coi_version_asm.h: Ditto.
* runtime/emulator/coi_version_linker_script.map: Ditto.
* runtime/emulator/myo_client.cpp: Ditto.
* runtime/emulator/myo_service.cpp: Ditto.
* runtime/emulator/myo_service.h: Ditto.
* runtime/emulator/myo_version_asm.h: Ditto.
* runtime/emulator/myo_version_linker_script.map: Ditto.
* runtime/liboffload_error.c: Ditto.
* runtime/liboffload_error_codes.h: Ditto.
* runtime/liboffload_msg.c: Ditto.
* runtime/liboffload_msg.h: Ditto.
* runtime/mic_lib.f90: Ditto.
* runtime/offload.h: Ditto.
* runtime/offload_common.cpp: Ditto.
* runtime/offload_common.h: Ditto.
* runtime/offload_engine.cpp: Ditto.
* runtime/offload_engine.h: Ditto.
* runtime/offload_env.cpp: Ditto.
* runtime/offload_env.h: Ditto.
* runtime/offload_host.cpp: Ditto.
* runtime/offload_host.h: Ditto.
* runtime/offload_myo_host.cpp: Ditto.
* runtime/offload_myo_host.h: Ditto.
* runtime/offload_myo_target.cpp: Ditto.
* runtime/offload_myo_target.h: Ditto.
* runtime/offload_omp_host.cpp: Ditto.
* runtime/offload_omp_target.cpp: Ditto.
* runtime/offload_orsl.cpp: Ditto.
* runtime/offload_orsl.h: Ditto.
* runtime/offload_table.cpp: Ditto.
* runtime/offload_table.h: Ditto.
* runtime/offload_target.cpp: Ditto.
* runtime/offload_target.h: Ditto.
* runtime/offload_target_main.cpp: Ditto.
* runtime/offload_timer.h: Ditto.
* runtime/offload_timer_host.cpp: Ditto.
* runtime/offload_timer_target.cpp: Ditto.
* runtime/offload_trace.cpp: Ditto.
* runtime/offload_trace.h: Ditto.
* runtime/offload_util.cpp: Ditto.
* runtime/offload_util.h: Ditto.
* runtime/ofldbegin.cpp: Ditto.
* runtime/ofldend.cpp: Ditto.
* runtime/orsl-lite/include/orsl-lite.h: Ditto.
* runtime/orsl-lite/lib/orsl-lite.c: Ditto.
* runtime/orsl-lite/version.txt: Ditto.
* runtime/use_mpss2.txt: Ditto.

172
liboffloadmic/Makefile.am Normal file
View File

@ -0,0 +1,172 @@
#
# Copyright (c) 2014 Intel Corporation. All Rights Reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of Intel Corporation nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
AUTOMAKE_OPTIONS = foreign
ACLOCAL_AMFLAGS = -I .. -I ../config
# Build plugin for Intel MIC
SUBDIRS = . plugin
# Directories.
build_dir = $(top_builddir)
coi_inc_dir = $(top_srcdir)/include/coi
myo_inc_dir = $(top_srcdir)/include/myo
libgomp_dir = $(build_dir)/../libgomp
source_dir = $(top_srcdir)/runtime
# May be used by toolexeclibdir.
gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER)
libsubincludedir = $(libdir)/gcc/$(target_alias)/$(gcc_version)/include
# Target list.
if LIBOFFLOADMIC_HOST
nodist_toolexeclib_HEADERS = liboffloadmic_host.spec
toolexeclib_LTLIBRARIES = libcoi_host.la libmyo-client.la liboffloadmic_host.la
nodist_libsubinclude_HEADERS = runtime/compiler_if_host.h
ofld_obj =
else # LIBOFFLOADMIC_TARGET
nodist_toolexeclib_HEADERS = liboffloadmic_target.spec
toolexeclib_LTLIBRARIES = libcoi_device.la libmyo-service.la liboffloadmic_target.la
nodist_libsubinclude_HEADERS = runtime/compiler_if_target.h
ofld_obj = ofldbegin.o ofldend.o
endif
# Liboffloadmic.
liboffloadmic_sources = runtime/dv_util.cpp \
runtime/liboffload_error.c \
runtime/liboffload_msg.c \
runtime/offload_common.cpp \
runtime/offload_table.cpp \
runtime/offload_trace.cpp \
runtime/offload_util.cpp
liboffloadmic_cppflags = -DLINUX -DCOI_LIBRARY_VERSION=2 -DMYO_SUPPORT -DOFFLOAD_DEBUG=1 -DSEP_SUPPORT -DTIMING_SUPPORT -I$(coi_inc_dir) -I$(myo_inc_dir) -I$(source_dir) -I$(libgomp_dir)
liboffloadmic_host_la_SOURCES = $(liboffloadmic_sources) \
runtime/cean_util.cpp \
runtime/coi/coi_client.cpp \
runtime/compiler_if_host.cpp \
runtime/offload_engine.cpp \
runtime/offload_env.cpp \
runtime/offload_host.cpp \
runtime/offload_myo_host.cpp \
runtime/offload_omp_host.cpp \
runtime/offload_orsl.cpp \
runtime/offload_timer_host.cpp \
runtime/orsl-lite/lib/orsl-lite.c
liboffloadmic_host_la_CPPFLAGS = $(liboffloadmic_cppflags) -DHOST_LIBRARY=1
liboffloadmic_host_la_LDFLAGS = @lt_cv_dlopen_libs@ -version-info 5:0:0
liboffloadmic_host_la_LIBADD = libcoi_host.la libmyo-client.la
liboffloadmic_host_la_DEPENDENCIES = $(liboffloadmic_host_la_LIBADD)
liboffloadmic_target_la_SOURCES = $(liboffloadmic_sources) \
runtime/coi/coi_server.cpp \
runtime/compiler_if_target.cpp \
runtime/offload_myo_target.cpp \
runtime/offload_omp_target.cpp \
runtime/offload_target.cpp \
runtime/offload_timer_target.cpp
liboffloadmic_target_la_CPPFLAGS = $(liboffloadmic_cppflags) -DHOST_LIBRARY=0
liboffloadmic_target_la_LDFLAGS = @lt_cv_dlopen_libs@ -version-info 5:0:0
liboffloadmic_target_la_LIBADD = libcoi_device.la libmyo-service.la
liboffloadmic_target_la_DEPENDENCIES = $(liboffloadmic_target_la_LIBADD)
# Emulator.
libcoi_host_la_SOURCES = runtime/emulator/coi_host.cpp
libcoi_device_la_SOURCES = runtime/emulator/coi_device.cpp
libmyo_client_la_SOURCES = runtime/emulator/myo_client.cpp
libmyo_service_la_SOURCES = runtime/emulator/myo_service.cpp
libcoi_host_la_DEPENDENCIES = runtime/emulator/coi_version_linker_script.map
libcoi_device_la_DEPENDENCIES = runtime/emulator/coi_version_linker_script.map
libmyo_client_la_DEPENDENCIES = runtime/emulator/myo_version_linker_script.map
libmyo_service_la_DEPENDENCIES = runtime/emulator/myo_version_linker_script.map
libcoi_host_la_CPPFLAGS = -I$(coi_inc_dir)
libcoi_device_la_CPPFLAGS = -I$(coi_inc_dir)
libmyo_client_la_CPPFLAGS = -I$(myo_inc_dir)
libmyo_service_la_CPPFLAGS = -I$(myo_inc_dir)
libcoi_host_la_LDFLAGS = -lrt -Wl,--version-script=$(source_dir)/emulator/coi_version_linker_script.map
libcoi_device_la_LDFLAGS = -lrt -Wl,--version-script=$(source_dir)/emulator/coi_version_linker_script.map
libmyo_client_la_LDFLAGS = -lrt -Wl,--version-script=$(source_dir)/emulator/myo_version_linker_script.map
libmyo_service_la_LDFLAGS = -lrt -Wl,--version-script=$(source_dir)/emulator/myo_version_linker_script.map
# ofldbegin, ofldend
all-local: $(ofld_obj)
ofldbegin.o: runtime/ofldbegin.cpp
$(CXXCOMPILE) $(liboffloadmic_target_la_CPPFLAGS) -c $< -o $@
ofldend.o: runtime/ofldend.cpp
$(CXXCOMPILE) $(liboffloadmic_target_la_CPPFLAGS) -c $< -o $@
# Work around what appears to be a GNU make bug handling MAKEFLAGS
# values defined in terms of make variables, as is the case for CC and
# friends when we are called from the top level Makefile.
AM_MAKEFLAGS = \
"AR_FLAGS=$(AR_FLAGS)" \
"CC_FOR_BUILD=$(CC_FOR_BUILD)" \
"CFLAGS=$(CFLAGS)" \
"CXXFLAGS=$(CXXFLAGS)" \
"CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \
"CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \
"INSTALL=$(INSTALL)" \
"INSTALL_DATA=$(INSTALL_DATA)" \
"INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
"INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \
"JC1FLAGS=$(JC1FLAGS)" \
"LDFLAGS=$(LDFLAGS)" \
"LIBCFLAGS=$(LIBCFLAGS)" \
"LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \
"MAKE=$(MAKE)" \
"MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \
"PICFLAG=$(PICFLAG)" \
"PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \
"SHELL=$(SHELL)" \
"RUNTESTFLAGS=$(RUNTESTFLAGS)" \
"exec_prefix=$(exec_prefix)" \
"infodir=$(infodir)" \
"libdir=$(libdir)" \
"prefix=$(prefix)" \
"includedir=$(includedir)" \
"AR=$(AR)" \
"AS=$(AS)" \
"LD=$(LD)" \
"LIBCFLAGS=$(LIBCFLAGS)" \
"NM=$(NM)" \
"PICFLAG=$(PICFLAG)" \
"RANLIB=$(RANLIB)" \
"DESTDIR=$(DESTDIR)"
MAKEOVERRIDES =

1254
liboffloadmic/Makefile.in Normal file

File diff suppressed because it is too large Load Diff

979
liboffloadmic/aclocal.m4 vendored Normal file
View File

@ -0,0 +1,979 @@
# generated automatically by aclocal 1.11.1 -*- Autoconf -*-
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.64],,
[m4_warning([this file was generated for autoconf 2.64.
You have another version of autoconf. It may work, but is not guaranteed to.
If you have problems, you may need to regenerate the build system entirely.
To do so, use the procedure documented by the package, typically `autoreconf'.])])
# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# AM_AUTOMAKE_VERSION(VERSION)
# ----------------------------
# Automake X.Y traces this macro to ensure aclocal.m4 has been
# generated from the m4 files accompanying Automake X.Y.
# (This private macro should not be called outside this file.)
AC_DEFUN([AM_AUTOMAKE_VERSION],
[am__api_version='1.11'
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
dnl require some minimum version. Point them to the right macro.
m4_if([$1], [1.11.1], [],
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
])
# _AM_AUTOCONF_VERSION(VERSION)
# -----------------------------
# aclocal traces this macro to find the Autoconf version.
# This is a private macro too. Using m4_define simplifies
# the logic in aclocal, which can simply ignore this definition.
m4_define([_AM_AUTOCONF_VERSION], [])
# AM_SET_CURRENT_AUTOMAKE_VERSION
# -------------------------------
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
[AM_AUTOMAKE_VERSION([1.11.1])dnl
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
#
# Of course, Automake must honor this variable whenever it calls a
# tool from the auxiliary directory. The problem is that $srcdir (and
# therefore $ac_aux_dir as well) can be either absolute or relative,
# depending on how configure is run. This is pretty annoying, since
# it makes $ac_aux_dir quite unusable in subdirectories: in the top
# source directory, any form will work fine, but in subdirectories a
# relative path needs to be adjusted first.
#
# $ac_aux_dir/missing
# fails when called from a subdirectory if $ac_aux_dir is relative
# $top_srcdir/$ac_aux_dir/missing
# fails if $ac_aux_dir is absolute,
# fails when called from a subdirectory in a VPATH build with
# a relative $ac_aux_dir
#
# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
# are both prefixed by $srcdir. In an in-source build this is usually
# harmless because $srcdir is `.', but things will broke when you
# start a VPATH build or use an absolute $srcdir.
#
# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
# and then we would define $MISSING as
# MISSING="\${SHELL} $am_aux_dir/missing"
# This will work as long as MISSING is not called from configure, because
# unfortunately $(top_srcdir) has no meaning in configure.
# However there are other variables, like CC, which are often used in
# configure, and could therefore not use this "fixed" $ac_aux_dir.
#
# Another solution, used here, is to always expand $ac_aux_dir to an
# absolute PATH. The drawback is that using absolute paths prevent a
# configured tree to be moved without reconfiguration.
AC_DEFUN([AM_AUX_DIR_EXPAND],
[dnl Rely on autoconf to set up CDPATH properly.
AC_PREREQ([2.50])dnl
# expand $ac_aux_dir to an absolute path
am_aux_dir=`cd $ac_aux_dir && pwd`
])
# AM_CONDITIONAL -*- Autoconf -*-
# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008
# Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 9
# AM_CONDITIONAL(NAME, SHELL-CONDITION)
# -------------------------------------
# Define a conditional.
AC_DEFUN([AM_CONDITIONAL],
[AC_PREREQ(2.52)dnl
ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
[$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
AC_SUBST([$1_TRUE])dnl
AC_SUBST([$1_FALSE])dnl
_AM_SUBST_NOTMAKE([$1_TRUE])dnl
_AM_SUBST_NOTMAKE([$1_FALSE])dnl
m4_define([_AM_COND_VALUE_$1], [$2])dnl
if $2; then
$1_TRUE=
$1_FALSE='#'
else
$1_TRUE='#'
$1_FALSE=
fi
AC_CONFIG_COMMANDS_PRE(
[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
AC_MSG_ERROR([[conditional "$1" was never defined.
Usually this means the macro was only invoked conditionally.]])
fi])])
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009
# Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 10
# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
# written in clear, in which case automake, when reading aclocal.m4,
# will think it sees a *use*, and therefore will trigger all it's
# C support machinery. Also note that it means that autoscan, seeing
# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
# _AM_DEPENDENCIES(NAME)
# ----------------------
# See how the compiler implements dependency checking.
# NAME is "CC", "CXX", "GCJ", or "OBJC".
# We try a few techniques and use that to set a single cache variable.
#
# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
# dependency, and given that the user is not expected to run this macro,
# just rely on AC_PROG_CC.
AC_DEFUN([_AM_DEPENDENCIES],
[AC_REQUIRE([AM_SET_DEPDIR])dnl
AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
AC_REQUIRE([AM_MAKE_INCLUDE])dnl
AC_REQUIRE([AM_DEP_TRACK])dnl
ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
[$1], CXX, [depcc="$CXX" am_compiler_list=],
[$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
[$1], UPC, [depcc="$UPC" am_compiler_list=],
[$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
[depcc="$$1" am_compiler_list=])
AC_CACHE_CHECK([dependency style of $depcc],
[am_cv_$1_dependencies_compiler_type],
[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
# We make a subdir and do the tests there. Otherwise we can end up
# making bogus files that we don't know about and never remove. For
# instance it was reported that on HP-UX the gcc test will end up
# making a dummy file named `D' -- because `-MD' means `put the output
# in D'.
mkdir conftest.dir
# Copy depcomp to subdir because otherwise we won't find it if we're
# using a relative directory.
cp "$am_depcomp" conftest.dir
cd conftest.dir
# We will build objects and dependencies in a subdirectory because
# it helps to detect inapplicable dependency modes. For instance
# both Tru64's cc and ICC support -MD to output dependencies as a
# side effect of compilation, but ICC will put the dependencies in
# the current directory while Tru64 will put them in the object
# directory.
mkdir sub
am_cv_$1_dependencies_compiler_type=none
if test "$am_compiler_list" = ""; then
am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
fi
am__universal=false
m4_case([$1], [CC],
[case " $depcc " in #(
*\ -arch\ *\ -arch\ *) am__universal=true ;;
esac],
[CXX],
[case " $depcc " in #(
*\ -arch\ *\ -arch\ *) am__universal=true ;;
esac])
for depmode in $am_compiler_list; do
# Setup a source with many dependencies, because some compilers
# like to wrap large dependency lists on column 80 (with \), and
# we should not choose a depcomp mode which is confused by this.
#
# We need to recreate these files for each test, as the compiler may
# overwrite some of them when testing with obscure command lines.
# This happens at least with the AIX C compiler.
: > sub/conftest.c
for i in 1 2 3 4 5 6; do
echo '#include "conftst'$i'.h"' >> sub/conftest.c
# Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
# Solaris 8's {/usr,}/bin/sh.
touch sub/conftst$i.h
done
echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
# We check with `-c' and `-o' for the sake of the "dashmstdout"
# mode. It turns out that the SunPro C++ compiler does not properly
# handle `-M -o', and we need to detect this. Also, some Intel
# versions had trouble with output in subdirs
am__obj=sub/conftest.${OBJEXT-o}
am__minus_obj="-o $am__obj"
case $depmode in
gcc)
# This depmode causes a compiler race in universal mode.
test "$am__universal" = false || continue
;;
nosideeffect)
# after this tag, mechanisms are not by side-effect, so they'll
# only be used when explicitly requested
if test "x$enable_dependency_tracking" = xyes; then
continue
else
break
fi
;;
msvisualcpp | msvcmsys)
# This compiler won't grok `-c -o', but also, the minuso test has
# not run yet. These depmodes are late enough in the game, and
# so weak that their functioning should not be impacted.
am__obj=conftest.${OBJEXT-o}
am__minus_obj=
;;
none) break ;;
esac
if depmode=$depmode \
source=sub/conftest.c object=$am__obj \
depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
$SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
>/dev/null 2>conftest.err &&
grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
${MAKE-make} -s -f confmf > /dev/null 2>&1; then
# icc doesn't choke on unknown options, it will just issue warnings
# or remarks (even with -Werror). So we grep stderr for any message
# that says an option was ignored or not supported.
# When given -MP, icc 7.0 and 7.1 complain thusly:
# icc: Command line warning: ignoring option '-M'; no argument required
# The diagnosis changed in icc 8.0:
# icc: Command line remark: option '-MP' not supported
if (grep 'ignoring option' conftest.err ||
grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
am_cv_$1_dependencies_compiler_type=$depmode
break
fi
fi
done
cd ..
rm -rf conftest.dir
else
am_cv_$1_dependencies_compiler_type=none
fi
])
AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
AM_CONDITIONAL([am__fastdep$1], [
test "x$enable_dependency_tracking" != xno \
&& test "$am_cv_$1_dependencies_compiler_type" = gcc3])
])
# AM_SET_DEPDIR
# -------------
# Choose a directory name for dependency files.
# This macro is AC_REQUIREd in _AM_DEPENDENCIES
AC_DEFUN([AM_SET_DEPDIR],
[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
])
# AM_DEP_TRACK
# ------------
AC_DEFUN([AM_DEP_TRACK],
[AC_ARG_ENABLE(dependency-tracking,
[ --disable-dependency-tracking speeds up one-time build
--enable-dependency-tracking do not reject slow dependency extractors])
if test "x$enable_dependency_tracking" != xno; then
am_depcomp="$ac_aux_dir/depcomp"
AMDEPBACKSLASH='\'
fi
AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
AC_SUBST([AMDEPBACKSLASH])dnl
_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
])
# Generate code to set up dependency tracking. -*- Autoconf -*-
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
# Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
#serial 5
# _AM_OUTPUT_DEPENDENCY_COMMANDS
# ------------------------------
AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
[{
# Autoconf 2.62 quotes --file arguments for eval, but not when files
# are listed without --file. Let's play safe and only enable the eval
# if we detect the quoting.
case $CONFIG_FILES in
*\'*) eval set x "$CONFIG_FILES" ;;
*) set x $CONFIG_FILES ;;
esac
shift
for mf
do
# Strip MF so we end up with the name of the file.
mf=`echo "$mf" | sed -e 's/:.*$//'`
# Check whether this is an Automake generated Makefile or not.
# We used to match only the files named `Makefile.in', but
# some people rename them; so instead we look at the file content.
# Grep'ing the first line is not enough: some people post-process
# each Makefile.in and add a new line on top of each file to say so.
# Grep'ing the whole file is not good either: AIX grep has a line
# limit of 2048, but all sed's we know have understand at least 4000.
if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
dirpart=`AS_DIRNAME("$mf")`
else
continue
fi
# Extract the definition of DEPDIR, am__include, and am__quote
# from the Makefile without running `make'.
DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
test -z "$DEPDIR" && continue
am__include=`sed -n 's/^am__include = //p' < "$mf"`
test -z "am__include" && continue
am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
# When using ansi2knr, U may be empty or an underscore; expand it
U=`sed -n 's/^U = //p' < "$mf"`
# Find all dependency output files, they are included files with
# $(DEPDIR) in their names. We invoke sed twice because it is the
# simplest approach to changing $(DEPDIR) to its actual value in the
# expansion.
for file in `sed -n "
s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
# Make sure the directory exists.
test -f "$dirpart/$file" && continue
fdir=`AS_DIRNAME(["$file"])`
AS_MKDIR_P([$dirpart/$fdir])
# echo "creating $dirpart/$file"
echo '# dummy' > "$dirpart/$file"
done
done
}
])# _AM_OUTPUT_DEPENDENCY_COMMANDS
# AM_OUTPUT_DEPENDENCY_COMMANDS
# -----------------------------
# This macro should only be invoked once -- use via AC_REQUIRE.
#
# This code is only required when automatic dependency tracking
# is enabled. FIXME. This creates each `.P' file that we will
# need in order to bootstrap the dependency handling code.
AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
[AC_CONFIG_COMMANDS([depfiles],
[test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
[AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
])
# Do all the work for Automake. -*- Autoconf -*-
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
# 2005, 2006, 2008, 2009 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 16
# This macro actually does too much. Some checks are only needed if
# your package does certain things. But this isn't really a big deal.
# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
# AM_INIT_AUTOMAKE([OPTIONS])
# -----------------------------------------------
# The call with PACKAGE and VERSION arguments is the old style
# call (pre autoconf-2.50), which is being phased out. PACKAGE
# and VERSION should now be passed to AC_INIT and removed from
# the call to AM_INIT_AUTOMAKE.
# We support both call styles for the transition. After
# the next Automake release, Autoconf can make the AC_INIT
# arguments mandatory, and then we can depend on a new Autoconf
# release and drop the old call support.
AC_DEFUN([AM_INIT_AUTOMAKE],
[AC_PREREQ([2.62])dnl
dnl Autoconf wants to disallow AM_ names. We explicitly allow
dnl the ones we care about.
m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
AC_REQUIRE([AC_PROG_INSTALL])dnl
if test "`cd $srcdir && pwd`" != "`pwd`"; then
# Use -I$(srcdir) only when $(srcdir) != ., so that make's output
# is not polluted with repeated "-I."
AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
# test to see if srcdir already configured
if test -f $srcdir/config.status; then
AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
fi
fi
# test whether we have cygpath
if test -z "$CYGPATH_W"; then
if (cygpath --version) >/dev/null 2>/dev/null; then
CYGPATH_W='cygpath -w'
else
CYGPATH_W=echo
fi
fi
AC_SUBST([CYGPATH_W])
# Define the identity of the package.
dnl Distinguish between old-style and new-style calls.
m4_ifval([$2],
[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
AC_SUBST([PACKAGE], [$1])dnl
AC_SUBST([VERSION], [$2])],
[_AM_SET_OPTIONS([$1])dnl
dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
[m4_fatal([AC_INIT should be called with package and version arguments])])dnl
AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
_AM_IF_OPTION([no-define],,
[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
# Some tools Automake needs.
AC_REQUIRE([AM_SANITY_CHECK])dnl
AC_REQUIRE([AC_ARG_PROGRAM])dnl
AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
AM_MISSING_PROG(AUTOCONF, autoconf)
AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
AM_MISSING_PROG(AUTOHEADER, autoheader)
AM_MISSING_PROG(MAKEINFO, makeinfo)
AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
AC_REQUIRE([AM_PROG_MKDIR_P])dnl
# We need awk for the "check" target. The system "awk" is bad on
# some platforms.
AC_REQUIRE([AC_PROG_AWK])dnl
AC_REQUIRE([AC_PROG_MAKE_SET])dnl
AC_REQUIRE([AM_SET_LEADING_DOT])dnl
_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
[_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
[_AM_PROG_TAR([v7])])])
_AM_IF_OPTION([no-dependencies],,
[AC_PROVIDE_IFELSE([AC_PROG_CC],
[_AM_DEPENDENCIES(CC)],
[define([AC_PROG_CC],
defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
AC_PROVIDE_IFELSE([AC_PROG_CXX],
[_AM_DEPENDENCIES(CXX)],
[define([AC_PROG_CXX],
defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
AC_PROVIDE_IFELSE([AC_PROG_OBJC],
[_AM_DEPENDENCIES(OBJC)],
[define([AC_PROG_OBJC],
defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
])
_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl
dnl The `parallel-tests' driver may need to know about EXEEXT, so add the
dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro
dnl is hooked onto _AC_COMPILER_EXEEXT early, see below.
AC_CONFIG_COMMANDS_PRE(dnl
[m4_provide_if([_AM_COMPILER_EXEEXT],
[AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
])
dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
dnl mangled by Autoconf and run in a shell conditional statement.
m4_define([_AC_COMPILER_EXEEXT],
m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
# When config.status generates a header, we must update the stamp-h file.
# This file resides in the same directory as the config header
# that is generated. The stamp files are numbered to have different names.
# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
# loop where config.status creates the headers, so we can generate
# our stamp files there.
AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
[# Compute $1's index in $config_headers.
_am_arg=$1
_am_stamp_count=1
for _am_header in $config_headers :; do
case $_am_header in
$_am_arg | $_am_arg:* )
break ;;
* )
_am_stamp_count=`expr $_am_stamp_count + 1` ;;
esac
done
echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
# Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# AM_PROG_INSTALL_SH
# ------------------
# Define $install_sh.
AC_DEFUN([AM_PROG_INSTALL_SH],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
if test x"${install_sh}" != xset; then
case $am_aux_dir in
*\ * | *\ *)
install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
*)
install_sh="\${SHELL} $am_aux_dir/install-sh"
esac
fi
AC_SUBST(install_sh)])
# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
# From Jim Meyering
# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008
# Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 5
# AM_MAINTAINER_MODE([DEFAULT-MODE])
# ----------------------------------
# Control maintainer-specific portions of Makefiles.
# Default is to disable them, unless `enable' is passed literally.
# For symmetry, `disable' may be passed as well. Anyway, the user
# can override the default with the --enable/--disable switch.
AC_DEFUN([AM_MAINTAINER_MODE],
[m4_case(m4_default([$1], [disable]),
[enable], [m4_define([am_maintainer_other], [disable])],
[disable], [m4_define([am_maintainer_other], [enable])],
[m4_define([am_maintainer_other], [enable])
m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])
AC_MSG_CHECKING([whether to am_maintainer_other maintainer-specific portions of Makefiles])
dnl maintainer-mode's default is 'disable' unless 'enable' is passed
AC_ARG_ENABLE([maintainer-mode],
[ --][am_maintainer_other][-maintainer-mode am_maintainer_other make rules and dependencies not useful
(and sometimes confusing) to the casual installer],
[USE_MAINTAINER_MODE=$enableval],
[USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))
AC_MSG_RESULT([$USE_MAINTAINER_MODE])
AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
MAINT=$MAINTAINER_MODE_TRUE
AC_SUBST([MAINT])dnl
]
)
AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
# Check to see how 'make' treats includes. -*- Autoconf -*-
# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 4
# AM_MAKE_INCLUDE()
# -----------------
# Check to see how make treats includes.
AC_DEFUN([AM_MAKE_INCLUDE],
[am_make=${MAKE-make}
cat > confinc << 'END'
am__doit:
@echo this is the am__doit target
.PHONY: am__doit
END
# If we don't find an include directive, just comment out the code.
AC_MSG_CHECKING([for style of include used by $am_make])
am__include="#"
am__quote=
_am_result=none
# First try GNU make style include.
echo "include confinc" > confmf
# Ignore all kinds of additional output from `make'.
case `$am_make -s -f confmf 2> /dev/null` in #(
*the\ am__doit\ target*)
am__include=include
am__quote=
_am_result=GNU
;;
esac
# Now try BSD make style include.
if test "$am__include" = "#"; then
echo '.include "confinc"' > confmf
case `$am_make -s -f confmf 2> /dev/null` in #(
*the\ am__doit\ target*)
am__include=.include
am__quote="\""
_am_result=BSD
;;
esac
fi
AC_SUBST([am__include])
AC_SUBST([am__quote])
AC_MSG_RESULT([$_am_result])
rm -f confinc confmf
])
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008
# Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 6
# AM_MISSING_PROG(NAME, PROGRAM)
# ------------------------------
AC_DEFUN([AM_MISSING_PROG],
[AC_REQUIRE([AM_MISSING_HAS_RUN])
$1=${$1-"${am_missing_run}$2"}
AC_SUBST($1)])
# AM_MISSING_HAS_RUN
# ------------------
# Define MISSING if not defined so far and test if it supports --run.
# If it does, set am_missing_run to use it, otherwise, to nothing.
AC_DEFUN([AM_MISSING_HAS_RUN],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
AC_REQUIRE_AUX_FILE([missing])dnl
if test x"${MISSING+set}" != xset; then
case $am_aux_dir in
*\ * | *\ *)
MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
*)
MISSING="\${SHELL} $am_aux_dir/missing" ;;
esac
fi
# Use eval to expand $SHELL
if eval "$MISSING --run true"; then
am_missing_run="$MISSING --run "
else
am_missing_run=
AC_MSG_WARN([`missing' script is too old or missing])
fi
])
# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# AM_PROG_MKDIR_P
# ---------------
# Check for `mkdir -p'.
AC_DEFUN([AM_PROG_MKDIR_P],
[AC_PREREQ([2.60])dnl
AC_REQUIRE([AC_PROG_MKDIR_P])dnl
dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P,
dnl while keeping a definition of mkdir_p for backward compatibility.
dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
dnl Makefile.ins that do not define MKDIR_P, so we do our own
dnl adjustment using top_builddir (which is defined more often than
dnl MKDIR_P).
AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
case $mkdir_p in
[[\\/$]]* | ?:[[\\/]]*) ;;
*/*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
esac
])
# Helper functions for option handling. -*- Autoconf -*-
# Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 4
# _AM_MANGLE_OPTION(NAME)
# -----------------------
AC_DEFUN([_AM_MANGLE_OPTION],
[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
# _AM_SET_OPTION(NAME)
# ------------------------------
# Set option NAME. Presently that only means defining a flag for this option.
AC_DEFUN([_AM_SET_OPTION],
[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
# _AM_SET_OPTIONS(OPTIONS)
# ----------------------------------
# OPTIONS is a space-separated list of Automake options.
AC_DEFUN([_AM_SET_OPTIONS],
[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
# -------------------------------------------
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
AC_DEFUN([_AM_IF_OPTION],
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
# Check to make sure that the build environment is sane. -*- Autoconf -*-
# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008
# Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 5
# AM_SANITY_CHECK
# ---------------
AC_DEFUN([AM_SANITY_CHECK],
[AC_MSG_CHECKING([whether build environment is sane])
# Just in case
sleep 1
echo timestamp > conftest.file
# Reject unsafe characters in $srcdir or the absolute working directory
# name. Accept space and tab only in the latter.
am_lf='
'
case `pwd` in
*[[\\\"\#\$\&\'\`$am_lf]]*)
AC_MSG_ERROR([unsafe absolute working directory name]);;
esac
case $srcdir in
*[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);;
esac
# Do `set' in a subshell so we don't clobber the current shell's
# arguments. Must try -L first in case configure is actually a
# symlink; some systems play weird games with the mod time of symlinks
# (eg FreeBSD returns the mod time of the symlink's containing
# directory).
if (
set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
if test "$[*]" = "X"; then
# -L didn't work.
set X `ls -t "$srcdir/configure" conftest.file`
fi
rm -f conftest.file
if test "$[*]" != "X $srcdir/configure conftest.file" \
&& test "$[*]" != "X conftest.file $srcdir/configure"; then
# If neither matched, then we have a broken ls. This can happen
# if, for instance, CONFIG_SHELL is bash and it inherits a
# broken ls alias from the environment. This has actually
# happened. Such a system could not be considered "sane".
AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
alias in your environment])
fi
test "$[2]" = conftest.file
)
then
# Ok.
:
else
AC_MSG_ERROR([newly created file is older than distributed files!
Check your system clock])
fi
AC_MSG_RESULT(yes)])
# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# AM_PROG_INSTALL_STRIP
# ---------------------
# One issue with vendor `install' (even GNU) is that you can't
# specify the program used to strip binaries. This is especially
# annoying in cross-compiling environments, where the build's strip
# is unlikely to handle the host's binaries.
# Fortunately install-sh will honor a STRIPPROG variable, so we
# always use install-sh in `make install-strip', and initialize
# STRIPPROG with the value of the STRIP variable (set by the user).
AC_DEFUN([AM_PROG_INSTALL_STRIP],
[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
# Installed binaries are usually stripped using `strip' when the user
# run `make install-strip'. However `strip' might not be the right
# tool to use in cross-compilation environments, therefore Automake
# will honor the `STRIP' environment variable to overrule this program.
dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
if test "$cross_compiling" != no; then
AC_CHECK_TOOL([STRIP], [strip], :)
fi
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
AC_SUBST([INSTALL_STRIP_PROGRAM])])
# Copyright (C) 2006, 2008 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 2
# _AM_SUBST_NOTMAKE(VARIABLE)
# ---------------------------
# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
# This macro is traced by Automake.
AC_DEFUN([_AM_SUBST_NOTMAKE])
# AM_SUBST_NOTMAKE(VARIABLE)
# ---------------------------
# Public sister of _AM_SUBST_NOTMAKE.
AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
# Check how to create a tarball. -*- Autoconf -*-
# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# serial 2
# _AM_PROG_TAR(FORMAT)
# --------------------
# Check how to create a tarball in format FORMAT.
# FORMAT should be one of `v7', `ustar', or `pax'.
#
# Substitute a variable $(am__tar) that is a command
# writing to stdout a FORMAT-tarball containing the directory
# $tardir.
# tardir=directory && $(am__tar) > result.tar
#
# Substitute a variable $(am__untar) that extract such
# a tarball read from stdin.
# $(am__untar) < result.tar
AC_DEFUN([_AM_PROG_TAR],
[# Always define AMTAR for backward compatibility.
AM_MISSING_PROG([AMTAR], [tar])
m4_if([$1], [v7],
[am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
[m4_case([$1], [ustar],, [pax],,
[m4_fatal([Unknown tar format])])
AC_MSG_CHECKING([how to create a $1 tar archive])
# Loop over all known methods to create a tar archive until one works.
_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
_am_tools=${am_cv_prog_tar_$1-$_am_tools}
# Do not fold the above two line into one, because Tru64 sh and
# Solaris sh will not grok spaces in the rhs of `-'.
for _am_tool in $_am_tools
do
case $_am_tool in
gnutar)
for _am_tar in tar gnutar gtar;
do
AM_RUN_LOG([$_am_tar --version]) && break
done
am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
am__untar="$_am_tar -xf -"
;;
plaintar)
# Must skip GNU tar: if it does not support --format= it doesn't create
# ustar tarball either.
(tar --version) >/dev/null 2>&1 && continue
am__tar='tar chf - "$$tardir"'
am__tar_='tar chf - "$tardir"'
am__untar='tar xf -'
;;
pax)
am__tar='pax -L -x $1 -w "$$tardir"'
am__tar_='pax -L -x $1 -w "$tardir"'
am__untar='pax -r'
;;
cpio)
am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
am__untar='cpio -i -H $1 -d'
;;
none)
am__tar=false
am__tar_=false
am__untar=false
;;
esac
# If the value was cached, stop now. We just wanted to have am__tar
# and am__untar set.
test -n "${am_cv_prog_tar_$1}" && break
# tar/untar a dummy directory, and stop if the command works
rm -rf conftest.dir
mkdir conftest.dir
echo GrepMe > conftest.dir/file
AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
rm -rf conftest.dir
if test -s conftest.tar; then
AM_RUN_LOG([$am__untar <conftest.tar])
grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
fi
done
rm -rf conftest.dir
AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
AC_MSG_RESULT([$am_cv_prog_tar_$1])])
AC_SUBST([am__tar])
AC_SUBST([am__untar])
]) # _AM_PROG_TAR
m4_include([../config/depstand.m4])
m4_include([../config/lead-dot.m4])
m4_include([../config/multi.m4])
m4_include([../config/override.m4])
m4_include([../libtool.m4])
m4_include([../ltoptions.m4])
m4_include([../ltsugar.m4])
m4_include([../ltversion.m4])
m4_include([../lt~obsolete.m4])

16957
liboffloadmic/configure vendored Normal file

File diff suppressed because it is too large Load Diff

131
liboffloadmic/configure.ac Normal file
View File

@ -0,0 +1,131 @@
# Copyright (c) 2014 Intel Corporation. All Rights Reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of Intel Corporation nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# Process this file with autoconf to produce a configure script, like so:
# aclocal -I .. -I ../config && autoconf && automake
AC_PREREQ([2.64])
AC_INIT([MIC Offload Runtime Library], [1.0], ,[liboffloadmic])
AC_CANONICAL_SYSTEM
target_alias=${target_alias-$host_alias}
AC_SUBST(target_alias)
AM_INIT_AUTOMAKE(foreign no-dist)
AM_MAINTAINER_MODE
AC_PROG_CC
AC_PROG_CXX
AC_CONFIG_FILES([Makefile liboffloadmic_host.spec liboffloadmic_target.spec])
AM_ENABLE_MULTILIB(, ..)
AC_FUNC_ALLOCA
AC_CHECK_HEADERS([mm_malloc.h], [], [AC_MSG_ERROR(["Couldn't find mm_malloc.h"])])
AC_CHECK_FUNCS([__secure_getenv secure_getenv])
# Get target configure.
. ${srcdir}/configure.tgt
if test -n "$UNSUPPORTED"; then
AC_MSG_ERROR([Configuration ${target} is unsupported])
fi
if test "${multilib}" = "yes"; then
multilib_arg="--enable-multilib"
else
multilib_arg=
fi
AC_MSG_CHECKING([for --enable-version-specific-runtime-libs])
AC_ARG_ENABLE([version-specific-runtime-libs],
AC_HELP_STRING([--enable-version-specific-runtime-libs],
[Specify that runtime libraries should be installed in a compiler-specific directory]),
[case "$enableval" in
yes) enable_version_specific_runtime_libs=yes ;;
no) enable_version_specific_runtime_libs=no ;;
*) AC_MSG_ERROR([Unknown argument to enable/disable version-specific libs]);;
esac],
[enable_version_specific_runtime_libs=no])
AC_MSG_RESULT($enable_version_specific_runtime_libs)
# Make sure liboffloadmic is enabled
case "$enable_liboffloadmic" in
host | target)
;;
*)
AC_MSG_ERROR([Liboffloadmic is disabled]) ;;
esac
AM_CONDITIONAL(LIBOFFLOADMIC_HOST, [test x"$enable_liboffloadmic" = xhost])
# Calculate toolexeclibdir.
# Also toolexecdir, though it's only used in toolexeclibdir.
case ${enable_version_specific_runtime_libs} in
yes)
# Need the gcc compiler version to know where to install libraries
# and header files if --enable-version-specific-runtime-libs option
# is selected.
toolexecdir='$(libdir)/gcc/$(target_alias)'
toolexeclibdir='$(toolexecdir)/$(gcc_version)$(MULTISUBDIR)'
;;
no)
if test -n "$with_cross_host" &&
test x"$with_cross_host" != x"no"; then
# Install a library built with a cross compiler in tooldir, not libdir.
toolexecdir='$(exec_prefix)/$(target_alias)'
toolexeclibdir='$(toolexecdir)/lib'
else
toolexecdir='$(libdir)/gcc-lib/$(target_alias)'
toolexeclibdir='$(libdir)'
fi
multi_os_directory=`$CC -print-multi-os-directory`
case $multi_os_directory in
.) ;; # Avoid trailing /.
*) toolexeclibdir=$toolexeclibdir/$multi_os_directory ;;
esac
;;
esac
AC_LIBTOOL_DLOPEN
AM_PROG_LIBTOOL
# Forbid libtool to hardcode RPATH, because we want to be able to specify
# library search directory using LD_LIBRARY_PATH
hardcode_into_libs=no
AC_SUBST(toolexecdir)
AC_SUBST(toolexeclibdir)
AC_SUBST(lt_cv_dlopen_libs)
if test $enable_shared = yes; then
link_offloadmic_host="-loffloadmic_host %{static: $LIBS}"
link_offloadmic_target="-loffloadmic_target %{static: $LIBS}"
else
link_offloadmic_host="-loffloadmic_host $LIBS"
link_offloadmic_target="-loffloadmic_target $LIBS"
fi
AC_SUBST(link_offloadmic_host)
AC_SUBST(link_offloadmic_target)
# Must be last
AC_OUTPUT

View File

@ -0,0 +1,39 @@
# Copyright (c) 2014 Intel Corporation. All Rights Reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of Intel Corporation nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# Disable Offload Runtime library for non x86 architecture.
case "${target}" in
x86_64-*-linux*)
;;
i?86-*-linux*)
;;
*-*-*)
UNSUPPORTED=1 ;;
esac
# Disable liboffloadmic on non POSIX hosted systems.
. ${srcdir}/../config/target-posix

File diff suppressed because it is too large Load Diff

View File

@ -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}

View File

@ -0,0 +1,108 @@
/*
* Copyright 2010-2013 Intel Corporation.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, version 2.1.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* Disclaimer: The codes contained in these modules may be specific
* to the Intel Software Development Platform codenamed Knights Ferry,
* and the Intel product codenamed Knights Corner, and are not backward
* compatible with other Intel products. Additionally, Intel will NOT
* support the codes or instruction set in future products.
*
* Intel offers no warranty of any kind regarding the code. This code is
* licensed on an "AS IS" basis and Intel is not obligated to provide
* any support, assistance, installation, training, or other services
* of any kind. Intel is also not obligated to provide any updates,
* enhancements or extensions. Intel specifically disclaims any warranty
* of merchantability, non-infringement, fitness for any particular
* purpose, and any other warranty.
*
* Further, Intel disclaims all liability of any kind, including but
* not limited to liability for infringement of any proprietary rights,
* relating to the use of the code, even if Intel is notified of the
* possibility of such liability. Except as expressly stated in an Intel
* license agreement provided with this code and agreed upon with Intel,
* no license, express or implied, by estoppel or otherwise, to any
* intellectual property rights is granted herein.
*/
#ifndef _COIENGINE_COMMON_H
#define _COIENGINE_COMMON_H
/** @ingroup COIEngine
* @addtogroup COIEnginecommon
@{
* @file common/COIEngine_common.h
*/
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#include "../common/COITypes_common.h"
#include "../common/COIResult_common.h"
#ifdef __cplusplus
extern "C" {
#endif
#endif // DOXYGEN_SHOULD_SKIP_THIS
#define COI_MAX_ISA_x86_64_DEVICES 1
#define COI_MAX_ISA_MIC_DEVICES 128
#define COI_MAX_ISA_KNF_DEVICES COI_MAX_ISA_MIC_DEVICES
#define COI_MAX_ISA_KNC_DEVICES COI_MAX_ISA_MIC_DEVICES
///////////////////////////////////////////////////////////////////////////////
///
/// List of ISA types of supported engines.
///
typedef enum
{
COI_ISA_INVALID = 0, ///< Represents an invalid ISA.
COI_ISA_x86_64, ///< The ISA for an x86_64 host engine.
COI_ISA_MIC, ///< Special value used to represent any device
///< in the Intel(R) Many Integrated Core
///< architecture family.
COI_ISA_KNF, ///< ISA for L1OM devices.
COI_ISA_KNC ///< ISA for K1OM devices.
} COI_ISA_TYPE;
///////////////////////////////////////////////////////////////////////////////
///
/// Get the information about the COIEngine executing this function call.
///
/// @param out_pType
/// [out] The COI_ISA_TYPE of the engine.
///
/// @param out_pIndex
/// [out] The zero-based index of this engine in the collection of
/// engines of the ISA returned in out_pType.
///
/// @return COI_INVALID_POINTER if the any of the parameters are NULL.
///
/// @return COI_SUCCESS
///
COIACCESSAPI
COIRESULT
COIEngineGetIndex(
COI_ISA_TYPE* out_pType,
uint32_t* out_pIndex);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* _COIENGINE_COMMON_H */
/*! @} */

View File

@ -0,0 +1,69 @@
/*
* Copyright 2010-2013 Intel Corporation.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, version 2.1.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* Disclaimer: The codes contained in these modules may be specific
* to the Intel Software Development Platform codenamed Knights Ferry,
* and the Intel product codenamed Knights Corner, and are not backward
* compatible with other Intel products. Additionally, Intel will NOT
* support the codes or instruction set in future products.
*
* Intel offers no warranty of any kind regarding the code. This code is
* licensed on an "AS IS" basis and Intel is not obligated to provide
* any support, assistance, installation, training, or other services
* of any kind. Intel is also not obligated to provide any updates,
* enhancements or extensions. Intel specifically disclaims any warranty
* of merchantability, non-infringement, fitness for any particular
* purpose, and any other warranty.
*
* Further, Intel disclaims all liability of any kind, including but
* not limited to liability for infringement of any proprietary rights,
* relating to the use of the code, even if Intel is notified of the
* possibility of such liability. Except as expressly stated in an Intel
* license agreement provided with this code and agreed upon with Intel,
* no license, express or implied, by estoppel or otherwise, to any
* intellectual property rights is granted herein.
*/
#ifndef _COIMACROS_COMMON_H
#define _COIMACROS_COMMON_H
/// @file common/COIMacros_common.h
/// Commonly used macros
// Note that UNUSUED_ATTR means that it is "possibly" unused, not "definitely".
// This should compile out in release mode if indeed it is unused.
#define UNUSED_ATTR __attribute__((unused))
#ifndef UNREFERENCED_CONST_PARAM
#define UNREFERENCED_CONST_PARAM(P) { void* x UNUSED_ATTR = \
(void*)(uint64_t)P; \
}
#endif
// This seems to work on everything.
#ifndef UNREFERENCED_PARAM
#define UNREFERENCED_PARAM(P) (P = P)
#endif
#ifndef SYMBOL_VERSION
/* Linux support: */
#define SYMBOL_VERSION( SYMBOL , VERSION ) SYMBOL ## VERSION
#endif
#endif /* _COIMACROS_COMMON_H */

View File

@ -0,0 +1,87 @@
/*
* Copyright 2010-2013 Intel Corporation.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, version 2.1.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* Disclaimer: The codes contained in these modules may be specific
* to the Intel Software Development Platform codenamed Knights Ferry,
* and the Intel product codenamed Knights Corner, and are not backward
* compatible with other Intel products. Additionally, Intel will NOT
* support the codes or instruction set in future products.
*
* Intel offers no warranty of any kind regarding the code. This code is
* licensed on an "AS IS" basis and Intel is not obligated to provide
* any support, assistance, installation, training, or other services
* of any kind. Intel is also not obligated to provide any updates,
* enhancements or extensions. Intel specifically disclaims any warranty
* of merchantability, non-infringement, fitness for any particular
* purpose, and any other warranty.
*
* Further, Intel disclaims all liability of any kind, including but
* not limited to liability for infringement of any proprietary rights,
* relating to the use of the code, even if Intel is notified of the
* possibility of such liability. Except as expressly stated in an Intel
* license agreement provided with this code and agreed upon with Intel,
* no license, express or implied, by estoppel or otherwise, to any
* intellectual property rights is granted herein.
*/
#ifndef _COIPERF_COMMON_H
#define _COIPERF_COMMON_H
/** @ingroup COIPerf
* @addtogroup COIPerfCommon
@{
* @file common/COIPerf_common.h
* Performance Analysis API */
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#include "../common/COITypes_common.h"
#ifdef __cplusplus
extern "C" {
#endif
#endif // DOXYGEN_SHOULD_SKIP_THIS
///////////////////////////////////////////////////////////////////////////////
///
/// Returns a performance counter value
///
/// This function returns a performance counter value that increments
/// at a constant rate for all time and is coherent across all cores.
///
/// @return Current performance counter value or 0 if no performance counter
///// is available
///
///
COIACCESSAPI
uint64_t COIPerfGetCycleCounter(void);
///////////////////////////////////////////////////////////////////////////////
///
/// Returns the calculated system frequency in hertz.
///
/// @return Current system frequency in hertz.
///
COIACCESSAPI
uint64_t COIPerfGetCycleFrequency(void);
#ifdef __cplusplus
} /* extern "C" */
#endif
/*! @} */
#endif /* _COIPERF_COMMON_H */

View File

@ -0,0 +1,145 @@
/*
* Copyright 2010-2013 Intel Corporation.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, version 2.1.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* Disclaimer: The codes contained in these modules may be specific
* to the Intel Software Development Platform codenamed Knights Ferry,
* and the Intel product codenamed Knights Corner, and are not backward
* compatible with other Intel products. Additionally, Intel will NOT
* support the codes or instruction set in future products.
*
* Intel offers no warranty of any kind regarding the code. This code is
* licensed on an "AS IS" basis and Intel is not obligated to provide
* any support, assistance, installation, training, or other services
* of any kind. Intel is also not obligated to provide any updates,
* enhancements or extensions. Intel specifically disclaims any warranty
* of merchantability, non-infringement, fitness for any particular
* purpose, and any other warranty.
*
* Further, Intel disclaims all liability of any kind, including but
* not limited to liability for infringement of any proprietary rights,
* relating to the use of the code, even if Intel is notified of the
* possibility of such liability. Except as expressly stated in an Intel
* license agreement provided with this code and agreed upon with Intel,
* no license, express or implied, by estoppel or otherwise, to any
* intellectual property rights is granted herein.
*/
#ifndef _COIRESULT_COMMON_H
#define _COIRESULT_COMMON_H
/** @ingroup COIResult
* @addtogroup COIResultCommon
@{
* @file common/COIResult_common.h
* Result codes and definitions. */
#include "../common/COITypes_common.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum COIRESULT
{
COI_SUCCESS = 0, ///< The function succeeded without error.
COI_ERROR, ///< Unspecified error.
COI_NOT_INITIALIZED, ///< The function was called before the
///< system was initialized.
COI_ALREADY_INITIALIZED, ///< The function was called after the
///< system was initialized.
COI_ALREADY_EXISTS, ///< Cannot complete the request due to
///< the existence of a similar object.
COI_DOES_NOT_EXIST, ///< The specified object was not found.
COI_INVALID_POINTER, ///< One of the provided addresses was not
///< valid.
COI_OUT_OF_RANGE, ///< One of the arguments contains a value
///< that is invalid.
COI_NOT_SUPPORTED, ///< This function is not currently
///< supported as used.
COI_TIME_OUT_REACHED, ///< The specified time out caused the
///< function to abort.
COI_MEMORY_OVERLAP, ///< The source and destination range
///< specified overlaps for the same
///< buffer.
COI_ARGUMENT_MISMATCH, ///< The specified arguments are not
///< compatible.
COI_SIZE_MISMATCH, ///< The specified size does not match the
///< expected size.
COI_OUT_OF_MEMORY, ///< The function was unable to allocate
///< the required memory.
COI_INVALID_HANDLE, ///< One of the provided handles was not
///< valid.
COI_RETRY, ///< This function currently can't
///< complete, but might be able to later.
COI_RESOURCE_EXHAUSTED, ///< The resource was not large enough.
COI_ALREADY_LOCKED, ///< The object was expected to be
///< unlocked, but was locked.
COI_NOT_LOCKED, ///< The object was expected to be locked,
///< but was unlocked.
COI_MISSING_DEPENDENCY, ///< One or more dependent components
///< could not be found.
COI_UNDEFINED_SYMBOL, ///< One or more symbols the component
///< required was not defined in any
///< library.
COI_PENDING, ///< Operation is not finished
COI_BINARY_AND_HARDWARE_MISMATCH, ///< A specified binary will not run on
///< the specified hardware.
COI_PROCESS_DIED,
COI_INVALID_FILE, ///< The file is invalid for its intended
///< usage in the function.
COI_EVENT_CANCELED, ///< Event wait on a user event that
///< was unregistered or is being
///< unregistered returns
///< COI_EVENT_CANCELED.
COI_VERSION_MISMATCH, ///< The version of Intel(R) Coprocessor
///< Offload Infrastructure on the host
///< is not compatible with the version
///< on the device.
COI_BAD_PORT, ///< The port that the host is set to
///< connect to is invalid.
COI_AUTHENTICATION_FAILURE, ///< The daemon was unable to authenticate
///< the user that requested an engine.
///< Only reported if daemon is set up for
///< authorization.
COI_NUM_RESULTS ///< Reserved, do not use.
}
COIRESULT;
//////////////////////////////////////////////////////////////////////////////
///
/// Returns the string version of the passed in COIRESULT. Thus if
/// COI_RETRY is passed in, this function returns the string "COI_RETRY". If
/// the error code passed ins is not valid then "COI_ERROR" will be returned.
///
/// @param in_ResultCode
/// [in] COIRESULT code to return the string version of.
///
/// @return String version of the passed in COIRESULT code.
///
COIACCESSAPI
const char*
COIResultGetName(
COIRESULT in_ResultCode);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* _COIRESULT_COMMON_H */
/*! @} */

View File

@ -0,0 +1,85 @@
/*
* Copyright 2010-2013 Intel Corporation.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, version 2.1.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* Disclaimer: The codes contained in these modules may be specific
* to the Intel Software Development Platform codenamed Knights Ferry,
* and the Intel product codenamed Knights Corner, and are not backward
* compatible with other Intel products. Additionally, Intel will NOT
* support the codes or instruction set in future products.
*
* Intel offers no warranty of any kind regarding the code. This code is
* licensed on an "AS IS" basis and Intel is not obligated to provide
* any support, assistance, installation, training, or other services
* of any kind. Intel is also not obligated to provide any updates,
* enhancements or extensions. Intel specifically disclaims any warranty
* of merchantability, non-infringement, fitness for any particular
* purpose, and any other warranty.
*
* Further, Intel disclaims all liability of any kind, including but
* not limited to liability for infringement of any proprietary rights,
* relating to the use of the code, even if Intel is notified of the
* possibility of such liability. Except as expressly stated in an Intel
* license agreement provided with this code and agreed upon with Intel,
* no license, express or implied, by estoppel or otherwise, to any
* intellectual property rights is granted herein.
*/
#ifndef _COITYPES_COMMON_H
#define _COITYPES_COMMON_H
/** @ingroup COITypes
* @addtogroup COITypesSource
@{
* @file common/COITypes_common.h
*/
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#include <stdint.h>
#include <wchar.h>
#define COIACCESSAPI /* nothing */
#define COIACCESSAPI2 /* nothing */
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
#ifdef __cplusplus
extern "C" {
#endif
struct coievent { uint64_t opaque[2]; };
typedef struct coiprocess * COIPROCESS;
typedef struct coipipeline * COIPIPELINE;
typedef struct coifunction * COIFUNCTION;
typedef struct coiengine * COIENGINE;
typedef struct coievent COIEVENT;
typedef struct coibuffer * COIBUFFER;
typedef struct coilibrary * COILIBRARY;
typedef struct coimapinst * COIMAPINSTANCE;
typedef uint64_t COI_CPU_MASK[16];
/**
* On Windows, coi_wchar_t is a uint32_t. On Windows, wchar_t is 16 bits wide, and on Linux it is 32 bits wide, so uint32_t is used for portability.
*/
typedef wchar_t coi_wchar_t;
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* _COITYPES_COMMON_H */

View File

@ -0,0 +1,130 @@
/*
* Copyright 2010-2013 Intel Corporation.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, version 2.1.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* Disclaimer: The codes contained in these modules may be specific
* to the Intel Software Development Platform codenamed Knights Ferry,
* and the Intel product codenamed Knights Corner, and are not backward
* compatible with other Intel products. Additionally, Intel will NOT
* support the codes or instruction set in future products.
*
* Intel offers no warranty of any kind regarding the code. This code is
* licensed on an "AS IS" basis and Intel is not obligated to provide
* any support, assistance, installation, training, or other services
* of any kind. Intel is also not obligated to provide any updates,
* enhancements or extensions. Intel specifically disclaims any warranty
* of merchantability, non-infringement, fitness for any particular
* purpose, and any other warranty.
*
* Further, Intel disclaims all liability of any kind, including but
* not limited to liability for infringement of any proprietary rights,
* relating to the use of the code, even if Intel is notified of the
* possibility of such liability. Except as expressly stated in an Intel
* license agreement provided with this code and agreed upon with Intel,
* no license, express or implied, by estoppel or otherwise, to any
* intellectual property rights is granted herein.
*/
#ifndef _COIBUFFER_SINK_H
#define _COIBUFFER_SINK_H
/** @ingroup COIBuffer
* @addtogroup COIBufferSink
@{
* @file sink\COIBuffer_sink.h
*/
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#include "../common/COITypes_common.h"
#include "../common/COIResult_common.h"
#endif // DOXYGEN_SHOULD_SKIP_THIS
#ifdef __cplusplus
extern "C" {
#endif
//////////////////////////////////////////////////////////////////////////////
///
/// Adds a reference to the memory of a buffer. The memory of the buffer
/// will remain on the device until both a corresponding COIBufferReleaseRef()
/// call is made and the run function that delivered the buffer returns.
///
/// Intel® Coprocessor Offload Infrastructure (Intel® COI) streaming buffers should not be AddRef'd. Doing so may result in
/// unpredictable results or may cause the sink process to crash.
///
/// @warning 1.It is possible for enqueued run functions to be unable to
/// execute due to all card memory being occupied by addref'ed
/// buffers. As such, it is important that whenever a buffer is
/// addref'd that there be no dependencies on future run functions
/// for progress to be made towards releasing the buffer.
/// 2.It is important that AddRef is called within the scope of
/// run function that carries the buffer to be addref'ed.
///
/// @param in_pBuffer
/// [in] Pointer to the start of a buffer being addref'ed, that was
/// passed in at the start of the run function.
///
/// @return COI_SUCCESS if the buffer ref count was successfully incremented.
///
/// @return COI_INVALID_POINTER if the buffer pointer is NULL.
///
/// @return COI_INVALID_HANDLE if the buffer pointer is invalid.
///
COIRESULT
COIBufferAddRef(
void* in_pBuffer);
//////////////////////////////////////////////////////////////////////////////
///
/// Removes a reference to the memory of a buffer. The memory of the buffer
/// will be eligible for being freed on the device when the following
/// conditions are met: the run function that delivered the buffer
/// returns, and the number of calls to COIBufferReleaseRef() matches the
/// number of calls to COIBufferAddRef().
///
/// @warning When a buffer is addref'ed it is assumed that it is in use and all
/// other operations on that buffer waits for ReleaseRef() to happen.
/// So you cannot pass the addref'ed buffer's handle to RunFunction
/// that calls ReleaseRef(). This is a circular dependency and will
/// cause a deadlock. Buffer's pointer (buffer's sink side
/// address/pointer which is different than source side BUFFER handle)
/// needs to be stored somewhere to retrieve it later to use in
/// ReleaseRef.
///
/// @param in_pBuffer
/// [in] Pointer to the start of a buffer previously addref'ed, that
/// was passed in at the start of the run function.
///
/// @return COI_SUCCESS if the buffer refcount was successfully decremented.
///
/// @return COI_INVALID_POINTER if the buffer pointer was invalid.
///
/// @return COI_INVALID_HANDLE if the buffer did not have COIBufferAddRef()
/// previously called on it.
///
COIRESULT
COIBufferReleaseRef(
void* in_pBuffer);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* _COIBUFFER_SINK_H */
/*! @} */

View File

@ -0,0 +1,137 @@
/*
* Copyright 2010-2013 Intel Corporation.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, version 2.1.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* Disclaimer: The codes contained in these modules may be specific
* to the Intel Software Development Platform codenamed Knights Ferry,
* and the Intel product codenamed Knights Corner, and are not backward
* compatible with other Intel products. Additionally, Intel will NOT
* support the codes or instruction set in future products.
*
* Intel offers no warranty of any kind regarding the code. This code is
* licensed on an "AS IS" basis and Intel is not obligated to provide
* any support, assistance, installation, training, or other services
* of any kind. Intel is also not obligated to provide any updates,
* enhancements or extensions. Intel specifically disclaims any warranty
* of merchantability, non-infringement, fitness for any particular
* purpose, and any other warranty.
*
* Further, Intel disclaims all liability of any kind, including but
* not limited to liability for infringement of any proprietary rights,
* relating to the use of the code, even if Intel is notified of the
* possibility of such liability. Except as expressly stated in an Intel
* license agreement provided with this code and agreed upon with Intel,
* no license, express or implied, by estoppel or otherwise, to any
* intellectual property rights is granted herein.
*/
#ifndef _COIPIPELINE_SINK_H
#define _COIPIPELINE_SINK_H
/** @ingroup COIPipeline
* @addtogroup COIPipelineSink
@{
* @file sink/COIPipeline_sink.h
*/
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#include "../common/COITypes_common.h"
#include "../common/COIResult_common.h"
#ifdef __FreeBSD__
#define COINATIVELIBEXPORT_VISIBILITY "extern"
#else
#define COINATIVELIBEXPORT_VISIBILITY "default"
#endif
#ifdef __cplusplus
#define COINATIVELIBEXPORT \
extern "C" __attribute__ ((visibility(COINATIVELIBEXPORT_VISIBILITY)))
#else
#define COINATIVELIBEXPORT \
__attribute__ ((visibility(COINATIVELIBEXPORT_VISIBILITY)))
#endif
#ifdef __cplusplus
extern "C" {
#endif
#endif // DOXYGEN_SHOULD_SKIP_THIS
//////////////////////////////////////////////////////////////////////////////
///
/// This is the prototype that run functions should follow.
///
/// @param in_BufferCount
/// The number of buffers passed to the run function.
///
/// @param in_ppBufferPointers
/// An array that is in_BufferCount in length that contains the
/// sink side virtual addresses for each buffer passed in to
/// the run function.
///
/// @param in_pBufferLengths
/// An array that is in_BufferCount in length of uint32_t integers
/// describing the length of each passed in buffer in bytes.
///
/// @param in_pMiscData
/// Pointer to the MiscData passed in when the run function
/// was enqueued on the source.
///
/// @param in_MiscDataLen
/// Length in bytes of the MiscData passed in when the run function
/// was enqueued on the source.
///
/// @param in_pReturnValue
/// Pointer to the location where the return value from this run
/// function will be stored.
///
/// @param in_ReturnValueLength
/// Length in bytes of the user-allocated ReturnValue pointer.
///
/// @return A uint64_t that can be retrieved in the out_UserData parameter
/// from the COIPipelineWaitForEvent function.
///
typedef void
(*RunFunctionPtr_t)(
uint32_t in_BufferCount,
void** in_ppBufferPointers,
uint64_t* in_pBufferLengths,
void* in_pMiscData,
uint16_t in_MiscDataLength,
void* in_pReturnValue,
uint16_t in_ReturnValueLength);
///////////////////////////////////////////////////////////////////////////////
///
/// Start processing pipelines on the Sink. This should be done after any
/// required initialization in the Sink's application has finished. No
/// run functions will actually be executed (although they may be queued)
/// until this function is called.
///
///
/// @return COI_SUCCESS if the pipelines were successfully started.
///
COIRESULT
COIPipelineStartExecutingRunFunctions();
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* _COIPIPELINE_SINK_H */
/*! @} */

View File

@ -0,0 +1,103 @@
/*
* Copyright 2010-2013 Intel Corporation.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, version 2.1.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* Disclaimer: The codes contained in these modules may be specific
* to the Intel Software Development Platform codenamed Knights Ferry,
* and the Intel product codenamed Knights Corner, and are not backward
* compatible with other Intel products. Additionally, Intel will NOT
* support the codes or instruction set in future products.
*
* Intel offers no warranty of any kind regarding the code. This code is
* licensed on an "AS IS" basis and Intel is not obligated to provide
* any support, assistance, installation, training, or other services
* of any kind. Intel is also not obligated to provide any updates,
* enhancements or extensions. Intel specifically disclaims any warranty
* of merchantability, non-infringement, fitness for any particular
* purpose, and any other warranty.
*
* Further, Intel disclaims all liability of any kind, including but
* not limited to liability for infringement of any proprietary rights,
* relating to the use of the code, even if Intel is notified of the
* possibility of such liability. Except as expressly stated in an Intel
* license agreement provided with this code and agreed upon with Intel,
* no license, express or implied, by estoppel or otherwise, to any
* intellectual property rights is granted herein.
*/
#ifndef _COIPROCESS_SINK_H
#define _COIPROCESS_SINK_H
/** @ingroup COIProcess
* @addtogroup COIProcessSink
@{
* @file sink/COIProcess_sink.h
*/
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#include "../common/COITypes_common.h"
#include "../common/COIResult_common.h"
#ifdef __cplusplus
extern "C" {
#endif
#endif // DOXYGEN_SHOULD_SKIP_THIS
//////////////////////////////////////////////////////////////////////////////
///
/// This call will block while waiting for the source to send a process destroy
/// message. This provides the sink side application with an event to keep the
/// main() function from exiting until it is directed to by the source. When
/// the shutdown message is received this function will stop any future run
/// functions from executing but will wait for any current run functions to
/// complete. All Intel® Coprocessor Offload Infrastructure (Intel® COI) resources will be cleaned up and no additional Intel® Coprocessor Offload Infrastructure (Intel® COI) APIs
/// should be called after this function returns. This function does not
/// invoke exit() so the application can perform any of its own cleanup once
/// this call returns.
///
/// @return COI_SUCCESS once the process receives the shutdown message.
///
COIRESULT
COIProcessWaitForShutdown();
//////////////////////////////////////////////////////////////////////////////
///
/// This call will block until all stdout and stderr output has been proxied
/// to and written by the source. This call guarantees that any output in a
/// run function is transmitted to the source before the run function signals
/// its completion event back to the source.
///
/// Note that having an additional thread printing forever while another
/// calls COIProxyFlush may lead to a hang because the process will be forced
/// to wait until all that output can be flushed to the source before returning
/// from this call.
///
/// @return COI_SUCCESS once the proxy output has been flushed to and written
/// written by the host. Note that Intel® Coprocessor Offload Infrastructure (Intel® COI) on the source writes to stdout
/// and stderr, but does not flush this output.
/// @return COI_SUCCESS if the process was created without enabling
/// proxy IO this function.
///
COIRESULT
COIProcessProxyFlush();
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* _COIPROCESS_SINK_H */
/*! @} */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,247 @@
/*
* Copyright 2010-2013 Intel Corporation.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, version 2.1.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* Disclaimer: The codes contained in these modules may be specific
* to the Intel Software Development Platform codenamed Knights Ferry,
* and the Intel product codenamed Knights Corner, and are not backward
* compatible with other Intel products. Additionally, Intel will NOT
* support the codes or instruction set in future products.
*
* Intel offers no warranty of any kind regarding the code. This code is
* licensed on an "AS IS" basis and Intel is not obligated to provide
* any support, assistance, installation, training, or other services
* of any kind. Intel is also not obligated to provide any updates,
* enhancements or extensions. Intel specifically disclaims any warranty
* of merchantability, non-infringement, fitness for any particular
* purpose, and any other warranty.
*
* Further, Intel disclaims all liability of any kind, including but
* not limited to liability for infringement of any proprietary rights,
* relating to the use of the code, even if Intel is notified of the
* possibility of such liability. Except as expressly stated in an Intel
* license agreement provided with this code and agreed upon with Intel,
* no license, express or implied, by estoppel or otherwise, to any
* intellectual property rights is granted herein.
*/
#ifndef _COIENGINE_SOURCE_H
#define _COIENGINE_SOURCE_H
/** @ingroup COIEngine
* @addtogroup COIEngineSource
@{
* @file source\COIEngine_source.h
*/
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#include <wchar.h>
#include "../common/COITypes_common.h"
#include "../common/COIResult_common.h"
#include "../common/COIEngine_common.h"
#endif // DOXYGEN_SHOULD_SKIP_THIS
#ifdef __cplusplus
extern "C" {
#endif
#define COI_MAX_DRIVER_VERSION_STR_LEN 255
#define COI_MAX_HW_THREADS 1024
///////////////////////////////////////////////////////////////////////////////
/// This enum defines miscellaneous information returned from the
/// COIGetEngineInfo() function.
///
typedef enum
{
COI_ENG_ECC_DISABLED = 0, //ECC is not enabled on this engine
COI_ENG_ECC_ENABLED = 0x00000001, //ECC is enabled on this engine
COI_ENG_ECC_UNKNOWN = 0x00000002 //ECC is mode is unknown
} coi_eng_misc;
///////////////////////////////////////////////////////////////////////////////
/// This structure returns information about an Intel(r) Xeon Phi(tm)
/// coprocessor.
/// A pointer to this structure is passed into the COIGetEngineInfo() function,
/// which fills in the data before returning to the caller.
///
typedef struct COI_ENGINE_INFO
{
/// The version string identifying the driver.
coi_wchar_t DriverVersion[COI_MAX_DRIVER_VERSION_STR_LEN];
/// The ISA supported by the engine.
COI_ISA_TYPE ISA;
/// The number of cores on the engine.
uint32_t NumCores;
/// Miscellaneous fields
coi_eng_misc MiscFlags;
/// The number of hardware threads on the engine.
uint32_t NumThreads;
/// The maximum frequency (in MHz) of the cores on the engine.
uint32_t CoreMaxFrequency;
/// The load percentage for each of the hardware threads on the engine.
uint32_t Load[COI_MAX_HW_THREADS];
/// The amount of physical memory managed by the OS.
uint64_t PhysicalMemory;
/// The amount of free physical memory in the OS.
uint64_t PhysicalMemoryFree;
/// The amount of swap memory managed by the OS.
uint64_t SwapMemory;
/// The amount of free swap memory in the OS.
uint64_t SwapMemoryFree;
/// The pci config vendor id
uint16_t VendorId;
/// The pci config device id
uint16_t DeviceId;
/// The pci config subsystem id
uint16_t SubSystemId;
/// The stepping of the board, A0, A1, C0, D0 etc.
uint16_t BoardStepping;
/// The SKU of the stepping, EB, ED, etc.
uint16_t BoardSKU;
} COI_ENGINE_INFO;
///////////////////////////////////////////////////////////////////////////////
///
/// Returns information related to a specified engine. Note that if Intel® Coprocessor Offload Infrastructure (Intel® COI) is
/// unable to query a value it will be returned as zero but the call will
/// still succeed.
///
///
/// @param in_EngineHandle
/// [in] The COIENGINE structure as provided from COIEngineGetHandle()
/// which to query for device level information.
///
/// @param in_EngineInfoSize
/// [in] The size of the structure that out_pEngineInfo points to.
/// Used for version safety of the function call.
///
/// @param out_pEngineInfo
/// [out] The address of a user allocated COI_ENGINE_INFO structure.
/// Upon success, the contents of the structure will be updated
/// to contain information related to the specified engine.
///
///
/// @return COI_SUCCESS if the function completed without error.
///
/// @return COI_INVALID_HANDLE if the in_EngineHandle handle is not valid.
///
/// @return COI_SIZE_MISMATCH if in_EngineInfoSize does not match any current
/// or previous COI_ENGINE_INFO structure sizes.
///
/// @return COI_INVALID_POINTER if the out_pEngineInfo pointer is NULL.
///
COIACCESSAPI
COIRESULT
COIEngineGetInfo(
COIENGINE in_EngineHandle,
uint32_t in_EngineInfoSize,
COI_ENGINE_INFO* out_pEngineInfo);
///////////////////////////////////////////////////////////////////////////////
///
/// Returns the number of engines in the system that match the provided ISA.
///
/// Note that while it is possible to enumerate different types of Intel(r)
/// Xeon Phi(tm) coprocessors on a single host this is not currently
/// supported. Intel® Coprocessor Offload Infrastructure (Intel® COI) makes an assumption that all Intel(r) Xeon Phi(tm)
/// coprocessors found in the system are the same architecture as the first
/// coprocessor device.
///
/// Also, note that this function returns the number of engines that Intel® Coprocessor Offload Infrastructure (Intel® COI)
/// is able to detect. Not all of them may be online.
///
/// @param in_ISA
/// [in] Specifies the ISA type of the engine requested.
///
/// @param out_pNumEngines
/// [out] The number of engines available. This can be used to index
/// into the engines using COIEngineGetHandle().
///
/// @return COI_SUCCESS if the function completed without error.
///
/// @return COI_DOES_NOT_EXIST if the in_ISA parameter is not valid.
///
/// @return COI_INVALID_POINTER if the out_pNumEngines parameter is NULL.
///
COIACCESSAPI
COIRESULT
COIEngineGetCount(
COI_ISA_TYPE in_ISA,
uint32_t* out_pNumEngines);
///////////////////////////////////////////////////////////////////////////////
///
/// Returns the handle of a user specified engine.
///
/// @param in_ISA
/// [in] Specifies the ISA type of the engine requested.
///
/// @param in_EngineIndex
/// [in] A unsigned integer which specifies the zero-based position of
/// the engine in a collection of engines. The makeup of this
/// collection is defined by the in_ISA parameter.
///
/// @param out_pEngineHandle
/// [out] The address of an COIENGINE handle.
///
/// @return COI_SUCCESS if the function completed without error.
///
/// @return COI_DOES_NOT_EXIST if the in_ISA parameter is not valid.
///
/// @return COI_OUT_OF_RANGE if in_EngineIndex is greater than or equal to
/// the number of engines that match the in_ISA parameter.
///
/// @return COI_INVALID_POINTER if the out_pEngineHandle parameter is NULL.
///
/// @return COI_VERSION_MISMATCH if the version of Intel® Coprocessor Offload Infrastructure (Intel® COI) on the host is not
/// compatible with the version on the device.
///
/// @return COI_NOT_INITIALIZED if the engine requested exists but is offline.
///
COIACCESSAPI
COIRESULT
COIEngineGetHandle(
COI_ISA_TYPE in_ISA,
uint32_t in_EngineIndex,
COIENGINE* out_pEngineHandle);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* _COIENGINE_SOURCE_H */
/*! @} */

View File

@ -0,0 +1,192 @@
/*
* Copyright 2010-2013 Intel Corporation.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, version 2.1.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* Disclaimer: The codes contained in these modules may be specific
* to the Intel Software Development Platform codenamed Knights Ferry,
* and the Intel product codenamed Knights Corner, and are not backward
* compatible with other Intel products. Additionally, Intel will NOT
* support the codes or instruction set in future products.
*
* Intel offers no warranty of any kind regarding the code. This code is
* licensed on an "AS IS" basis and Intel is not obligated to provide
* any support, assistance, installation, training, or other services
* of any kind. Intel is also not obligated to provide any updates,
* enhancements or extensions. Intel specifically disclaims any warranty
* of merchantability, non-infringement, fitness for any particular
* purpose, and any other warranty.
*
* Further, Intel disclaims all liability of any kind, including but
* not limited to liability for infringement of any proprietary rights,
* relating to the use of the code, even if Intel is notified of the
* possibility of such liability. Except as expressly stated in an Intel
* license agreement provided with this code and agreed upon with Intel,
* no license, express or implied, by estoppel or otherwise, to any
* intellectual property rights is granted herein.
*/
#ifndef _COIEVENT_SOURCE_H
#define _COIEVENT_SOURCE_H
/** @ingroup COIEvent
* @addtogroup COIEventSource
@{
* @file source/COIEvent_source.h
*/
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#include "../common/COITypes_common.h"
#include "../common/COIResult_common.h"
#ifdef __cplusplus
extern "C" {
#endif
#endif // DOXYGEN_SHOULD_SKIP_THIS
///////////////////////////////////////////////////////////////////////////////
///
/// Special case event values which can be passed in to APIs to specify
/// how the API should behave. In COIBuffer APIs passing in NULL for the
/// completion event is the equivalent of passing COI_EVENT_SYNC. For
/// COIPipelineRunFunction passing in NULL is the equivalent of
/// COI_EVENT_ASYNC.
/// Note that passing COI_EVENT_ASYNC can be used when the caller wishes the
/// operation to be performed asynchronously but does not care when the
/// operation completes. This can be useful for opertions that by definition
/// must complete in order (DMAs, run functions on a single pipeline). If
/// the caller does care when the operation completes then they should pass
/// in a valid completion event which they can later wait on.
///
#define COI_EVENT_ASYNC ((COIEVENT*)1)
#define COI_EVENT_SYNC ((COIEVENT*)2)
///////////////////////////////////////////////////////////////////////////////
///
/// Wait for an arbitrary number of COIEVENTs to be signaled as completed,
/// eg when the run function or asynchronous map call associated with an event
/// has finished execution.
/// If the user sets in_WaitForAll = True and not all of the events are
/// signaled when the timeout period is reached then COI_TIME_OUT_REACHED will
/// be returned.
/// If the user sets in_WaitForAll = False then if at least one event is
/// signaled when the timeout is reached then COI_SUCCESS is returned.
///
/// @param in_NumEvents
/// [in] The number of events to wait for.
///
/// @param in_pEvents
/// [in] The array of COIEVENT handles to wait for.
///
/// @param in_Timeout
/// [in] The time in milliseconds to wait for the event. 0 polls
/// and returns immediately, -1 blocks indefinitely.
///
/// @param in_WaitForAll
/// [in] Boolean value specifying behavior. If true, wait for all
/// events to be signaled, or for timeout, whichever happens first.
/// If false, return when any event is signaled, or at timeout.
///
/// @param out_pNumSignaled
/// [out] The number of events that were signaled. If in_NumEvents
/// is 1 or in_WaitForAll = True, this parameter is optional.
///
/// @param out_pSignaledIndices
/// [out] Pointer to an array of indicies into the original event
/// array. Those denoted have been signaled. The user must provide an
/// array that is no smaller than the in_Events array. If in_NumEvents
/// is 1 or in_WaitForAll = True, this parameter is optional.
///
/// @return COI_SUCCESS once an event has been signaled completed.
///
/// @return COI_TIME_OUT_REACHED if the events are still in use when the
/// timeout is reached or timeout is zero (a poll).
///
/// @return COI_OUT_OF_RANGE if a negative value other than -1 is passed in to
/// the in_Timeout parameter.
///
/// @return COI_OUT_OF_RANGE if in_NumEvents is 0.
///
/// @return COI_INVALID_POINTER if in_pEvents is NULL.
///
/// @return COI_ARGUMENT_MISMATCH if in_NumEvents > 1 and if in_WaitForAll
/// is not true and out_pSignaled or out_pSignaledIndicies are NULL.
///
/// @return COI_ARGUMENT_MISMATCH if out_pNumSignaled is not NULL
/// and out_pSignaledIndices is NULL (or vice versa).
///
/// @return COI_EVENT_CANCELED if while waiting on a user event, it gets
/// unregistered this returns COI_EVENT_CANCELED
///
/// @return COI_PROCESS_DIED if the remote process died. See COIProcessDestroy
/// for more details.
///
COIACCESSAPI
COIRESULT
COIEventWait(
uint16_t in_NumEvents,
const COIEVENT* in_pEvents,
int32_t in_TimeoutMilliseconds,
uint8_t in_WaitForAll,
uint32_t* out_pNumSignaled,
uint32_t* out_pSignaledIndices);
///////////////////////////////////////////////////////////////////////////////
///
/// Register a User COIEVENT so that it can be fired. Registered event is
/// a one shot User event; in other words once signaled it cannot be used
/// again for signaling. You have to unregister and register again to enable
/// signaling. An event will be reset if it is re-registered without
/// unregistering, resulting in loss of all outstanding signals.
///
/// @param out_pEvent
/// [out] Pointer to COIEVENT handle being Registered
///
/// @return COI_SUCCESS an event is successfully registered
///
/// @return COI_INVALID_POINTER if out_pEvent is NULL
///
COIACCESSAPI
COIRESULT
COIEventRegisterUserEvent(
COIEVENT* out_pEvent);
///////////////////////////////////////////////////////////////////////////////
///
/// Unregister a User COIEVENT. Unregistering a unsignaled event is similar
/// to firing an event. Except Calling COIEventWait on an event that is
/// being unregistered returns COI_EVENT_CANCELED
///
/// @param in_Event
/// [in] Event Handle to be unregistered.
///
/// @return COI_INVALID_HANDLE if in_Event is not a UserEvent
///
/// @return COI_SUCCESS an event is successfully registered
///
COIACCESSAPI
COIRESULT
COIEventUnregisterUserEvent(
COIEVENT in_Event);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* _COIEVENT_SOURCE_H */
/*! @} */

View File

@ -0,0 +1,426 @@
/*
* Copyright 2010-2013 Intel Corporation.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, version 2.1.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* Disclaimer: The codes contained in these modules may be specific
* to the Intel Software Development Platform codenamed Knights Ferry,
* and the Intel product codenamed Knights Corner, and are not backward
* compatible with other Intel products. Additionally, Intel will NOT
* support the codes or instruction set in future products.
*
* Intel offers no warranty of any kind regarding the code. This code is
* licensed on an "AS IS" basis and Intel is not obligated to provide
* any support, assistance, installation, training, or other services
* of any kind. Intel is also not obligated to provide any updates,
* enhancements or extensions. Intel specifically disclaims any warranty
* of merchantability, non-infringement, fitness for any particular
* purpose, and any other warranty.
*
* Further, Intel disclaims all liability of any kind, including but
* not limited to liability for infringement of any proprietary rights,
* relating to the use of the code, even if Intel is notified of the
* possibility of such liability. Except as expressly stated in an Intel
* license agreement provided with this code and agreed upon with Intel,
* no license, express or implied, by estoppel or otherwise, to any
* intellectual property rights is granted herein.
*/
#ifndef _COIPIPELINE_SOURCE_H
#define _COIPIPELINE_SOURCE_H
/** @ingroup COIPipeline
* @addtogroup COIPipelineSource
@{
* @file source/COIPipeline_source.h
*/
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#include "../common/COITypes_common.h"
#include "../common/COIResult_common.h"
#ifdef __cplusplus
extern "C" {
#endif
#endif // DOXYGEN_SHOULD_SKIP_THIS
//////////////////////////////////////////////////////////////////////////////
/// These flags specify how a buffer will be used within a run function. They
/// allow Intel® Coprocessor Offload Infrastructure (Intel® COI) to make optimizations in how it moves data around the system.
/// These flags can affect the correctness of an application, so they must be
/// set properly. For example, if a buffer is used in a run function with the
/// COI_SINK_READ flag and then mapped on the source, Intel® Coprocessor Offload Infrastructure (Intel® COI) may use a previously
/// cached version of the buffer instead of retrieving data from the sink.
typedef enum COI_ACCESS_FLAGS
{
/// Specifies that the run function will only read the associated buffer.
COI_SINK_READ = 1,
/// Specifies that the run function will write to the associated buffer.
COI_SINK_WRITE,
/// Specifies that the run function will overwrite the entire associated
/// buffer and therefore the buffer will not be synchronized with the
/// source before execution.
COI_SINK_WRITE_ENTIRE
} COI_ACCESS_FLAGS;
#define COI_PIPELINE_MAX_PIPELINES 512
#define COI_PIPELINE_MAX_IN_BUFFERS 16384
#define COI_PIPELINE_MAX_IN_MISC_DATA_LEN 32768
///////////////////////////////////////////////////////////////////////////////
///
/// Create a pipeline assoiated with a remote process. This pipeline can
/// then be used to execute remote functions and to share data using
/// COIBuffers.
///
/// @param in_Process
/// [in] A handle to an already existing process that the pipeline
/// will be associated with.
///
/// @param in_Mask
/// [in] An optional mask of the set of hardware threads on which the
/// sink pipeline command processing thread could run.
///
/// @param in_StackSize
/// [in] An optional value that will be used when the pipeline
/// processing thread is created on the sink. If the user passes in
/// 0 the OS default stack size will be used. Otherwise the value
/// must be PTHREAD_STACK_MIN (16384) bytes or larger and must be
/// a multiple of a page (4096 bytes).
///
/// @param out_pPipeline
/// [out] Handle returned to uniquely identify the pipeline that was
/// created for use in later API calls.
///
///
/// @return COI_SUCCESS if the pipeline was successfully created.
///
/// @return COI_INVALID_HANDLE if the in_Process handle passed in was invalid.
///
/// @return COI_INVALID_POINTER if the out_pPipeline pointer was NULL.
///
/// @return COI_RESOURCE_EXHAUSTED if no more COIPipelines can be created. The
/// maximum number of pipelines allowed is COI_PIPELINE_MAX_PIPELINES.
/// It is recommended in most cases to not exceed the number of CPU's
/// that are reported on the offload device, performance will suffer.
///
///
/// @return COI_OUT_OF_RANGE if the in_StackSize > 0 &&
/// in_StackSize < PTHREAD_STACK_MIN or if in_StackSize is not a
/// multiple of a page (4096 bytes).
///
/// @return COI_OUT_OF_RANGE if the in_Mask is set to all zeroes. If no mask
/// is desired then the in_Mask should be passed as NULL, otherwise
/// at least one thread must be set.
///
/// @return COI_TIME_OUT_REACHED if establishing the communication channel with
/// the remote pipeline timed out.
///
/// @return COI_RETRY if the pipeline cannot be created due to the number of
/// source-to-sink connections in use. A subsequent call to
/// COIPipelineCreate may succeed if resources are freed up.
///
/// @return COI_PROCESS_DIED if in_Process died.
///
COIACCESSAPI
COIRESULT
COIPipelineCreate(
COIPROCESS in_Process,
COI_CPU_MASK in_Mask,
uint32_t in_StackSize,
COIPIPELINE* out_pPipeline);
///////////////////////////////////////////////////////////////////////////////
///
/// Destroys the inidicated pipeline, releasing its resources.
///
/// @param in_Pipeline
/// [in] Pipeline to destroy.
///
///
/// @return COI_SUCCESS if the pipeline was destroyed
///
COIACCESSAPI
COIRESULT
COIPipelineDestroy(
COIPIPELINE in_Pipeline);
//////////////////////////////////////////////////////////////////////////////
///
/// Enqueues a function in the remote process binary to be executed. The
/// function execution is asynchronous in regards to the Source and all
/// run functions enqueued on a pipeline are executed in-order. The run
/// function will only execute when all of the required buffers are present
/// in the Sink's memory.
///
/// Potential Hazards while using Runfunctions:
///
/// 1. Proper care has to be taken while setting the input dependencies for
/// RunFunctions. Setting it incorrectly can lead to cyclic dependencies
/// and can cause the respective pipeline (as a result Intel® Coprocessor Offload Infrastructure (Intel® COI) Runtime) to
/// stall.
/// 2. RunFunctions can also segfault if enough memory space is not available
/// on the sink for the buffers passed in. Pinned buffers and buffers that
/// are AddRef'd need to be accounted for available memory space. In other
/// words, this memory is not available for use until it is freed up.
/// 3. Unexpected segmentation faults or erroneous behaviour can occur if
/// handles or data passed in to Runfunction gets destroyed before the
/// RunFunction finishes.
/// For example, if a variable passed in as Misc data or the buffer gets
/// destroyed before the Intel® Coprocessor Offload Infrastructure (Intel® COI) runtime receives the completion notification
/// of the Runfunction, it can cause unexpected behaviour. So it is always
/// recommended to wait for RunFunction completion event before any related
/// destroy event occurs.
///
/// Intel® Coprocessor Offload Infrastructure (Intel® COI) Runtime expects users to handle such scenarios. COIPipelineRunFunction
/// returns COI_SUCCESS for above cases because it was queued up successfully.
/// Also if you try to destroy a pipeline with a stalled function then the
/// destroy call will hang. COIPipelineDestroy waits until all the functions
/// enqueued are finished executing.
///
/// @param in_Pipeline
/// [in] Handle to a previously created pipeline that this run
/// function should be enqueued to.
///
/// @param in_Function
/// [in] Previously returned handle from a call to
/// COIPipelineGetFunctionHandle() that represents a function in the
/// application running on the Sink process.
///
/// @param in_NumBuffers
/// [in] The number of buffers that are being passed to the run
/// function. This number must match the number of buffers in the
/// in_pBuffers and in_pBufferAccessFlags arrays. Must be less than
/// COI_PIPELINE_MAX_IN_BUFFERS.
///
/// @param in_pBuffers
/// [in] An array of COIBUFFER handles that the function is expected
/// to use during its execution. Each buffer when it arrives at the
/// Sink process will be at least 4k page aligned, thus, using a very
/// large number of small buffers is memory inefficient and should be
/// avoided.
///
/// @param in_pBufferAccessFlags
/// [in] An array of flag values which correspond to the buffers
/// passed in the in_pBuffers parameter. These flags are used to
/// track dependencies between different run functions being
/// executed from different pipelines.
///
/// @param in_NumDependencies
/// [in] The number of dependencies specified in the in_pDependencies
/// array. This may be 0 if the caller does not want the run function
/// to wait for any dependencies.
///
/// @param in_pDependencies
/// [in] An optional array of COIEVENT objects that this run
/// function will wait for before executing. This allows the user to
/// create dependencies between run functions in different pipelines.
/// The user may pass in NULL if they do not wish to wait for any
/// dependencies to complete.
///
/// @param in_pMiscData
/// [in] Pointer to user defined data, typically used to pass
/// parameters to Sink side functions. Should only be used for small
/// amounts data since the data will be placed directly in the
/// Driver's command buffer. COIBuffers should be used to pass large
/// amounts of data.
///
/// @param in_MiscDataLen
/// [in] Size of the in_pMiscData in bytes. Must be less than
/// COI_PIPELINE_MAX_IN_MISC_DATA_LEN, and should usually be much
/// smaller, see documentation for the parameter in_pMiscData.
///
/// @param out_pAsyncReturnValue
/// [out] Pointer to user-allocated memory where the return value from
/// the run function will be placed. This memory should not be read
/// until out_pCompletion has been signalled.
///
/// @param in_AsyncReturnValueLen
/// [in] Size of the out_pAsyncReturnValue in bytes.
///
/// @param out_pCompletion
/// [out] An optional pointer to a COIEVENT object
/// that will be signaled when this run function has completed
/// execution. The user may pass in NULL if they do not wish to signal
/// any COIEVENTs when this run function completes.
///
/// @return COI_SUCCESS if the function was successfully placed in a
/// pipeline for future execution. Note that the actual
/// execution of the function will occur in the future.
///
/// @return COI_OUT_OF_RANGE if in_NumBuffers is greater than
/// COI_PIPELINE_MAX_IN_BUFFERS or if in_MiscDataLen is greater than
/// COI_PIPELINE_MAX_IN_MISC_DATA_LEN.
///
/// @return COI_INVALID_HANDLE if the pipeline handle passed in was invalid.
///
/// @return COI_INVALID_HANDLE if the function handle passed in was invalid.
///
/// @return COI_INVALID_HANDLE if any of the buffers passed in are invalid.
///
/// @return COI_ARGUMENT_MISMATCH if in_NumDependencies is non-zero while
/// in_pDependencies was passed in as NULL.
///
/// @return COI_ARGUMENT_MISMATCH if in_pDependencies is non-NULL but
/// in_NumDependencies is zero.
///
/// @return COI_ARGUMENT_MISMATCH if in_MiscDataLen is non-zero while
/// in_pMiscData was passed in as NULL.
///
/// @return COI_ARGUMENT_MISMATCH if in_pMiscData is non-NULL but
/// in_MiscDataLen is zero.
///
/// @return COI_ARGUMENT_MISMATCH if in_NumBuffers is non-zero and in_pBuffers
/// or in_pBufferAccessFlags are NULL.
///
/// @return COI_ARGUMENT_MISMATCH if in_pBuffers is non-NULL but
/// in_NumBuffers is zero.
///
/// @return COI_ARGUMENT_MISMATCH if in_pBufferAccessFlags is non-NULL but
/// in_NumBuffers is zero.
///
/// @return COI_ARGUMENT_MISMATCH if in_ReturnValueLen is non-zero while
/// in_pReturnValue was passed in as NULL.
///
/// @return COI_ARGUMENT_MISMATCH if in_pReturnValue is non-NULL but
/// in_ReturnValueLen is zero.
///
/// @return COI_ARGUMENT_MISMATCH if a COI_BUFFER_STREAMING_TO_SOURCE buffer
/// is not passed with COI_SINK_WRITE_ENTIRE access flag.
///
/// @return COI_RESOURCE_EXHAUSTED if could not create a version for TO_SOURCE
/// streaming buffer. It can fail if enough memory is not available to
/// register. This call will succeed eventually when the registered
/// memory becomes available.
///
/// @return COI_RETRY if any input buffers, which are not pinned buffers,
/// are still mapped when passed to the run function.
///
/// @return COI_MISSING_DEPENDENCY if buffer was not created on the process
/// associated with the pipeline that was passed in.
///
/// @return COI_OUT_OF_RANGE if any of the access flags in
/// in_pBufferAccessFlags is not a valid COI_ACCESS_FLAGS.
///
COIACCESSAPI
COIRESULT
COIPipelineRunFunction(
COIPIPELINE in_Pipeline,
COIFUNCTION in_Function,
uint32_t in_NumBuffers,
const COIBUFFER* in_pBuffers,
const COI_ACCESS_FLAGS* in_pBufferAccessFlags,
uint32_t in_NumDependencies,
const COIEVENT* in_pDependencies,
const void* in_pMiscData,
uint16_t in_MiscDataLen,
void* out_pAsyncReturnValue,
uint16_t in_AsyncReturnValueLen,
COIEVENT* out_pCompletion);
//////////////////////////////////////////////////////////////////////////////
///
/// Retrieve the engine that the pipeline is associated with.
///
/// @param in_Pipeline
/// [in] Pipeline to query.
///
/// @param out_pEngine
/// [out] The handle of the Engine.
///
/// @return COI_SUCCESS if the engine was retrieved.
///
/// @return COI_INVALID_HANDLE if the pipeline handle passed in was invalid.
///
/// @return COI_INVALID_POINTER if the out_pEngine parameter is NULL.
///
/// @return COI_PROCESS_DIED if the process associated with this engine died.
///
COIACCESSAPI
COIRESULT
COIPipelineGetEngine(
COIPIPELINE in_Pipeline,
COIENGINE* out_pEngine);
//////////////////////////////////////////////////////////////////////////////
///
/// Add a particular core:thread pair to a COI_CPU_MASK.
///
/// @param in_Process
/// [in] A handle to an already existing process that the pipeline
/// will be associated with.
///
/// @param in_CoreID
/// [in] Core to affinitize to; must be less than the number of cores
/// on the device.
///
/// @param in_ThreadID
/// [in] Thread on the core to affinitize to (0 - 3).
///
/// @param out_pMask
/// [out] Pointer to the mask to set.
///
/// @warning Unless it is explicitly done, the contents of the mask may not
/// be zero when creating or declaring a COI_CPU_MASK variable.
///
/// @return COI_SUCCESS if the mask was set.
///
/// @return COI_OUT_OF_RANGE if the in_CoreID or in_ThreadID is out of range.
///
/// @return COI_INVALID_POINTER if out_pMask is invalid.
///
/// @return COI_INVALID_HANDLE if in_Process is invalid.
///
COIACCESSAPI
COIRESULT
COIPipelineSetCPUMask(
COIPROCESS in_Process,
uint32_t in_CoreID,
uint8_t in_ThreadID,
COI_CPU_MASK* out_pMask);
//////////////////////////////////////////////////////////////////////////////
///
/// Clears a given mask. Note that the memory contents of COI_CPU_MASK are not
/// guaranteed to be zero when declaring a COI_CPU_MASK variable. Thus, prior
/// to setting a specific affinity to in_Mask it is important to call this
/// function first.
///
/// @param in_Mask
/// [in] Pointer to the mask to clear.
///
/// @return COI_SUCCESS if the mask was cleared.
///
/// @return COI_INVALID_POINTER if in_Mask is invalid.
///
COIACCESSAPI
COIRESULT
COIPipelineClearCPUMask(
COI_CPU_MASK* in_Mask);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* _COIPIPELINE_SOURCE_H */
/*! @} */

View File

@ -0,0 +1,971 @@
/*
* Copyright 2010-2013 Intel Corporation.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, version 2.1.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* Disclaimer: The codes contained in these modules may be specific
* to the Intel Software Development Platform codenamed Knights Ferry,
* and the Intel product codenamed Knights Corner, and are not backward
* compatible with other Intel products. Additionally, Intel will NOT
* support the codes or instruction set in future products.
*
* Intel offers no warranty of any kind regarding the code. This code is
* licensed on an "AS IS" basis and Intel is not obligated to provide
* any support, assistance, installation, training, or other services
* of any kind. Intel is also not obligated to provide any updates,
* enhancements or extensions. Intel specifically disclaims any warranty
* of merchantability, non-infringement, fitness for any particular
* purpose, and any other warranty.
*
* Further, Intel disclaims all liability of any kind, including but
* not limited to liability for infringement of any proprietary rights,
* relating to the use of the code, even if Intel is notified of the
* possibility of such liability. Except as expressly stated in an Intel
* license agreement provided with this code and agreed upon with Intel,
* no license, express or implied, by estoppel or otherwise, to any
* intellectual property rights is granted herein.
*/
#ifndef _COIPROCESS_SOURCE_H
#define _COIPROCESS_SOURCE_H
/** @ingroup COIProcess
* @addtogroup COIProcessSource
@{
* @file source/COIProcess_source.h
*/
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#include "../common/COITypes_common.h"
#include "../common/COIResult_common.h"
#ifdef __cplusplus
extern "C" {
#endif
#endif // DOXYGEN_SHOULD_SKIP_THIS
///////////////////////////////////////////////////////////////////////////////
/// This is a special COIPROCESS handle that can be used to indicate that
/// the source process should be used for an operation.
///
#define COI_PROCESS_SOURCE ((COIPROCESS)-1)
#define COI_MAX_FILE_NAME_LENGTH 256
///////////////////////////////////////////////////////////////////////////////
///
/// Create a remote process on the Sink and start executing its main()
/// function.
///
/// For more details about creating a process see COIProcessCreateFromMemory.
///
/// @param in_Engine
/// [in] A handle retrieved via a call to COIEngineGetHandle() that
/// indicates which device to create the process on. This is
/// necessary because there can be more than one device
/// within the system.
///
/// @param in_pBinaryName
/// [in] Pointer to a null-terminated string that contains the
/// path to the program binary to be instantiated as a process on
/// the sink device. The file name will be accessed via
/// fopen and fread, as such, the passed in binary name must
/// be locatable via these commands. Also, the file name (without
/// directory information) will be used automatically by the system
/// to create the argv[0] of the new process.
///
/// @param in_Argc
/// [in] The number of arguments being passed in to the process in the
/// in_ppArgv parameter.
///
/// @param in_ppArgv
/// [in] An array of strings that represent the arguments being passed
/// in. The system will auto-generate argv[0] using in_pBinaryName and
/// thus that parameter cannot be passed in using in_ppArgv. Instead,
/// in_ppArgv contains the rest of the parameters being passed in.
///
/// @param in_DupEnv
/// [in] A boolean that indicates whether the process that is being
/// created should inherit the environment of the caller.
///
/// @param in_ppAdditionalEnv
/// [in] An array of strings that represent additional environment
/// variables. This parameter must terminate the array with a NULL
/// string. For convenience it is also allowed to be NULL if there are
/// no additional environment variables that need adding. Note that
/// any environment variables specified here will be in addition to
/// but override those that were inherited via in_DupEnv.
///
/// @param in_ProxyActive
/// [in] A boolean that specifies whether the process that is to be
/// created wants I/O proxy support. If this flag is enabled, then
/// stdout and stderr are forwarded back to the calling process's
/// output and error streams.
///
/// @param in_Reserved
/// Reserved for future use, best set at NULL.
///
/// @param in_InitialBufferSpace
/// [in] The initial memory (in bytes) that will be pre-allocated at
/// process creation for use by buffers associated with this remote
/// process. In addition to allocating, Intel® Coprocessor Offload
/// Infrastructure (Intel® COI) will also fault in the
/// memory during process creation. If the total size of the buffers
/// in use by this process exceed this initial size, memory on the
/// sink may continue to be allocated on demand, as needed, subject
/// to the system constraints on the sink.
///
///@param in_LibrarySearchPath
/// [in] a path to locate dynamic libraries dependencies for the sink
/// application. If not NULL, this path will override the environment
/// variable SINK_LD_LIBRARY_PATH. If NULL it will use
/// SINK_LD_LIBRARY_PATH to locate dependencies.
///
/// @param out_pProcess
/// [out] Handle returned to uniquely identify the process that was
/// created for use in later API calls.
///
/// @return COI_SUCCESS if the remote process was successfully created.
///
/// @return COI_INVALID_POINTER if in_pBinaryName was NULL.
///
/// @return COI_INVALID_FILE if in_pBinaryName is not a "regular file" as
/// determined by stat or if its size is 0.
///
/// @return COI_DOES_NOT_EXIST if in_pBinaryName cannot be found.
///
/// @return See COIProcessCreateFromMemory for additional errors.
///
COIACCESSAPI
COIRESULT
COIProcessCreateFromFile(
COIENGINE in_Engine,
const char* in_pBinaryName,
int in_Argc,
const char** in_ppArgv,
uint8_t in_DupEnv,
const char** in_ppAdditionalEnv,
uint8_t in_ProxyActive,
const char* in_Reserved,
uint64_t in_InitialBufferSpace,
const char* in_LibrarySearchPath,
COIPROCESS* out_pProcess);
///////////////////////////////////////////////////////////////////////////////
///
/// Create a remote process on the Sink and start executing its main()
/// function. This will also automatically load any dependent shared objects
/// on to the device. Once the process is created, remote calls can be
/// initiated by using the RunFunction mechanism found in the COIPipeline APIs.
///
/// If instead of creating a process you only wish to check for dynamic
/// library dependencies set the environment variable
/// SINK_LD_TRACE_LOADED_OBJECTS to be non empty before making this call.
///
/// If there are dynamic link libraries on the source file system that need to
/// be preloaded when the process is created on the device, callers of this
/// API can set the environment variable SINK_LD_PRELOAD to a colon separated
/// list of libraries that need to be copied to the sink and preloaded as part
/// of process creation.
///
/// For more information on how dependencies are loaded, see
/// COIProcessLoadLibraryFromMemory.
///
/// @param in_Engine
/// [in] A handle retrieved via a call to COIEngineGetHandle() that
/// indicates which device to create the process on. This is
/// necessary because there can be more than one device
/// within the system.
///
/// @param in_pBinaryName
/// [in] Pointer to a null-terminated string that contains the name to
/// give the process that will be created. Note that the final name
/// will strip out any directory information from in_pBinaryName and
/// use the file information to generate an argv[0] for the new
/// process.
///
/// @param in_pBinaryBuffer
/// [in] Pointer to a buffer whose contents represent the sink-side
/// process that we want to create.
///
/// @param in_BinaryBufferLength
/// [in] Number of bytes in in_pBinaryBuffer.
///
/// @param in_Argc
/// [in] The number of arguments being passed in to the process in the
/// in_ppArgv parameter.
///
/// @param in_ppArgv
/// [in] An array of strings that represent the arguments being passed
/// in. The system will auto-generate argv[0] using in_pBinaryName and
/// thus that parameter cannot be passed in using in_ppArgv. Instead,
/// in_ppArgv contains the rest of the parameters being passed in.
///
/// @param in_DupEnv
/// [in] A boolean that indicates whether the process that is being
/// created should inherit the environment of the caller.
///
/// @param in_ppAdditionalEnv
/// [in] An array of strings that represent additional environment
/// variables. This parameter must terminate the array with a NULL
/// string. For convenience it is also allowed to be NULL if there are
/// no additional environment variables that need adding. Note that
/// any environment variables specified here will be in addition to
/// but override those that were inherited via in_DupEnv.
///
/// @param in_ProxyActive
/// [in] A boolean that specifies whether the process that is to be
/// created wants I/O proxy support.
///
/// @param in_Reserved
/// Reserved for future use, best set to NULL.
///
/// @param in_InitialBufferSpace
/// [in] The initial memory (in bytes) that will be pre-allocated at
/// process creation for use by buffers associated with this remote
/// process. In addition to allocating, Intel® Coprocessor
/// Offload Infrastructure (Intel® COI) will also fault in the
/// memory during process creation. If the total size of the buffers
/// in use by this process exceed this initial size, memory on the
/// sink may continue to be allocated on demand, as needed, subject
/// to the system constraints on the sink.
///
/// @param in_LibrarySearchPath
/// [in] A path to locate dynamic libraries dependencies for the sink
/// application. If not NULL, this path will override the environment
/// variable SINK_LD_LIBRARY_PATH. If NULL it will use
/// SINK_LD_LIBRARY_PATH to locate dependencies.
///
/// @param in_FileOfOrigin
/// [in] If not NULL, this parameter indicates the file from which the
/// in_pBinaryBuffer was obtained. This parameter is optional.
///
/// @param in_FileOfOriginOffset
/// [in] If in_FileOfOrigin is not NULL, this parameter indicates the
/// offset within that file where in_pBinaryBuffer begins.
///
/// @param out_pProcess
/// [out] Handle returned to uniquely identify the process that was
/// created for use in later API calls.
///
/// @return COI_SUCCESS if the remote process was successfully created.
///
/// @return COI_INVALID_HANDLE if the in_Engine handle passed in was invalid.
///
/// @return COI_INVALID_POINTER if out_pProcess was NULL.
///
/// @return COI_INVALID_POINTER if in_pBinaryName or in_pBinaryBuffer was NULL.
///
/// @return COI_MISSING_DEPENDENCY if a dependent library is missing from
/// either SINK_LD_LIBRARY_PATH or the in_LibrarySearchPath parameter.
///
/// @return COI_BINARY_AND_HARDWARE_MISMATCH if in_pBinaryName or any of its
/// recursive dependencies were built for a target machine that does
/// not match the engine specified.
///
/// @return COI_RESOURCE_EXHAUSTED if no more COIProcesses can be created,
/// possibly, but not necessarily because in_InitialBufferSpace is too
/// large.
///
/// @return COI_ARGUMENT_MISMATCH if in_Argc is 0 and in_ppArgv is not NULL.
///
/// @return COI_ARGUMENT_MISMATCH if in_Argc is greater than 0 and in_ppArgv is
/// NULL.
///
/// @return COI_OUT_OF_RANGE if in_Argc is less than 0.
///
/// @return COI_OUT_OF_RANGE if the length of in_pBinaryName is greater than or
/// equal to COI_MAX_FILE_NAME_LENGTH.
///
/// @return COI_OUT_OF_RANGE if in_BinaryBufferLength is 0.
///
/// @return COI_TIME_OUT_REACHED if establishing the communication channel with
/// the remote process timed out.
///
/// @return COI_DOES_NOT_EXIST if in_FileOfOrigin is not NULL and does not
/// exist.
///
/// @return COI_ARGUMENT_MISMATCH if in_FileOfOrigin is NULL and
/// in_FileOfOriginOffset is not 0.
///
/// @return COI_INVALID_FILE if in_FileOfOrigin is not a "regular file" as
/// determined by stat or if its size is 0.
///
/// @return COI_OUT_OF_RANGE if in_FileOfOrigin exists but its size is
/// less than in_FileOfOriginOffset + in_BinaryBufferLength.
///
/// @return COI_NOT_INITIALIZED if the environment variable
/// SINK_LD_TRACE_LOADED_OBJECTS is set to a non empty string and there
/// are no errors locating the shared library dependencies.
///
/// @return COI_PROCESS_DIED if at some point during the loading of the remote
/// process the remote process terminated abnormally.
///
/// @return COI_VERSION_MISMATCH if the version of Intel® Coprocessor
/// Offload Infrastructure (Intel® COI) on the host is not
/// compatible with the version on the device.
///
COIACCESSAPI
COIRESULT
COIProcessCreateFromMemory(
COIENGINE in_Engine,
const char* in_pBinaryName,
const void* in_pBinaryBuffer,
uint64_t in_BinaryBufferLength,
int in_Argc,
const char** in_ppArgv,
uint8_t in_DupEnv,
const char** in_ppAdditionalEnv,
uint8_t in_ProxyActive,
const char* in_Reserved,
uint64_t in_InitialBufferSpace,
const char* in_LibrarySearchPath,
const char* in_FileOfOrigin,
uint64_t in_FileOfOriginOffset,
COIPROCESS* out_pProcess);
//////////////////////////////////////////////////////////////////////////////
///
/// Destroys the indicated process, releasing its resources. Note, this
/// will destroy any outstanding pipelines created in this process as well.
///
/// @param in_Process
/// [in] Process to destroy.
///
/// @param in_WaitForMainTimeout
/// [in] The number of milliseconds to wait for the main() function
/// to return in the sink process before timing out. -1 means to wait
/// indefinitely.
///
/// @param in_ForceDestroy
/// [in] If this flag is set to true, then the sink process will be
/// forcibly terminated after the timeout has been reached. A timeout
/// value of 0 will kill the process immediately, while a timeout of
/// -1 is invalid. If the flag is set to false then a message will
/// be sent to the sink process requesting a clean shutdown. A value
/// of false along with a timeout of 0 does not send a shutdown
/// message, instead simply polls the process to see if it is alive.
/// In most cases this flag should be set to false. If a sink process
/// is not responding then it may be necessary to set this flag to
/// true.
///
/// @param out_pProcessReturn
/// [out] The value returned from the main() function executing in
/// the sink process. This is an optional parameter. If the caller
/// is not interested in the return value from the remote process
/// they may pass in NULL for this parameter. The output value of
/// this pointer is only meaningful if COI_SUCCESS is returned.
///
/// @param out_pTerminationCode
/// [out] This parameter specifies the termination code. This will
/// be 0 if the remote process exited cleanly. If the remote process
/// exited abnormally this will contain the termination code given
/// by the operating system of the remote process. This is an optional
/// parameter and the caller may pass in NULL if they are not
/// interested in the termination code. The output value of this
/// pointer is only meaningful if COI_SUCCESS is returned.
///
/// @return COI_SUCCESS if the process was destroyed.
///
/// @return COI_INVALID_HANDLE if the process handle passed in was invalid.
///
/// @return COI_OUT_OF_RANGE for any negative in_WaitForMainTimeout value
/// except -1.
///
/// @return COI_ARGUMENT_MISMATCH if in_WaitForMainTimeout is -1 and
/// in_ForceDestroy is true.
///
/// @return COI_TIME_OUT_REACHED if the sink process is still running after
/// waiting in_WaitForMainTimeout milliseconds and in_ForceDestroy
/// is false. This is true even if in_WaitForMainTimeout was 0.
/// In this case, out_pProcessReturn and out_pTerminationCode
/// are undefined.
///
COIACCESSAPI
COIRESULT
COIProcessDestroy(
COIPROCESS in_Process,
int32_t in_WaitForMainTimeout,
uint8_t in_ForceDestroy,
int8_t* out_pProcessReturn,
uint32_t* out_pTerminationCode);
#define COI_MAX_FUNCTION_NAME_LENGTH 256
//////////////////////////////////////////////////////////////////////////////
///
/// Given a loaded native process, gets an array of function handles that can
/// be used to schedule run functions on a pipeline associated with that
/// process. See the documentation for COIPipelineRunFunction() for
/// additional information. All functions that are to be retrieved in this
/// fashion must have the define COINATIVEPROCESSEXPORT preceeding their type
/// specification. For functions that are written in C++, either the entries
/// in in_pFunctionNameArray in must be pre-mangled, or the functions must be
/// declared as extern "C". It is also necessary to link the binary containing
/// the exported functions with the -rdynamic linker flag.
/// It is possible for this call to successfully find function handles for
/// some of the names passed in but not all of them. If this occurs
/// COI_DOES_NOT_EXIST will return and any handles not found will be returned
/// as NULL.
///
/// @param in_Process
/// [in] Process handle previously returned via COIProcessCreate().
///
/// @param in_NumFunctions
/// [in] Number of function names passed in to the in_pFunctionNames
/// array.
///
/// @param in_ppFunctionNameArray
/// [in] Pointer to an array of null-terminated strings that match
/// the name of functions present in the code of the binary
/// previously loaded via COIProcessCreate(). Note that if a C++
/// function is used, then the string passed in must already be
/// properly name-mangled, or extern "C" must be used for where
/// the function is declared.
///
/// @param out_pFunctionHandleArray
/// [in out] Pointer to a location created by the caller large
/// enough to hold an array of COIFUNCTION sized elements that has
/// in_numFunctions entries in the array.
///
/// @return COI_SUCCESS if all function names indicated were found.
///
/// @return COI_INVALID_HANDLE if the in_Process handle passed in was invalid.
///
/// @return COI_OUT_OF_RANGE if in_NumFunctions is zero.
///
/// @return COI_INVALID_POINTER if the in_ppFunctionNameArray or
/// out_pFunctionHandleArray pointers was NULL.
///
/// @return COI_DOES_NOT_EXIST if one or more function names were not
/// found. To determine the function names that were not found,
/// check which elements in the out_pFunctionHandleArray
/// are set to NULL.
///
/// @return COI_OUT_OF_RANGE if any of the null-terminated strings passed in
/// via in_ppFunctionNameArray were more than
/// COI_MAX_FUNCTION_NAME_LENGTH characters in length including
/// the null.
///
/// @warning This operation can take several milliseconds so it is recommended
/// that it only be be done at load time.
///
COIACCESSAPI
COIRESULT
COIProcessGetFunctionHandles(
COIPROCESS in_Process,
uint32_t in_NumFunctions,
const char** in_ppFunctionNameArray,
COIFUNCTION* out_pFunctionHandleArray);
#if COI_LIBRARY_VERSION >= 2
/// @name COIProcessLoadLibrary* flags, named after the corresponding
/// RTLD flags that are passed into dlopen().
/// Please consult a Linux manual for more information about these flags.
//@{
#define COI_LOADLIBRARY_LOCAL 0x00000
#define COI_LOADLIBRARY_GLOBAL 0x00100
#define COI_LOADLIBRARY_LAZY 0x00001
#define COI_LOADLIBRARY_NOW 0x00002
#define COI_LOADLIBRARY_NOLOAD 0x00004
#define COI_LOADLIBRARY_DEEPBIND 0x00008
#define COI_LOADLIBRARY_NODELETE 0x01000
/// Flags to replicate the behavior of the original version of
/// COIProcessLoadLibrary* APIs.
#define COI_LOADLIBRARY_V1_FLAGS (COI_LOADLIBRARY_GLOBAL|COI_LOADLIBRARY_NOW)
//@}
#endif
//////////////////////////////////////////////////////////////////////////////
///
/// Loads a shared library into the specified remote process, akin to using
/// dlopen() on a local process in Linux or LoadLibrary() in Windows.
/// Dependencies for this library that are not listed with absolute paths
/// are searched for first in current working directory, then in the
/// colon-delimited paths in the environment variable SINK_LD_LIBRARY_PATH,
/// and finally on the sink in the standard search paths as defined by the
/// sink's operating system / dynamic loader.
///
/// @param in_Process
/// [in] Process to load the library into.
///
/// @param in_pLibraryBuffer
/// [in] The memory buffer containing the shared library to load.
///
/// @param in_LibraryBufferLength
/// [in] The number of bytes in the memory buffer in_pLibraryBuffer.
///
/// @param in_pLibraryName
/// [in] Name for the shared library. This optional parameter can
/// be specified in case the dynamic library doesn't have an
/// SO_NAME field. If specified, it will take precedence over
/// the SO_NAME if it exists. If it is not specified then
/// the library must have a valid SO_NAME field.
///
///@param in_LibrarySearchPath
/// [in] A path to locate dynamic libraries dependencies for the
/// library being loaded. If not NULL, this path will override the
/// environment variable SINK_LD_LIBRARY_PATH. If NULL it will use
/// SINK_LD_LIBRARY_PATH to locate dependencies.
///
///@param in_LibrarySearchPath
/// [in] A path to locate dynamic libraries dependencies for the sink
/// application. If not NULL, this path will override the environment
/// variable SINK_LD_LIBRARY_PATH. If NULL it will use
/// SINK_LD_LIBRARY_PATH to locate dependencies.
///
/// @param in_FileOfOrigin
/// [in] If not NULL, this parameter indicates the file from which the
/// in_pBinaryBuffer was obtained. This parameter is optional.
///
/// @param in_FileOfOriginOffset
/// [in] If in_FileOfOrigin is not NULL, this parameter indicates the
/// offset within that file where in_pBinaryBuffer begins.
///
#if COI_LIBRARY_VERSION >= 2
/// @param in_Flags
/// [in] Bitmask of the flags that will be passed in as the dlopen()
/// "flag" parameter on the sink.
///
#endif
///
/// @param out_pLibrary
/// [out] If COI_SUCCESS or COI_ALREADY_EXISTS is returned, the handle
/// that uniquely identifies the loaded library.
///
/// @return COI_SUCCESS if the library was successfully loaded.
///
/// @return COI_INVALID_HANDLE if the process handle passed in was invalid.
///
/// @return COI_OUT_OF_RANGE if in_LibraryBufferLength is 0.
///
/// @return COI_INVALID_FILE if in_pLibraryBuffer does not represent a valid
/// shared library file.
///
/// @return COI_MISSING_DEPENDENCY if a dependent library is missing from
/// either SINK_LD_LIBRARY_PATH or the in_LibrarySearchPath parameter.
///
/// @return COI_ARGUMENT_MISMATCH if the shared library is missing an SONAME
/// and in_pLibraryName is NULL.
///
/// @return COI_ARGUMENT_MISMATCH if in_pLibraryName is the same as that of
/// any of the dependencies (recursive) of the library being loaded.
///
/// @return COI_ALREADY_EXISTS if there is an existing COILIBRARY handle
/// that identifies this library, and this COILIBRARY hasn't been
/// unloaded yet.
///
/// @return COI_BINARY_AND_HARDWARE_MISMATCH if the target machine of the
/// binary or any of its recursive dependencies does not match the
/// engine associated with in_Process.
///
/// @return COI_UNDEFINED_SYMBOL if we are unable to load the library due to
/// an undefined symbol.
///
/// @return COI_PROCESS_DIED if loading the library on the device caused
/// the remote process to terminate.
///
/// @return COI_DOES_NOT_EXIST if in_FileOfOrigin is not NULL and does not
/// exist.
///
/// @return COI_ARGUMENT_MISMATCH if in_FileOfOrigin is NULL and
/// in_FileOfOriginOffset is not 0.
///
/// @return COI_INVALID_FILE if in_FileOfOrigin is not a "regular file" as
/// determined by stat or if its size is 0.
///
/// @return COI_OUT_OF_RANGE if in_FileOfOrigin exists but its size is
/// less than in_FileOfOriginOffset + in_BinaryBufferLength.
///
/// @return COI_INVALID_POINTER if out_pLibrary or in_pLibraryBuffer are NULL.
///
#if COI_LIBRARY_VERSION >= 2
COIACCESSAPI
COIRESULT
COIProcessLoadLibraryFromMemory(
COIPROCESS in_Process,
const void* in_pLibraryBuffer,
uint64_t in_LibraryBufferLength,
const char* in_pLibraryName,
const char* in_LibrarySearchPath,
const char* in_FileOfOrigin,
uint64_t in_FileOfOriginOffset,
uint32_t in_Flags,
COILIBRARY* out_pLibrary);
__asm__(".symver COIProcessLoadLibraryFromMemory,"
"COIProcessLoadLibraryFromMemory@COI_2.0");
#else
COIRESULT
COIProcessLoadLibraryFromMemory(
COIPROCESS in_Process,
const void* in_pLibraryBuffer,
uint64_t in_LibraryBufferLength,
const char* in_pLibraryName,
const char* in_LibrarySearchPath,
const char* in_FileOfOrigin,
uint64_t in_FileOfOriginOffset,
COILIBRARY* out_pLibrary);
__asm__(".symver COIProcessLoadLibraryFromMemory,"
"COIProcessLoadLibraryFromMemory@COI_1.0");
#endif
//////////////////////////////////////////////////////////////////////////////
///
/// Loads a shared library into the specified remote process, akin to using
/// dlopen() on a local process in Linux or LoadLibrary() in Windows.
///
/// For more details, see COIProcessLoadLibraryFromMemory.
///
/// @param in_Process
/// [in] Process to load the library into.
///
/// @param in_pFileName
/// [in] The name of the shared library file on the source's file
/// system that is being loaded. If the file name is not an absolute
/// path, the file is searched for in the same manner as dependencies.
///
/// @param in_pLibraryName
/// [in] Name for the shared library. This optional parameter can
/// be specified in case the dynamic library doesn't have an
/// SO_NAME field. If specified, it will take precedence over
/// the SO_NAME if it exists. If it is not specified then
/// the library must have a valid SO_NAME field.
///
///@param in_LibrarySearchPath
/// [in] a path to locate dynamic libraries dependencies for the
/// library being loaded. If not NULL, this path will override the
/// environment variable SINK_LD_LIBRARY_PATH. If NULL it will use
/// SINK_LD_LIBRARY_PATH to locate dependencies.
///
#if COI_LIBRARY_VERSION >= 2
/// @param in_Flags
/// [in] Bitmask of the flags that will be passed in as the dlopen()
/// "flag" parameter on the sink.
///
#endif
///
/// @param out_pLibrary
/// [out] If COI_SUCCESS or COI_ALREADY_EXISTS is returned, the handle
/// that uniquely identifies the loaded library.
///
/// @return COI_SUCCESS if the library was successfully loaded.
///
/// @return COI_INVALID_POINTER if in_pFileName is NULL.
///
/// @return COI_DOES_NOT_EXIST if in_pFileName cannot be found.
///
/// @return COI_INVALID_FILE if the file is not a valid shared library.
///
/// @return See COIProcessLoadLibraryFromMemory for additional errors.
///
#if COI_LIBRARY_VERSION >= 2
COIACCESSAPI
COIRESULT
COIProcessLoadLibraryFromFile(
COIPROCESS in_Process,
const char* in_pFileName,
const char* in_pLibraryName,
const char* in_LibrarySearchPath,
uint32_t in_Flags,
COILIBRARY* out_pLibrary);
__asm__(".symver COIProcessLoadLibraryFromFile,"
"COIProcessLoadLibraryFromFile@COI_2.0");
#else
COIRESULT
COIProcessLoadLibraryFromFile(
COIPROCESS in_Process,
const char* in_pFileName,
const char* in_pLibraryName,
const char* in_LibrarySearchPath,
COILIBRARY* out_pLibrary);
__asm__(".symver COIProcessLoadLibraryFromFile,"
"COIProcessLoadLibraryFromFile@COI_1.0");
#endif
//////////////////////////////////////////////////////////////////////////////
///
/// Unloads a a previously loaded shared library from the specified
/// remote process.
///
/// @param in_Process
/// [in] Process that we are unloading a library from.
///
/// @param in_Library
/// [in] Library that we want to unload.
///
/// @return COI_SUCCESS if the library was successfully loaded.
///
/// @return COI_INVALID_HANDLE if the process or library handle were invalid.
///
COIACCESSAPI
COIRESULT
COIProcessUnloadLibrary(
COIPROCESS in_Process,
COILIBRARY in_Library);
//////////////////////////////////////////////////////////////////////////////
///
/// Registers shared libraries that are already in the host process's memory
/// to be used during the shared library dependency resolution steps that take
/// place during subsequent calls to COIProcessCreate* and
/// COIProcessLoadLibrary*. If listed as a dependency, the registered library
/// will be used to satisfy the dependency, even if there is another library
/// on disk that also satisfies that dependency.
///
/// Addresses registered must remain valid during subsequent calls to
/// COIProcessCreate* and COIProcessLoadLibrary*.
///
/// If the Sink is Linux, the shared libraries must have a library name
/// (DT_SONAME field). On most compilers this means built with -soname.
///
/// If successful, this API registers all the libraries. Otherwise none
/// are registered.
///
/// @param in_NumLibraries
/// [in] The number of libraries that are being registered.
///
/// @param in_ppLibraryArray
/// [in] An array of pointers that point to the starting addresses
/// of the libraries.
///
/// @param in_pLibrarySizeArray
/// [in] An array of pointers that point to the number of bytes in
/// each of the libraries.
///
/// @param in_ppFileOfOriginArray
/// [in] An array of strings indicating the file from which the
/// library was obtained. This parameter is optional. Elements
/// in the array may be set to NULL.
///
/// @param in_pFileOfOriginOffSetArray
/// [in] If the corresponding entry in in_ppFileOfOriginArray is not
/// NULL, this parameter indicates the offsets within those files
/// where the corresponding libraries begin.
///
/// @return COI_SUCCESS if the libraries were registered successfully.
///
/// @return COI_OUT_OF_RANGE if in_NumLibraries is 0.
///
/// @return COI_INVALID_POINTER if in_ppLibraryArray or in_pLibrarySizeArray
/// are NULL.
///
/// @return COI_INVALID_POINTER if any of the pointers in in_ppLibraryArray
/// are NULL.
///
/// @return COI_OUT_OF_RANGE if any of the values in in_pLibrarySizeArray is 0.
///
/// @return COI_ARGUMENT_MISMATCH if either one of in_ppFileOfOriginArray
/// and in_pFileOfOriginOffSetArray is NULL and the other is not.
///
/// @return COI_OUT_OF_RANGE if one of the addresses being registered does not
/// represent a valid library.
///
COIACCESSAPI
COIRESULT
COIProcessRegisterLibraries(
uint32_t in_NumLibraries,
const void** in_ppLibraryArray,
const uint64_t* in_pLibrarySizeArray,
const char** in_ppFileOfOriginArray,
const uint64_t* in_pFileOfOriginOffSetArray);
//////////////////////////////////////////////////////////////////////////////
/// The user can choose to have notifications for these internal events
/// so that they can build their own profiling and performance layer on
/// top of Intel® Coprocessor Offload Infrastructure (Intel® COI) .
///
typedef enum COI_NOTIFICATIONS
{
/// This event occurs when all explicit and implicit dependencies are
/// satisified and Intel® Coprocessor Offload Infrastructure
/// (Intel® COI) schedules the run function to begin execution.
RUN_FUNCTION_READY = 0,
/// This event occurs just before the run function actually starts
/// executing. There may be some latency between the ready and start
/// events if other run functions are already queued and ready to run.
RUN_FUNCTION_START,
/// This event occurs when the run function finishes. This is when the
/// completion event for that run function would be signaled.
RUN_FUNCTION_COMPLETE,
/// This event occurs when all explicit and implicit dependencies are
/// met for the pending buffer operation. Assuming buffer needs to be
/// moved, copied, read, etc... Will not be invoked if no actual memory
/// is moved, copied, read, etc. This means that COIBufferUnmap will
/// never result in a callback as it simply updates the status of the
/// buffer but doesn't initiate any data movement. COIBufferMap,
/// COIBufferSetState, COIBufferWrite, COIBufferRead and COIBufferCopy
/// do initiate data movement and therefore will invoke the callback.
BUFFER_OPERATION_READY,
/// This event occurs when the buffer operation is completed.
BUFFER_OPERATION_COMPLETE,
/// This event occurs when a user event is signaled from the remotely
/// a sink process. Local (source triggered) events do not trigger this.
USER_EVENT_SIGNALED
} COI_NOTIFICATIONS;
//////////////////////////////////////////////////////////////////////////////
///
/// A callback that will be invoked to notify the user of an internal
/// Intel® Coprocessor Offload Infrastructure (Intel® COI)
/// event. Note that the callback is registered per process so any of the
/// above notifications that happen on the registered process will receive
/// the callback.
/// As with any callback mechanism it is up to the user to make sure that
/// there are no possible deadlocks due to reentrancy (ie the callback being
/// invoked in the same context that triggered the notification) and also
/// that the callback does not slow down overall processing. If the user
/// performs too much work within the callback it could delay further
/// Intel® Coprocessor Offload Infrastructure (Intel® COI)
/// processing.
/// Intel® Coprocessor Offload Infrastructure (Intel® COI)
/// promises to invoke the callback for an internal event prior to
/// signaling the corresponding COIEvent. For example, if a user is waiting
/// for a COIEvent associated with a run function completing they will
/// receive the callback before the COIEvent is marked as signaled.
///
///
/// @param in_Type
/// [in] The type of internal event that has occurred.
///
/// @param in_Process
/// [in] The process associated with the operation.
///
/// @param in_Event
/// [in] The completion event that is associated with the
/// operation that is being notified.
///
/// @param in_UserData
/// [in] Opaque data that was provided when the callback was
/// registered. Intel® Coprocessor Offload Infrastructure (Intel® COI) simply passes this back to the user so that
/// they can interpret it as they choose.
///
typedef void (*COI_NOTIFICATION_CALLBACK)(
COI_NOTIFICATIONS in_Type,
COIPROCESS in_Process,
COIEVENT in_Event,
const void* in_UserData);
//////////////////////////////////////////////////////////////////////////////
///
/// Register a callback to be invoked to notify that an internal
/// Intel® Coprocessor Offload Infrastructure (Intel® COI) event
/// has occured on the process that is associated with the callback.
/// Note that it is legal to have more than one callback registered with
/// a given process but those must all be unique callback pointers.
/// Note that setting a UserData value with COINotificationCallbackSetContext
/// will override a value set when registering the callback.
///
/// @param in_Process
/// [in] Process that the callback is associated with. The callback
/// will only be invoked to notify an event for this specific process.
///
/// @param in_Callback
/// [in] Pointer to a user function used to signal a notification.
///
/// @param in_UserData
/// [in] Opaque data to pass to the callback when it is invoked.
///
/// @return COI_SUCCESS if the callback was registered successfully.
///
/// @return COI_INVALID_HANDLE if the in_Process parameter does not identify
/// a valid process.
///
/// @return COI_INVALID_POINTER if the in_Callback parameter is NULL.
///
/// @return COI_ALREADY_EXISTS if the user attempts to reregister the same
/// callback for a process.
///
COIACCESSAPI
COIRESULT COIRegisterNotificationCallback(
COIPROCESS in_Process,
COI_NOTIFICATION_CALLBACK in_Callback,
const void* in_UserData);
//////////////////////////////////////////////////////////////////////////////
///
/// Unregisters a callback, notifications will no longer be signaled.
///
/// @param in_Process
/// [in] Process that we are unregistering.
///
/// @param in_Callback
/// [in] The specific callback to unregister.
///
/// @return COI_SUCCESS if the callback was unregistered.
///
/// @return COI_INVALID_HANDLE if the in_Process parameter does not identify
/// a valid process.
///
/// @return COI_INVALID_POINTER if the in_Callback parameter is NULL.
///
/// @return COI_DOES_NOT_EXIST if in_Callback was not previously registered
/// for in_Process.
///
COIACCESSAPI
COIRESULT COIUnregisterNotificationCallback(
COIPROCESS in_Process,
COI_NOTIFICATION_CALLBACK in_Callback);
//////////////////////////////////////////////////////////////////////////////
///
/// Set the user data that will be returned in the notification callback.
/// This data is sticky and per thread so must be set prior to the
/// Intel® Coprocessor Offload Infrastructure (Intel® COI) //
/// operation being invoked. If you wish to set the context to be returned
/// for a specific instance of a user event notification then the context
/// must be set using this API prior to registering that user event with
/// COIEventRegisterUserEvent.
/// The value may be set prior to each Intel® Coprocessor Offload
/// Infrastructure (Intel® COI) operation being called to
/// effectively have a unique UserData per callback.
/// Setting this value overrides any value that was set when the
/// callback was registered and will also override any future registrations
/// that occur.
///
/// @param in_UserData
/// [in] Opaque data to pass to the callback when it is invoked.
/// Note that this data is set per thread.
///
COIACCESSAPI
void COINotificationCallbackSetContext(
const void* in_UserData);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* _COIPROCESS_SOURCE_H */
/*! @} */

View File

@ -0,0 +1,619 @@
/*
* Copyright 2010-2013 Intel Corporation.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, version 2.1.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* Disclaimer: The codes contained in these modules may be specific
* to the Intel Software Development Platform codenamed Knights Ferry,
* and the Intel product codenamed Knights Corner, and are not backward
* compatible with other Intel products. Additionally, Intel will NOT
* support the codes or instruction set in future products.
*
* Intel offers no warranty of any kind regarding the code. This code is
* licensed on an "AS IS" basis and Intel is not obligated to provide
* any support, assistance, installation, training, or other services
* of any kind. Intel is also not obligated to provide any updates,
* enhancements or extensions. Intel specifically disclaims any warranty
* of merchantability, non-infringement, fitness for any particular
* purpose, and any other warranty.
*
* Further, Intel disclaims all liability of any kind, including but
* not limited to liability for infringement of any proprietary rights,
* relating to the use of the code, even if Intel is notified of the
* possibility of such liability. Except as expressly stated in an Intel
* license agreement provided with this code and agreed upon with Intel,
* no license, express or implied, by estoppel or otherwise, to any
* intellectual property rights is granted herein.
*/
/**
* Description:
* External APIs of MYO runtime (MYO stands for Mine, Yours and Ours).
**/
#ifndef _MYO_H_
#define _MYO_H_
#include "myotypes.h"
#include "myoimpl.h"
/** @ingroup MYO
* @addtogroup MYO_API
@{
* @file myo.h
*/
#ifdef __cplusplus
extern "C" {
#endif
/****************************************************************************
Arena-based APIs
***************************************************************************/
/*
* Arena is a set of memory pages with the same ownership type. The ownership
* type of all the memory pages inside the same arena can only be changed as
* a whole. For "OURS", it is also the minimal unit of sync operations to
* implement "release consistency".
*/
/** @fn extern MyoError myoArenaCreate(MyoOwnershipType in_Type,
* int in_Property, MyoArena *out_pArena)
* @brief Create an arena with specified ownership type and property.
*
* @param in_Type Specified ownership type (MYO_ARENA_OURS or
* MYO_ARENA_MINE).
* @param in_Property Specified properties of the arena. Set it
* to 0 to use default properties.
*
* MYO_RELEASE_CONSISTENCY or MYO_STRONG_RELEASE_CONSISTENCY
* or MYO_STRONG_CONSISTENCY:
*
* Consistency modes for "OURS" arenas. For MYO_RELEASE_CONSISTENCY,
* there are 2 functions, "Acquire" and "Release", which are
* used for memory ordering. "Release" makes all local stores
* prior to the release globally visible; "Acquire" syncs up the
* local memory with all stores that have been made globally
* visible. However, there is no definite answer as to whether
* local stores can be globally visible before reaching a release
* point, nor whether the newest globally visible stores can be
* updated to local before reaching an acquire point. By using
* MYO_STRONG_RELEASE_CONSISTENCY, the answer to these questions
* is "no". A sequential consistency model is maintained to the
* arena when using MYO_STRONG_CONSISTENCY.
* MYO_RELEASE_CONSISTENCY is the default property.
*
* MYO_UPDATE_ON_DEMAND or MYO_UPDATE_ON_ACQUIRE:
*
* Only apply to "OURS" arenas with "Release Consistency".
* MYO_UPDATE_ON_ACQUIRE means that the shared pages of this
* arena will be updated on acquire point; MYO_UPDATE_ON_DEMAND
* means that the shared pages will not be updated until they
* are accessed. MYO_UPDATE_ON_DEMAND is the default property.
*
* MYO_RECORD_DIRTY or MYO_NOT_RECORD_DIRTY:
*
* This property controls whether to record dirty pages.
* There will be runtime overhead when recording dirty pages,
* as it can reduce the communication data. It is a trade-off
* for performance. Also when MYO_NOT_RECORD_DIRTY is set for
* "OURS" arena, the runtime cannot guarantee the correctness
* when the host and card modify the same shared page between
* the same sync segment. MYO_RECORD_DIRTY is the default
* property.
*
* MYO_ONE_VERSION or MYO_MULTI_VERSION:
*
* Only apply to "OURS" arenas with "Release Consistency". When
* MYO_MULTI_VERSION is set, this arena can only be "release" on
* HOST side and "acquire" on CARD side. Releasing the arena on
* HOST will create a new versioned data and put it into a FIFO;
* acquiring the arena on CARD will get the versioned data
* from the FIFO one by one. MYO_ONE_VERSION is the default
* property.
*
* MYO_CONSISTENCY or MYO_NO_CONSISTENCY:
*
* Only apply to "OURS" arenas with "Release Consistency". When
* MYO_NO_CONSISTENCY is set, the consistency of the arena will
* not be maintained. That is, it is a no-op operation when
* calling acquire/release for such arenas. MYO_CONSISTENCY is
* the default property.
*
* MYO_HOST_TO_DEVICE and MYO_DEVICE_TO_HOST:
*
* When it is certain that there is only one communication
* direction for this arena, it can be created with only
* MYO_HOST_TO_DEVICE or MYO_DEVICE_TO_HOST so the runtime
* can perform optimizations. The default property is
* MYO_HOST_TO_DEVICE | MYO_DEVICE_TO_HOST.
*
* @param out_pArena Used to store the handle of the created arena.
* @return
* MYO_SUCCESS; or
* an error number to indicate the error.
**/
MYOACCESSAPI
CILK_SHARED MyoError myoArenaCreate(MyoOwnershipType in_Type, int in_Property, MyoArena *out_pArena);
/** @fn extern MyoError myoArenaDestroy(MyoArena in_Arena)
* @brief Destroy an arena. As a result, the arena can not be
* referred any more.
*
* @param in_Arena Arena handle returned by previous call to
* myoArenaCreate.
* @return
* MYO_SUCCESS; or
* an error number to indicate the error.
**/
MYOACCESSAPI
CILK_SHARED MyoError myoArenaDestroy(MyoArena in_Arena);
/** @fn extern void *myoArenaMalloc(MyoArena in_Arena, size_t in_Size)
* @brief Allocates size bytes from the specified arena, and returns
* the start address of the allocated memory. The memory is not
* cleared.
*
* @param in_Arena Arena handle returned by previous call to
* myoArenaCreate.
* @param in_Size Size (bytes) of the required memory space.
* @return
* The start address of the allocated memory space.
* NULL: Failed.
**/
MYOACCESSAPI
void *myoArenaMalloc(MyoArena in_Arena, size_t in_Size);
/** @fn extern void myoArenaFree(MyoArena in_Arena, void *in_pPtr)
* @brief Frees the memory space allocated by myoArenaMalloc to the
* specified arena.
*
* @param in_Arena Arena handle returned by previous call to
* myoArenaCreate.
* @param in_pPtr The start address of the specified memory
* space, which must be retured by myoArenaMalloc.
* @return
**/
MYOACCESSAPI
void myoArenaFree(MyoArena in_Arena, void *in_pPtr);
/** @fn extern void *myoArenaAlignedMalloc(MyoArena in_Arena,
* size_t in_Size, size_t in_Alignment)
* @brief Allocates size bytes from the specified arena. The
* start address of the allocated memory will be a multiple of the
* alignment, which must be a power of two.
*
* @param in_Arena Arena handle returned by previous call to
* myoArenaCreate.
* @param in_Size Size (bytes) of the required memory space.
* @param in_Alignment The alignment value (must be a power
* of two).
* @return
* The start address of the allocated memory space.
* NULL: Failed.
**/
MYOACCESSAPI
void *myoArenaAlignedMalloc(MyoArena in_Arena, size_t in_Size, size_t in_Alignment);
/** @fn extern void myoArenaAlignedFree(MyoArena in_Arena, void *in_pPtr)
* @brief Frees the memory space allocated by myoArenaAlignedMalloc
* to the specified arena.
*
* @param in_Arena Arena handle returned by previous call to
* myoArenaCreate.
* @param in_pPtr The start address of the specified memory space,
* which must be returned by myoArenaAlignedMalloc.
* @return
**/
MYOACCESSAPI
void myoArenaAlignedFree(MyoArena in_Arena, void *in_pPtr);
/** @fn extern MyoError myoArenaAcquire(MyoArena in_Arena)
* @brief myoArenaAcquire is the sync point for "OURS" arena with
* "Release Consistency". myoArenaAcquire is used to obtain all
* stores of "OURS" arena that have been made globally visible prior
* to this point.
*
* @param in_Arena Arena handle returned by previous call to
* myoArenaCreate.
* @return
* MYO_SUCCESS; or
* an error number to indicate the error.
**/
MYOACCESSAPI
CILK_SHARED MyoError myoArenaAcquire(MyoArena in_Arena);
/** @fn extern MyoError myoArenaRelease(MyoArena in_Arena)
* @brief myoArenaRelease is the sync point for "OURS" arena with
* "Release Consistency". myoArenaRelease is used to flush all prior
* stores of "OURS" arena to be globally visible.
*
* @param in_Arena Arena handle returned by previous call to
* myoArenaCreate.
* @return
* MYO_SUCCESS; or
* an error number to indicate the error.
**/
MYOACCESSAPI
CILK_SHARED MyoError myoArenaRelease(MyoArena in_Arena);
/** @fn extern MyoError myoArenaAcquireOwnership(MyoArena in_Arena)
* @brief Changes the ownership type of the arena to MYO_ARENA_MINE.
*
* @param in_Arena Arena handle returned by previous call to
* myoArenaCreate.
* @return
* MYO_SUCCESS; or
* an error number to indicate the error.
**/
MYOACCESSAPI
MyoError myoArenaAcquireOwnership(MyoArena in_Arena);
/** @fn extern MyoError myoArenaReleaseOwnership(MyoArena in_Arena)
* @brief Change the ownership type of the arena to MYO_ARENA_OURS.
*
* @param in_Arena Arena handle returned by previous call to
* myoArenaCreate.
* @return
* MYO_SUCCESS; or
* an error number to indicate the error.
**/
MYOACCESSAPI
MyoError myoArenaReleaseOwnership(MyoArena in_Arena);
/** @fn extern MyoError myoArenaGetHandle(void *in_pPtr,
* MyoArena *out_pArena)
* @brief Gets the arena handle of the arena that contains the memory
* space pointed to by "in_pPtr". This API can be used when it is
* not clear which arena handle should be used for other arena
* related APIs.
*
* @param in_pPtr The start address of a chunk of memory space.
* @param out_pArena Handle of the arena.
* @return
* MYO_SUCCESS; or
* an error number to indicate the error.
**/
MYOACCESSAPI
CILK_SHARED MyoError myoArenaGetHandle(void *in_pPtr, MyoArena *out_pArena);
/********************************************************************************
APIs for the default arena
*******************************************************************************/
/**
* There will be a default arena inside MYO runtime, which will be used when
* there is no specified arena.
**/
/** @fn extern void* myoSharedMalloc(size_t in_Size)
* @brief Allocates size bytes from the default arena, and returns the
* start address of the allocated memory. The memory is not cleared.
*
@param in_Size Size (bytes) of the required memory space.
* @return
* The start address of the allocated memory space.
* NULL: Failed.
**/
MYOACCESSAPI
void* myoSharedMalloc(size_t in_Size);
/** @fn extern void myoSharedFree(void *in_pPtr)
* @brief Frees the memory space allocated by myoArenaMalloc to the
* default arena.
*
* @param in_pPtr The start address of the specified memory space,
* which must be retured by myoSharedMalloc.
* @return
**/
MYOACCESSAPI
void myoSharedFree(void *in_pPtr);
/** @fn extern void* myoSharedAlignedMalloc(size_t in_Size,
* size_t in_Alignment)
* @brief Allocates size bytes from the default arena. The start
* address of the allocated memory will be a multiple of alignment,
* which must be a power of two.
*
* @param in_Size Size (bytes) of the required memory space.
* @param in_Alignment The alignment value, which must be an power of two.
* @return
* The start address of the allocated memory space.
* NULL: Failed.
**/
MYOACCESSAPI
void* myoSharedAlignedMalloc(size_t in_Size, size_t in_Alignment);
/** @fn extern void myoSharedAlignedFree(void *in_pPtr)
* @brief Frees the memory space allocated by myoArenaAlignedMalloc
* to the default arena.
*
* @param in_pPtr The start address of the specified memory space,
* which must be returned by myoArenaAlignedMalloc.
* @return
**/
MYOACCESSAPI
void myoSharedAlignedFree(void *in_pPtr);
/** @fn extern MyoError myoAcquire()
* @brief myoAcquire is the sync point for the default arena with
* "Release Consistency". myoAcquire is used to obtain all stores of
* the default arena that have been made globally visible prior to
* this point.
*
* @return
* MYO_SUCCESS; or
* an error number to indicate the error.
**/
MYOACCESSAPI
MyoError myoAcquire();
/** @fn extern MyoError myoRelease()
* @brief myoRelease is the sync point for the default arena with
* "Release Consistency". myoRelease is used to flush all prior stores
* of the default arena to be globally visible.
*
* @return
* MYO_SUCCESS; or
* an error number to indicate the error.
**/
MYOACCESSAPI
MyoError myoRelease();
/** @fn extern MyoError myoAcquireOwnership()
* @brief Changes the ownership type of the default arena to
* MYO_ARENA_MINE.
*
* @return
* MYO_SUCCESS; or
* an error number to indicate the error.
**/
MYOACCESSAPI
MyoError myoAcquireOwnership();
/** @fn extern MyoError myoReleaseOwnership()
* @brief Change the ownership type of the default arena to
* MYO_ARENA_OURS.
*
* @return
* MYO_SUCCESS; or
* an error number to indicate the error.
**/
MYOACCESSAPI
MyoError myoReleaseOwnership();
/*****************************************************************************
APIs for global sync operations.
*****************************************************************************/
/** @fn extern MyoError myoMutexCreate(MyoMutex *out_pMutex)
* @brief Create a mutex and return the mutex handle.
*
* @param out_pMutex Used to store the handle of the created mutex.
* @return
* MYO_SUCCESS; or
* an error number to indicate the error.
**/
MYOACCESSAPI
MyoError myoMutexCreate(MyoMutex *out_pMutex);
/** @fn extern MyoError myoMutexLock(MyoMutex in_Mutex)
* @brief Lock the mutex. If the mutex is already locked by other peers,
* the call blocks until the mutex becomes available. Currently,
* attempting to re-acquire the mutex will cause a deadlock.
*
* @param in_Mutex the mutex handle returned by myoMutexCreate.
* @return
* MYO_SUCCESS; or
* an error number to indicate the error.
**/
MYOACCESSAPI
MyoError myoMutexLock(MyoMutex in_Mutex);
/** @fn extern MyoError myoMutexUnlock(MyoMutex in_Mutex)
* @brief Release the locked mutex.
* Currently, attempting to release an unlocked mutex will cause
* undefined results.
*
* @param in_Mutex the mutex handle returned by myoMutexCreate.
* @return
* MYO_SUCCESS; or
* an error number to indicate the error.
**/
MYOACCESSAPI
MyoError myoMutexUnlock(MyoMutex in_Mutex);
/** @fn extern MyoError myoMutexTryLock(MyoMutex in_Mutex)
* @brief Try to lock the mutex. myoMutexTryLock is equivalent to
* myoMutexLock, except that myoMutexLock will return immediately if
* the mutex is already locked.
*
* @param in_Mutex the mutex handle returned by myoMutexCreate.
* @return
* MYO_SUCCESS; or
* an error number to indicate the error.
**/
MYOACCESSAPI
MyoError myoMutexTryLock(MyoMutex in_Mutex);
/** @fn extern MyoError myoMutexDestroy(MyoMutex in_Mutex)
* @brief Destroy the mutex.
*
* @param in_Mutex the mutex handle returned by myoMutexCreate.
* @return
* MYO_SUCCESS; or
* an error number to indicate the error.
**/
MYOACCESSAPI
MyoError myoMutexDestroy(MyoMutex in_Mutex);
/** @fn extern MyoError myoSemCreate(int in_Value, MyoSem *out_pSem)
* @brief Create a semaphore and return the semaphore handle.
*
* @param in_Value the initial value for the semaphore.
* @param out_pSem Used to store the handle of the created semaphore.
* @return
* MYO_SUCCESS; or
* an error number to indicate the error.
**/
MYOACCESSAPI
MyoError myoSemCreate(int in_Value, MyoSem *out_pSem);
/** @fn extern MyoError myoSemWait(MyoSem in_Sem)
* @brief Decrements (locks) the semaphore. If the semaphore value is
* greater than zero, then the decrement proceeds and the function
* returns immediately, or else the call blocks until the semaphore
* value rises above zero.
*
* @param in_Sem the semaphore handle returned by myoSemCreate.
* @return
* MYO_SUCCESS; or
* an error number to indicate the error.
**/
MYOACCESSAPI
MyoError myoSemWait(MyoSem in_Sem);
/** @fn extern MyoError myoSemPost(MyoSem in_Sem)
* @brief Increments (unlocks) the semaphore. If the semaphore value
* becomes greater than zero, one blocked myoSemWait call will be
* notified to return.
*
* @param in_Sem the semaphore handle returned by myoSemCreate.
* @return
* MYO_SUCCESS; or
* an error number to indicate the error.
**/
MYOACCESSAPI
MyoError myoSemPost(MyoSem in_Sem);
/** @fn extern MyoError myoSemTryWait(MyoSem in_Sem)
* @brief Try to lock semaphore. myoSemTryWait is the same as
* myoSemAcquire, except that if the decrement cannot be immediately
* performed, then the call returns instead of blocking.
*
* @param in_Sem the semaphore handle returned by myoSemCreate.
* @return
* MYO_SUCCESS; or
* an error number to indicate the error.
**/
MYOACCESSAPI
MyoError myoSemTryWait(MyoSem in_Sem);
/** @fn extern MyoError myoSemDestroy(MyoSem in_Sem)
* @brief Destroy the semaphore.
*
* @param in_Sem the semaphore handle returned by myoSemCreate.
* @return
* MYO_SUCCESS; or
* an error number to indicate the error.
**/
MYOACCESSAPI
MyoError myoSemDestroy(MyoSem in_Sem);
/** @fn extern MyoError myoBarrierCreate(int in_Count, MyoBarrier *out_pBarrier)
* @brief Create a barrier and return the barrier handle.
*
* @param in_Count the number of threads that must call
* myoBarrierWait before any of them successfully return.
* @param out_pBarrier Used to store the handle of the created
* barrier.
* @return
* MYO_SUCCESS; or
* an error number to indicate the error.
**/
MYOACCESSAPI
MyoError myoBarrierCreate(int in_Count, MyoBarrier *out_pBarrier);
/** @fn extern MyoError myoBarrierWait(MyoBarrier in_Barrier)
* @brief The caller will block until the required number of threads
* have called myoBarrierWait with the same barrier handle.
*
* @param in_Barrier the barrier handle returned by myoBarrierCreate.
* @return
* MYO_SUCCESS; or
* an error number to indicate the error.
**/
MYOACCESSAPI
MyoError myoBarrierWait(MyoBarrier in_Barrier);
/** @fn extern MyoError myoBarrierDestroy(MyoBarrier in_Barrier)
* @brief Destroy the barrier.
*
* @param in_Barrier the barrier handle returned by myoBarrierCreate.
* @return
* MYO_SUCCESS; or
* an error number to indicate the error.
**/
MYOACCESSAPI
MyoError myoBarrierDestroy(MyoBarrier in_Barrier);
/*****************************************************************************
MISC APIs.
*****************************************************************************/
/**
* @cond INCLUDE_MYO_INTERNAL_DOCUMENTATION
**/
MYOACCESSAPI
int myoMyId();
/* int myoNumNodes() returns the number of peers, minus one, to
equal the number of cards in the system. */
MYOACCESSAPI
int myoNumNodes();
MYOACCESSAPI
unsigned long long myoTicks();
MYOACCESSAPI
unsigned long long myoWallTime();
MYOACCESSAPI
void myoStatOn();
MYOACCESSAPI
void myoStatOff();
/** @fn extern MyoError myoGetMemUsage(uint64 *out_memUsedMB)
* @brief Retrieves the amount of shared memory currently used.
* myoGetMemUsage() fills in out_memUsedMB when the pointer is not NULL.
*
* @param out_memUsedBytes, pointer to the current size shared memory used.
* @return
* MYO_SUCCESS; or
* an error number to indicate the error.
**/
MYOACCESSAPI
MyoError myoGetMemUsage(unsigned int *out_memUsedMB);
/** @fn extern MyoError myoHTimeOn(int in_On)
* @brief Toggle MYO HTime report feature on/off.
*
* @param in_On: 1 turn on MYO HTime report
* 0 turn off MYO HTime report
* @return
* MYO_SUCCESS; or
* an error number to indicate the error.
**/
extern MyoError myoHTimeOn(int in_On);
#ifdef __cplusplus
}
#endif
#endif
/**
* @endcond
**/
/*! @} */

View File

@ -0,0 +1,538 @@
/*
* Copyright 2010-2013 Intel Corporation.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, version 2.1.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* Disclaimer: The codes contained in these modules may be specific
* to the Intel Software Development Platform codenamed Knights Ferry,
* and the Intel product codenamed Knights Corner, and are not backward
* compatible with other Intel products. Additionally, Intel will NOT
* support the codes or instruction set in future products.
*
* Intel offers no warranty of any kind regarding the code. This code is
* licensed on an "AS IS" basis and Intel is not obligated to provide
* any support, assistance, installation, training, or other services
* of any kind. Intel is also not obligated to provide any updates,
* enhancements or extensions. Intel specifically disclaims any warranty
* of merchantability, non-infringement, fitness for any particular
* purpose, and any other warranty.
*
* Further, Intel disclaims all liability of any kind, including but
* not limited to liability for infringement of any proprietary rights,
* relating to the use of the code, even if Intel is notified of the
* possibility of such liability. Except as expressly stated in an Intel
* license agreement provided with this code and agreed upon with Intel,
* no license, express or implied, by estoppel or otherwise, to any
* intellectual property rights is granted herein.
*/
/**
Description:
Define APIs of MYO for compiler or pre-processor to transfer original programs.
*/
#ifndef _MYO_IMPL_H_
#define _MYO_IMPL_H_
/** @ingroup MYO
* @addtogroup MYOIMPL_API
@{
* @file myoimpl.h
*/
#ifdef __cplusplus
extern "C" {
#define EXTERN_C extern "C"
#else
#define EXTERN_C /* nothing */
#endif
# define MYOACCESSAPI /* nothing */
#ifdef DEFINE_ARENA_API_CILK_SHARED
#define CILK_SHARED _Cilk_shared
#else
#define CILK_SHARED /* nothing */
#endif
/* **************************************************************************** *\
APIs to enable functions being remotely called
\* **************************************************************************** */
typedef void *(*MyoiRemoteFuncType)(void *);
/** @fn extern MyoError myoiRemoteFuncRegister(MyoiRemoteFuncType in_pFuncAddr,
* const char *in_pFuncName)
* @brief Register a function so that it can be remotely called. This should be
* done in myoiUserInit or before calling myoiLibInit. After myoiLibInit,
* there will be a table on all peers, which contains the information for
* all remotely callable functions.
*
* @param in_pWrapFuncAddr address of the wrapper function.
* @param in_pFuncName name of the function.
* @return
* MYO_SUCCESS; or
* an error number to indicate the error.
**/
MYOACCESSAPI
MyoError myoiRemoteFuncRegister(MyoiRemoteFuncType in_pFuncAddr,
const char *in_pFuncName);
/** @fn extern MyoError myoiRemoteFuncLookupByName(char *in_pFuncName,
* MyoiRemoteFuncType *out_pWrapFuncAddr)
* @brief Get the address of the wrapper function by looking up the table
* by name. This API can be used when assigning a function pointer to
* remotely callable functions.
*
* @param in_pFuncName name of the function.
* @param out_pWrapFuncAddr address of the wrapper function.
* @return
* MYO_SUCCESS; or
* an error number to indicate the error.
**/
MYOACCESSAPI MyoError myoiRemoteFuncLookupByName(char *in_pFuncName,
MyoiRemoteFuncType *out_pWrapFuncAddr);
/** @fn extern MyoError myoiRemoteFuncLookupByAddr(MyoiRemoteFuncType
* in_pWrapFuncAddr,char **out_pFuncName)
* @brief Get the name of a remote function by looking up the table by
* the address. This API can be used when calling a remotely callable
* function by a function pointer.
*
* @param in_pWrapFuncAddr address of the function.
* @param out_pFuncName name of the function.
* @return
* MYO_SUCCESS; or
* an error number to indicate the error.
**/
MYOACCESSAPI MyoError myoiRemoteFuncLookupByAddr(MyoiRemoteFuncType in_pWrapFuncAddr,
char **out_pFuncName);
//! Host Side Shared Function Pointer Entry Struct
typedef struct {
//! Function Name
const char *funcName;
//! Function Address
void *funcAddr;
//! Local Thunk Address
void *localThunkAddr;
} MyoiHostSharedFptrEntry;
//! Target Side Shared Function Pointer Entry Struct
typedef struct {
//! Function Name
const char *funcName;
//! Function Address
void *funcAddr;
//! Wrap Function Address
void *wrapFuncAddr;
//! Locak Thunk Address
void *localThunkAddr;
} MyoiTargetSharedFptrEntry;
/**
* @cond INCLUDE_MYO_INTERNAL_DOCUMENTATION
* @fn extern MyoError myoiHostFptrTableRegister(void *in_pAddrOfFptrTable,
* int in_NumEntry, int in_Ordered)
* @brief Register shared functions on host side. A 16 byte thunk will be
* allocated for each function entry in non-coherent shared memory. The
* thunk will contain a jump instruction to the local version of the
* shared function, which is provided by the second item of the function
* entry. Also, the address of the thunk will be stored to the 3rd item
* of the function entry for Compiler usage.
*
* @param in_pAddrOfFptrTable start address of the shared function
* table, assuming it follows the format of MyoiHostSharedFptrEntry.
* @param in_NumEntry number of entry in the table.
* @param in_Ordered whether the table is ordered by function name.
* @return
* MYO_SUCCESS; or
* an error number to indicate the error.
**/
MYOACCESSAPI
MyoError myoiHostFptrTableRegister(
void *in_pAddrOfFptrTable, int in_NumEntry, int in_Ordered);
/** @fn extern MyoError myoiTargetFptrTableRegister(void *in_pAddrOfFptrTable,
* int in_NumEntry, int in_Ordered)
* @brief Register shared functions on target side. This function is the
* same as myoiHostFptrTableRegister, except it does not need to allocate
* thunks from non-coherent shared memory for each function entry, but
* instead looks up this information from a table retrieved from the
* Host side.
*
* @param in_pAddrOfFptrTable start address of the shared function
* table, assuming it follows the format of MyoiTargetSharedFptrEntry.
* @param in_NumEntry number of entry in the table.
* @param in_Ordered whether the table is ordered by function name.
* @return
* MYO_SUCCESS; or
* an error number to indicate the error.
**/
extern MyoError myoiTargetFptrTableRegister(
void *in_pAddrOfFptrTable, int in_NumEntry, int in_Ordered);
/**
* @endcond
**/
/* *************************************************************************** *\
APIs for remote function calls
\* *************************************************************************** */
typedef void * MyoiRFuncCallHandle;
/** @fn extern MyoiRFuncCallHandle myoiRemoteCall(char *in_pFuncName,
* void *in_pArgs, int in_deviceNum)
* @brief Call a remote callable function. If there are multiple arguments
* for the function, pack them to a shared buffer beforehand and take the
* address of the shared buffer as this function. After receiving the call
* requests from other peers, the arguments should be unpacked from the
* shared buffer before calling the target function. The shared buffer
* can also be used to store the return value of the function.
*
* @param in_pFuncName name of the function.
* @param in_pArgs address of the shared buffer.
* @return
* Handle used to check the result.
**/
MYOACCESSAPI
MyoiRFuncCallHandle myoiRemoteCall(const char *in_pFuncName, void *in_pArgs, int in_deviceNum);
/**
* @cond INCLUDE_MYO_INTERNAL_DOCUMENTATION
* @fn extern MyoError myoiRemoteThunkCall(void *in_funcThunkAddr, void *in_pArgs, int in_deviceNum)
* @brief Call a remote callable function. If there are multiple arguments for
* the function, pack them to a shared buffer beforehand and take the address
* of the shared buffer as this function. After receiving the call requests
* from other peers, the arguments should be unpacked from the shared buffer
* before calling the target function. The shared buffer can also be used to
* store the return value of the function.
*
* @param in_funcThunkAddr pointer to function thunk in the non-coherent
* shared memory.
* @param in_pArgs address of the shared buffer.
* @PARAM in_deviceNum: device ID (0-N-1) for the MIC device to run
* function call. -1 request causes MYO to schedule an available device.
* For RPC from device to host, in_deviceNum should always be -1.
* @return
* MYO_SUCCESS; or
* an error number to indicate the error.
**/
MYOACCESSAPI
MyoError myoiRemoteThunkCall(void *in_funcThunkAddr, void *in_pArgs, int in_deviceNum);
/**
* @endcond
**/
/** @fn extern MyoError myoiCheckResult(MyoiRFuncCallHandle in_Handle)
* @brief Check whether the remote call is done.
*
* @param in_Handle handle of the remote call.
* @return
* MYO_SUCCESS (done); or
* an error number to indicate the error.
**/
extern MyoError myoiCheckResult(MyoiRFuncCallHandle in_Handle);
/** @fn extern MyoError myoiGetResult(MyoiRFuncCallHandle in_Handle)
* @brief Wait till the remote call is done.
*
* @param in_Handle handle of the remote call.
* @return
* MYO_SUCCESS; or
* an error number to indicate the error.
**/
MYOACCESSAPI
MyoError myoiGetResult(MyoiRFuncCallHandle in_Handle);
/* **************************************************************************** *\
APIs related with shared variables.
\* **************************************************************************** */
/*
* It is Compiler's responsibility to make sure all shared variables
* located in shared memory space and have the same address in all sides.
* However, it is hard for Compiler to do this. So we propose a solution
* which is changing the definition of all shared variables and accessing
* them indirectly, and making sure all shared variables pointing
* to the same shared space on all sides. For example,
*
* "shared int a;" is changed to "shared int *a";
* Also all the accesses to "a" is change to "*a".
*
* We suppose the shared memory for each shared variable is allocated on
* host side by Compiler. For the upper example, Compiler can call:
*
* a = (shared int *) myoSharedMalloc(sizeof(shared int));
*
* Now the issue is how to make "a" on other sides also pointing to the
* same shared memory on other sides. We provide two methods to do this.
* They can be used in a hybrid way.
*/
/*
* The first method is calling myoiVarRegister for each shared variable
* on all sides in myoiUserInit. On host side, we will get a table containing
* a table containing the shared address and name of each shared variable.
* After calling myoiUserInit, we will propagate the table to other sides.
* On card side, after getting the table from host, myoiUserInit is called.
* When calling myoiVarRegister in myoiUserInit, we will make local pointer
* of each shared variable pointing to the same shared memory with the local
* pointer on host side of the same shared variable pointing to.
*/
/*
* The second method suppose that Compiler already have a table on all sides.
* On host side, the table contains the name and the shared address of each
* shared variable. On card side, the table contains the name of each shared
* variable and the address of the local pointer which will pointing to shared
* memory space.
*
* On host side, Compiler generates a call to myoiHostVarTablePropagate
* after initializing MYO runtime and making the host side table ready.
* On card side, Compiler uses myoiMicVarTableRegister to tell
* the runtime where the card side table is.
*
* Since there may be multiple libraries on card side for the same application,
* myoiHostVarTablePropagate and myoiMicVarTableRegister can be called multiple
* times and called simultaneously.
*
* Inside runtime, the local pointer of the same shared variable on all sides
* will be make sure pointing to the same shared space by using the information
* of the Compiler provided tables.
*/
/*
* Comipler knows the following two structures to make sure the var table
* has the following format.
*/
/*
* This is structure of the Shared var table entry. This table contains
* the shared address and name of each shared variable
*/
/** @fn extern MyoError myoiVarRegister(void *in_pAddrOfLocalPtrToShared, char *in_pSVarName)
* @brief Register shared variables. Call it on all sides in myoiUserInit.
* On host side, make sure calling it after allocating shared memory for
* the shared variables by calling myoSharedMalloc.
*
* @param in_pAddrOfLocalPtrToShared the address assigned by the compiler
* for the shared variable, which is the address of a local pointer,
* pointing to shared memory space.
* @param in_pSVarName name of shared variable.
* @return
* MYO_SUCCESS; or
* an error number to indicate the error.
**/
MYOACCESSAPI
MyoError myoiVarRegister(
void *in_pAddrOfLocalPtrToShared, const char *in_pSVarName);
/*
* Compiler knows the following two structures to make sure the var table
* has the following format.
*/
/**
* This is structure of the Shared var table entry. This table contains
* the shared address and name of each shared variable
**/
typedef struct {
//! Variable Name
const char *varName;
//! Shared Address
void *sharedAddr;
} MyoiSharedVarEntry;
//! Structure of the var table entry on host
typedef struct {
//! Variable Name
const char *varName;
//! Variable Size
int size;
//! Local pointer to Shared var
void *ptrToLocalPtrToShared;
} MyoiHostSharedVarEntry;
//! Structure of the var table entry on card
typedef struct {
//! Variable Name
const char *varName;
//! Local pointer to Shared var
void *ptrToLocalPtrToShared;
} MyoiMicSharedVarEntry;
/** @fn extern MyoError myoiHostVarTablePropagate(void *in_pAddrOfSVarTable, int in_NumEntry)
* @brief Send the host side var table to the card side. Card side will also
* have a copy of the host side var table after this propagation, although it
* is in an internal format different than the original host side var table,
* due to implementation convenience.
*
* @param in_pAddrOfSVarTable start address of the host side var table,
* assuming it follows the format of MyoiSharedVarEntry.
* @param in_NumEntry number of entry in the table.
* @return
* MYO_SUCCESS; or
* an error number to indicate the error.
**/
MYOACCESSAPI MyoError myoiHostVarTablePropagate(
void *in_pAddrOfSVarTable, int in_NumEntry);
/**
* @cond INCLUDE_MYO_INTERNAL_DOCUMENTATION
* @fn extern MyoError myoiMicVarTableRegister(void *in_pAddrOfSVarTable, int in_NumEntry)
* @brief Tell the runtime where the card side table is.
*
* @param in_pAddrOfSVarTable start address of the card side var
* table, assuming it follows the format of MyoiMicSharedVarEntry.
* @param in_NumEntry number of entry in the table.
* @return
* MYO_SUCCESS; or
* an error number to indicate the error.
**/
extern MyoError myoiMicVarTableRegister(
void *in_pAddrOfSVarTable, int in_NumEntry);
/**
* @endcond
**/
/** @fn MyoError myoiHostSharedMallocTableRegister(void *in_pAddrOfSVarTable, int in_NumEntry, int in_Ordered)
* @brief Allocate shared memory for all shared variables in the table.
* Also update local address of the shared variable with new shared address.
*
* @param in_pAddrOfSVarTable start address of the shared variable table,
* assuming it follows the format of MyoiHostSharedVarEntry.
* @param in_NumEntry number of entry in the table.
* @param in_Ordered whether the table ordered by name.
* @return
* MYO_SUCCESS; or
* an error number to indicate the error.
**/
MYOACCESSAPI
MyoError myoiHostSharedMallocTableRegister(
void *in_pAddrOfSVarTable, int in_NumEntry, int in_Ordered);
/** @fn extern MyoError myoiTargetSharedMallocTableRegister(void *in_pAddrOfSVarTable, int in_NumEntry, int in_Ordered)
* @brief Register the shared variables on the target side.
*
* @param in_pAddrOfSVarTable start address of the shared varaible table,
* assuming it follows the format of MyoiMicSharedVarEntry.
* @param in_NumEntry number of entry in the table.
* @param in_Ordered whether the table ordered by name.
* @return
* MYO_SUCCESS; or
* an error number to indicate the error.
**/
extern MyoError myoiTargetSharedMallocTableRegister(
void *in_pAddrOfSVarTable, int in_NumEntry, int in_Ordered);
/** @fn MyoError myoiLibInit(void * in_args, void (*userInitFunc))
* @brief Init entry of the MYO library responsible for initializing
* the runtime.
*
* @param in_args mechanism to pass arguments to the Initialization
* routine. The default value of NULL would mean the host is blocked
* on the completion of myoiLibInit() on all nodes. A subset of the
* installed cards can be intialized by passing an array of
* MyoiUserParams. For example, in a system with two cards, to run a
* MYO application only on the second card, intialize the array as
* follows:
* @code
* MyoiUserParams UserParas[64];
* UserParas[0].type = MYOI_USERPARAMS_DEVID;
* UserParas[0].nodeid = 2;
* UserParas[1].type = MYOI_USERPARAMS_LAST_MSG;
* if(MYO_SUCCESS != myoiLibInit(&UserParas, (void*)&myoiUserInit)) {
* printf("Failed to initialize MYO runtime\n");
* return -1;
* }
* @endcode
* This intialization is required only in the client/host side
* of the application. The server/card side executable should be
* executed only on the second card in this case.
*
* @param userInitFunc Shared variables and remote funtions are
* registered in this routine, which is called by the runtime during
* library initialization.
* @return
* MYO_SUCCESS;
* MYO_ERROR;
**/
MYOACCESSAPI
MyoError myoiLibInit(void * in_args, void *userInitFunc /*userInitFunc must be: MyoError (*userInitFunc)(void) */);
/** @fn void myoiLibFini()
* @brief Finalize the MYO library, all resources held by the runtime are
* released by this routine.
*
* @return
**/
MYOACCESSAPI
void myoiLibFini();
/* *************************************************************************** *\
APIs to set shared memory space consistent/non-consistent.
\* *************************************************************************** */
/** @fn extern MyoError myoiSetMemNonConsistent(void *in_pAddr, size_t in_Size)
* @brief Set part of the shared memory space to be non-consistent, which
* means that the consistency of this part of shared memory space does not
* need to be maintained between HOST and cards.
*
* @param in_pAddr The start address of the specified shared memory space;
* @param in_Size The size of the specified shared memory space;
* @return
* MYO_SUCCESS; or
* an error number to indicate the error.
**/
MYOACCESSAPI
MyoError myoiSetMemNonConsistent(void *in_pAddr, size_t in_Size);
/** @fn extern MyoError myoiSetMemConsistent(void *in_pAddr, size_t in_Size)
* @brief Set part of the shared memory space to be consistent, which
* means that the consistency of this part of shared memory space needs
* to be maintained between HOST and cards.
*
* @param in_pAddr The start address of the specified shared
* memory space.
* @param in_size The size of the specified shared memory space.
* @return
* MYO_SUCCESS; or
* an error number to indicate the error.
**/
MYOACCESSAPI
MyoError myoiSetMemConsistent(void *in_pAddr, size_t in_Size);
/* A collection of external data symbols */
EXTERN_C MYOACCESSAPI unsigned int myoiMyId; /* MYO_MYID if on accelerators */
EXTERN_C MYOACCESSAPI volatile int myoiInitFlag;
//! Structure of the array element that is passed to myoiLibInit() to initialize a subset of the available cards.
typedef struct{
//!type = MYOI_USERPARAMS_DEVID for each element in the array except the last element ; type = MYOI_USERPARAMS_LAST_MSG for the last element in the array.
int type;
//!nodeid refers to the card index.
int nodeid;
}MyoiUserParams;
#define MYOI_USERPARAMS_DEVID 1
#define MYOI_USERPARAMS_LAST_MSG -1
#ifdef __cplusplus
}
#endif
#endif // _MYO_IMPL_H_
/*! @} */

View File

@ -0,0 +1,116 @@
/*
* Copyright 2010-2013 Intel Corporation.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, version 2.1.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* Disclaimer: The codes contained in these modules may be specific
* to the Intel Software Development Platform codenamed Knights Ferry,
* and the Intel product codenamed Knights Corner, and are not backward
* compatible with other Intel products. Additionally, Intel will NOT
* support the codes or instruction set in future products.
*
* Intel offers no warranty of any kind regarding the code. This code is
* licensed on an "AS IS" basis and Intel is not obligated to provide
* any support, assistance, installation, training, or other services
* of any kind. Intel is also not obligated to provide any updates,
* enhancements or extensions. Intel specifically disclaims any warranty
* of merchantability, non-infringement, fitness for any particular
* purpose, and any other warranty.
*
* Further, Intel disclaims all liability of any kind, including but
* not limited to liability for infringement of any proprietary rights,
* relating to the use of the code, even if Intel is notified of the
* possibility of such liability. Except as expressly stated in an Intel
* license agreement provided with this code and agreed upon with Intel,
* no license, express or implied, by estoppel or otherwise, to any
* intellectual property rights is granted herein.
*/
/**
Description: Define the types used by APIs of MYO programming.
*/
#ifndef _MYO_TYPES_H_
#define _MYO_TYPES_H_
#include <string.h> /* For size_t */
/** @ingroup MYO
* @addtogroup MYOTYPES
@{
* @file myotypes.h
*/
#ifdef __cplusplus
extern "C" {
#endif
/*! MYO Status
*/
typedef enum {
MYO_SUCCESS = 0, /*!< Success */
MYO_ERROR, /*!< Error */
MYO_INVALID_ENV, /*!< Invalid Env */
MYO_INVALID_ARGUMENT, /*!< Invalid Argument */
MYO_NOT_INITIALIZED, /*!< Not Initialized */
MYO_ALREADY_FINALIZED,/*!< Already Finalized */
MYO_BUF_ERROR, /*!< Buffer Error */
MYO_OUT_OF_RANGE, /*!< Out of Range */
MYO_OUT_OF_MEMORY, /*!< Out of Memory */
MYO_ALREADY_EXISTS, /*!< Already Exists */
MYO_EOF, /*!< EOF */
} MyoError;
/*! Arena Ownership */
typedef enum {
MYO_ARENA_MINE = 1, /*!< Arena MINE Ownership */
MYO_ARENA_OURS, /*!< Arena OURS Ownership */
} MyoOwnershipType;
/*************************************************************
* define the property of MYO Arena
***********************************************************/
#define MYO_CONSISTENCY_MODE 0x3
#define MYO_RELEASE_CONSISTENCY 0x1
#define MYO_STRONG_RELEASE_CONSISTENCY 0x2
#define MYO_STRONG_CONSISTENCY 0x3
#define MYO_UPDATE_ON_DEMAND 0x8
#define MYO_UPDATE_ON_ACQUIRE 0x10
#define MYO_RECORD_DIRTY 0x20
#define MYO_NOT_RECORD_DIRTY 0x40
#define MYO_ONE_VERSION 0x80
#define MYO_MULTI_VERSIONS 0x100
#define MYO_CONSISTENCY 0x200
#define MYO_NO_CONSISTENCY 0x400
#define MYO_HOST_TO_DEVICE 0x800
#define MYO_DEVICE_TO_HOST 0x1000
#define MYO_HYBRID_UPDATE 0x2000
typedef unsigned int MyoArena;
typedef void * MyoMutex;
typedef void * MyoSem;
typedef void * MyoBarrier;
#ifdef __cplusplus
}
#endif
#endif // _MYO_TYPES_H_
/*! @} */

View File

@ -0,0 +1,3 @@
# This spec file is read by gcc when linking. It is used to specify the
# standard libraries we need in order to link with liboffloadmic_host.
*link_offloadmic_host: @link_offloadmic_host@

View File

@ -0,0 +1,3 @@
# This spec file is read by gcc when linking. It is used to specify the
# standard libraries we need in order to link with liboffloadmic_target.
*link_offloadmic_target: @link_offloadmic_target@

View File

@ -0,0 +1,366 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#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));
if (res == NULL)
LIBOFFLOAD_ERROR(c_malloc);
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 transfered 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

View File

@ -0,0 +1,116 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#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 transfered 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 transfered 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

View File

@ -0,0 +1,370 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// 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

View File

@ -0,0 +1,138 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// The interface betwen 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

View File

@ -0,0 +1,150 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// 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

View File

@ -0,0 +1,94 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
//The interface betwen 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

View File

@ -0,0 +1,343 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#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);
// initalize 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;
}

View File

@ -0,0 +1,153 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*! \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

View File

@ -0,0 +1,64 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#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");
}

View File

@ -0,0 +1,70 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*! \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

View File

@ -0,0 +1,153 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#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));
if (res == NULL)
LIBOFFLOAD_ERROR(c_malloc);
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

View File

@ -0,0 +1,83 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#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

View File

@ -0,0 +1,140 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef COI_COMMON_H_INCLUDED
#define COI_COMMON_H_INCLUDED
#include <common/COIMacros_common.h>
#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 <assert.h>
#include <dirent.h>
#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
/* Environment variable for path to 'target' files. */
#define MIC_DIR_ENV "OFFLOAD_MIC_DIR"
/* Environment variable for engine index. */
#define MIC_INDEX_ENV "OFFLOAD_MIC_INDEX"
/* Environment variable for target executable run command. */
#define OFFLOAD_EMUL_RUN_ENV "OFFLOAD_EMUL_RUN"
/* Environment variable for number ok KNC devices. */
#define OFFLOAD_EMUL_KNC_NUM_ENV "OFFLOAD_EMUL_KNC_NUM"
/* Path to engine directory. */
#define ENGINE_PATH "/tmp/offload_XXXXXX"
/* Relative path to directory with pipes. */
#define PIPES_PATH "/pipes"
/* Relative path to target-to-host pipe. */
#define PIPE_HOST_PATH PIPES_PATH"/host"
/* Relative path to host-to-target pipe. */
#define PIPE_TARGET_PATH PIPES_PATH"/target"
/* Non-numerical part of shared memory file name. */
#define SHM_NAME "/offload_shm_"
/* Use secure getenv if it's supported. */
#ifdef HAVE_SECURE_GETENV
#define getenv(x) secure_getenv(x)
#elif HAVE___SECURE_GETENV
#define getenv(x) __secure_getenv(x)
#endif
/* Wrapper for malloc. */
#define MALLOC(type, ptr, size) \
{ \
type p = (type) malloc (size); \
if (p == NULL) \
COIERROR ("Cannot allocate memory."); \
ptr = p; \
}
/* Wrapper for strdup. */
#define STRDUP(ptr, str) \
{ \
char *p = strdup (str); \
if (p == NULL) \
COIERROR ("Cannot allocate memory."); \
ptr = p; \
}
/* Wrapper for pipe reading. */
#define READ(pipe, ptr, size) \
{ \
int s = (int) size; \
if (read (pipe, ptr, s) != s) \
COIERROR ("Cannot read from pipe."); \
}
/* Wrapper for pipe writing. */
#define WRITE(pipe, ptr, size) \
{ \
int s = (int) size; \
if (write (pipe, ptr, s) != s) \
COIERROR ("Cannot write in pipe."); \
}
/* Command codes enum. */
typedef enum
{
CMD_BUFFER_COPY,
CMD_BUFFER_MAP,
CMD_BUFFER_UNMAP,
CMD_GET_FUNCTION_HANDLE,
CMD_OPEN_LIBRARY,
CMD_RUN_FUNCTION,
CMD_SHUTDOWN
} cmd_t;
#endif // COI_COMMON_H_INCLUDED

View File

@ -0,0 +1,330 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "coi_device.h"
#include "coi_version_asm.h"
#define CYCLE_FREQUENCY 1000000000
static uint32_t engine_index;
extern "C"
{
COIRESULT
SYMBOL_VERSION (COIBufferAddRef, 1) (void *ptr)
{
COITRACE ("COIBufferAddRef");
/* Looks like we have nothing to do here. */
return COI_SUCCESS;
}
COIRESULT
SYMBOL_VERSION (COIBufferReleaseRef, 1) (void *ptr)
{
COITRACE ("COIBufferReleaseRef");
/* Looks like we have nothing to do here. */
return COI_SUCCESS;
}
COIRESULT
SYMBOL_VERSION (COIEngineGetIndex, 1) (COI_ISA_TYPE *type,
uint32_t *index)
{
COITRACE ("COIEngineGetIndex");
/* type is not used in liboffload. */
*index = engine_index;
return COI_SUCCESS;
}
COIRESULT
SYMBOL_VERSION (COIPipelineStartExecutingRunFunctions, 1) ()
{
COITRACE ("COIPipelineStartExecutingRunFunctions");
/* Looks like we have nothing to do here. */
return COI_SUCCESS;
}
COIRESULT
SYMBOL_VERSION (COIProcessWaitForShutdown, 1) ()
{
COITRACE ("COIProcessWaitForShutdown");
char *mic_dir = getenv (MIC_DIR_ENV);
char *mic_index = getenv (MIC_INDEX_ENV);
char *pipe_host_path, *pipe_target_path;
int pipe_host, pipe_target;
int cmd_len;
pid_t ppid = getppid ();
cmd_t cmd;
assert (mic_dir != NULL && mic_index != NULL);
/* Get engine index. */
engine_index = atoi (mic_index);
/* Open pipes. */
MALLOC (char *, pipe_host_path,
strlen (PIPE_HOST_PATH) + strlen (mic_dir) + 1);
MALLOC (char *, pipe_target_path,
strlen (PIPE_TARGET_PATH) + strlen (mic_dir) + 1);
sprintf (pipe_host_path, "%s"PIPE_HOST_PATH, mic_dir);
sprintf (pipe_target_path, "%s"PIPE_TARGET_PATH, mic_dir);
pipe_host = open (pipe_host_path, O_CLOEXEC | O_WRONLY);
if (pipe_host < 0)
COIERROR ("Cannot open target-to-host pipe.");
pipe_target = open (pipe_target_path, O_CLOEXEC | O_RDONLY);
if (pipe_target < 0)
COIERROR ("Cannot open host-to-target pipe.");
/* Clean up. */
free (pipe_host_path);
free (pipe_target_path);
/* Handler. */
while (1)
{
/* Read and execute command. */
cmd = CMD_SHUTDOWN;
cmd_len = read (pipe_target, &cmd, sizeof (cmd_t));
if (cmd_len != sizeof (cmd_t) && cmd_len != 0)
COIERROR ("Cannot read from pipe.");
switch (cmd)
{
case CMD_BUFFER_COPY:
{
uint64_t len;
void *dest, *source;
/* Receive data from host. */
READ (pipe_target, &dest, sizeof (void *));
READ (pipe_target, &source, sizeof (void *));
READ (pipe_target, &len, sizeof (uint64_t));
/* Copy. */
memcpy (dest, source, len);
/* Notify host about completion. */
WRITE (pipe_host, &cmd, sizeof (cmd_t));
break;
}
case CMD_BUFFER_MAP:
{
char *name;
int fd;
size_t len;
uint64_t buffer_len;
void *buffer;
/* Receive data from host. */
READ (pipe_target, &len, sizeof (size_t));
MALLOC (char *, name, len);
READ (pipe_target, name, len);
READ (pipe_target, &buffer_len, sizeof (uint64_t));
/* Open shared memory. */
fd = shm_open (name, O_CLOEXEC | O_RDWR, S_IRUSR | S_IWUSR);
if (fd < 0)
COIERROR ("Cannot open shared memory.");
/* Map shared memory. */
buffer = mmap (NULL, buffer_len, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, 0);
if (buffer == NULL)
COIERROR ("Cannot map shared memory.");
/* Send data to host. */
WRITE (pipe_host, &fd, sizeof (int));
WRITE (pipe_host, &buffer, sizeof (void *));
/* Clean up. */
free (name);
break;
}
case CMD_BUFFER_UNMAP:
{
int fd;
uint64_t buffer_len;
void *buffer;
/* Receive data from host. */
READ (pipe_target, &fd, sizeof (int));
READ (pipe_target, &buffer, sizeof (void *));
READ (pipe_target, &buffer_len, sizeof (uint64_t));
/* Unmap buffer. */
if (munmap (buffer, buffer_len) < 0)
COIERROR ("Cannot unmap shared memory.");
/* Close shared memory. */
if (close (fd) < 0)
COIERROR ("Cannot close shared memory file.");
/* Notify host about completion. */
WRITE (pipe_host, &cmd, sizeof (cmd_t));
break;
}
case CMD_GET_FUNCTION_HANDLE:
{
char *name;
size_t len;
void *ptr;
/* Receive data from host. */
READ (pipe_target, &len, sizeof (size_t));
MALLOC (char *, name, len);
READ (pipe_target, name, len);
/* Find function. */
ptr = dlsym (RTLD_DEFAULT, name);
if (ptr == NULL)
COIERROR ("Cannot find symbol %s.", name);
/* Send data to host. */
WRITE (pipe_host, &ptr, sizeof (void *));
/* Clean up. */
free (name);
break;
}
case CMD_OPEN_LIBRARY:
{
char *lib_path;
size_t len;
/* Receive data from host. */
READ (pipe_target, &len, sizeof (size_t));
MALLOC (char *, lib_path, len);
READ (pipe_target, lib_path, len);
/* Open library. */
if (dlopen (lib_path, RTLD_LAZY | RTLD_GLOBAL) == 0)
COIERROR ("Cannot load %s: %s", lib_path, dlerror ());
/* Clean up. */
free (lib_path);
break;
}
case CMD_RUN_FUNCTION:
{
uint16_t misc_data_len, return_data_len;
uint32_t buffer_count, i;
uint64_t *buffers_len, size;
void *ptr;
void **buffers, *misc_data, *return_data;
void (*func) (uint32_t, void **, uint64_t *,
void *, uint16_t, void*, uint16_t);
/* Receive data from host. */
READ (pipe_target, &func, sizeof (void *));
READ (pipe_target, &buffer_count, sizeof (uint32_t));
MALLOC (void **, buffers, buffer_count * sizeof (void *));
MALLOC (uint64_t *, buffers_len, buffer_count * sizeof (uint64_t));
for (i = 0; i < buffer_count; i++)
{
READ (pipe_target, &(buffers_len[i]), sizeof (uint64_t));
READ (pipe_target, &(buffers[i]), sizeof (void *));
}
READ (pipe_target, &misc_data_len, sizeof (uint16_t));
if (misc_data_len > 0)
{
MALLOC (void *, misc_data, misc_data_len);
READ (pipe_target, misc_data, misc_data_len);
}
READ (pipe_target, &return_data_len, sizeof (uint16_t));
if (return_data_len > 0)
MALLOC (void *, return_data, return_data_len);
/* Run function. */
func (buffer_count, buffers, buffers_len, misc_data,
misc_data_len, return_data, return_data_len);
/* Send data to host if any or just send notification. */
WRITE (pipe_host, return_data_len > 0 ? return_data : &cmd,
return_data_len > 0 ? return_data_len : sizeof (cmd_t));
/* Clean up. */
free (buffers);
free (buffers_len);
if (misc_data_len > 0)
free (misc_data);
if (return_data_len > 0)
free (return_data);
break;
}
case CMD_SHUTDOWN:
if (close (pipe_host) < 0)
COIERROR ("Cannot close target-to-host pipe.");
if (close (pipe_target) < 0)
COIERROR ("Cannot close host-to-target pipe.");
return COI_SUCCESS;
default:
COIERROR ("Unrecognizable command from host.");
}
}
return COI_ERROR;
}
uint64_t
SYMBOL_VERSION (COIPerfGetCycleFrequency, 1) ()
{
COITRACE ("COIPerfGetCycleFrequency");
return (uint64_t) CYCLE_FREQUENCY;
}
} // extern "C"

View File

@ -0,0 +1,56 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef COI_DEVICE_H_INCLUDED
#define COI_DEVICE_H_INCLUDED
#include "coi_common.h"
#define COIERROR(...) \
{ \
fprintf (stderr, "COI ERROR - TARGET: "); \
fprintf (stderr, __VA_ARGS__); \
fprintf (stderr, "\n"); \
perror (NULL); \
return COI_ERROR; \
}
#ifdef DEBUG
#define COITRACE(...) \
{ \
fprintf (stderr, "COI TRACE - TARGET: "); \
fprintf (stderr, __VA_ARGS__); \
fprintf (stderr, "\n"); \
}
#else
#define COITRACE(...) {}
#endif
#endif // COI_DEVICE_H_INCLUDED

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,55 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef COI_HOST_H_INCLUDED
#define COI_HOST_H_INCLUDED
#include "coi_common.h"
#define COIERROR(...) \
{ \
fprintf (stderr, "COI ERROR - HOST: "); \
fprintf (stderr, __VA_ARGS__); \
fprintf (stderr, "\n"); \
perror (NULL); \
return COI_ERROR; \
}
#ifdef DEBUG
#define COITRACE(...) \
{ \
fprintf (stderr, "COI TRACE - HOST: "); \
fprintf (stderr, __VA_ARGS__); \
fprintf (stderr, "\n"); \
}
#else
#define COITRACE(...) {}
#endif
#endif // COI_HOST_H_INCLUDED

View File

@ -0,0 +1,68 @@
/*
* Copyright 2010-2013 Intel Corporation.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, version 2.1.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* Disclaimer: The codes contained in these modules may be specific
* to the Intel Software Development Platform codenamed Knights Ferry,
* and the Intel product codenamed Knights Corner, and are not backward
* compatible with other Intel products. Additionally, Intel will NOT
* support the codes or instruction set in future products.
*
* Intel offers no warranty of any kind regarding the code. This code is
* licensed on an "AS IS" basis and Intel is not obligated to provide
* any support, assistance, installation, training, or other services
* of any kind. Intel is also not obligated to provide any updates,
* enhancements or extensions. Intel specifically disclaims any warranty
* of merchantability, non-infringement, fitness for any particular
* purpose, and any other warranty.
*
* Further, Intel disclaims all liability of any kind, including but
* not limited to liability for infringement of any proprietary rights,
* relating to the use of the code, even if Intel is notified of the
* possibility of such liability. Except as expressly stated in an Intel
* license agreement provided with this code and agreed upon with Intel,
* no license, express or implied, by estoppel or otherwise, to any
* intellectual property rights is granted herein.
*/
__asm__ (".symver COIBufferAddRef1,COIBufferAddRef@@COI_1.0");
__asm__ (".symver COIBufferCopy1,COIBufferCopy@@COI_1.0");
__asm__ (".symver COIBufferCreate1,COIBufferCreate@@COI_1.0");
__asm__ (".symver COIBufferCreateFromMemory1,COIBufferCreateFromMemory@@COI_1.0");
__asm__ (".symver COIBufferDestroy1,COIBufferDestroy@@COI_1.0");
__asm__ (".symver COIBufferGetSinkAddress1,COIBufferGetSinkAddress@@COI_1.0");
__asm__ (".symver COIBufferMap1,COIBufferMap@@COI_1.0");
__asm__ (".symver COIBufferRead1,COIBufferRead@@COI_1.0");
__asm__ (".symver COIBufferReleaseRef1,COIBufferReleaseRef@@COI_1.0");
__asm__ (".symver COIBufferSetState1,COIBufferSetState@@COI_1.0");
__asm__ (".symver COIBufferUnmap1,COIBufferUnmap@@COI_1.0");
__asm__ (".symver COIBufferWrite1,COIBufferWrite@@COI_1.0");
__asm__ (".symver COIEngineGetCount1,COIEngineGetCount@@COI_1.0");
__asm__ (".symver COIEngineGetHandle1,COIEngineGetHandle@@COI_1.0");
__asm__ (".symver COIEngineGetIndex1,COIEngineGetIndex@@COI_1.0");
__asm__ (".symver COIEventWait1,COIEventWait@@COI_1.0");
__asm__ (".symver COIPerfGetCycleFrequency1,COIPerfGetCycleFrequency@@COI_1.0");
__asm__ (".symver COIPipelineCreate1,COIPipelineCreate@@COI_1.0");
__asm__ (".symver COIPipelineDestroy1,COIPipelineDestroy@@COI_1.0");
__asm__ (".symver COIPipelineRunFunction1,COIPipelineRunFunction@@COI_1.0");
__asm__ (".symver COIPipelineStartExecutingRunFunctions1,COIPipelineStartExecutingRunFunctions@@COI_1.0");
__asm__ (".symver COIProcessCreateFromMemory1,COIProcessCreateFromMemory@@COI_1.0");
__asm__ (".symver COIProcessDestroy1,COIProcessDestroy@@COI_1.0");
__asm__ (".symver COIProcessGetFunctionHandles1,COIProcessGetFunctionHandles@@COI_1.0");
__asm__ (".symver COIProcessLoadLibraryFromMemory2,COIProcessLoadLibraryFromMemory@COI_2.0");
__asm__ (".symver COIProcessRegisterLibraries1,COIProcessRegisterLibraries@@COI_1.0");
__asm__ (".symver COIProcessWaitForShutdown1,COIProcessWaitForShutdown@@COI_1.0");

View File

@ -0,0 +1,79 @@
/*
* Copyright 2010-2013 Intel Corporation.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, version 2.1.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* Disclaimer: The codes contained in these modules may be specific
* to the Intel Software Development Platform codenamed Knights Ferry,
* and the Intel product codenamed Knights Corner, and are not backward
* compatible with other Intel products. Additionally, Intel will NOT
* support the codes or instruction set in future products.
*
* Intel offers no warranty of any kind regarding the code. This code is
* licensed on an "AS IS" basis and Intel is not obligated to provide
* any support, assistance, installation, training, or other services
* of any kind. Intel is also not obligated to provide any updates,
* enhancements or extensions. Intel specifically disclaims any warranty
* of merchantability, non-infringement, fitness for any particular
* purpose, and any other warranty.
*
* Further, Intel disclaims all liability of any kind, including but
* not limited to liability for infringement of any proprietary rights,
* relating to the use of the code, even if Intel is notified of the
* possibility of such liability. Except as expressly stated in an Intel
* license agreement provided with this code and agreed upon with Intel,
* no license, express or implied, by estoppel or otherwise, to any
* intellectual property rights is granted herein.
*/
COI_1.0
{
global:
COIBufferAddRef;
COIBufferCopy;
COIBufferCreate;
COIBufferCreateFromMemory;
COIBufferDestroy;
COIBufferGetSinkAddress;
COIBufferMap;
COIBufferRead;
COIBufferReleaseRef;
COIBufferSetState;
COIBufferUnmap;
COIBufferWrite;
COIEngineGetCount;
COIEngineGetHandle;
COIEngineGetIndex;
COIEventWait;
COIPerfGetCycleFrequency;
COIPipelineCreate;
COIPipelineDestroy;
COIPipelineRunFunction;
COIPipelineStartExecutingRunFunctions;
COIProcessCreateFromMemory;
COIProcessDestroy;
COIProcessGetFunctionHandles;
COIProcessLoadLibraryFromMemory;
COIProcessRegisterLibraries;
COIProcessWaitForShutdown;
local:
*;
};
COI_2.0
{
} COI_1.0;

View File

@ -0,0 +1,31 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* We don't need to implement any MYO client functions. */

View File

@ -0,0 +1,159 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "myo_service.h"
#include "myo_version_asm.h"
extern "C"
{
MYOACCESSAPI MyoError
SYMBOL_VERSION (myoAcquire, 1) ()
{
MYOTRACE ("myoAcquire");
assert (false);
return MYO_ERROR;
}
MYOACCESSAPI MyoError
SYMBOL_VERSION (myoRelease, 1) ()
{
MYOTRACE ("myoRelease");
assert (false);
return MYO_ERROR;
}
MYOACCESSAPI void
SYMBOL_VERSION (myoSharedAlignedFree, 1) (void *ptr)
{
MYOTRACE ("myoSharedAlignedFree");
assert (false);
}
MYOACCESSAPI void*
SYMBOL_VERSION (myoSharedAlignedMalloc, 1) (size_t size,
size_t alignment)
{
MYOTRACE ("myoSharedAlignedMalloc");
assert (false);
return 0;
}
MYOACCESSAPI void
SYMBOL_VERSION (myoSharedFree, 1) (void *ptr)
{
MYOTRACE ("myoSharedFree");
assert (false);
}
MYOACCESSAPI void*
SYMBOL_VERSION (myoSharedMalloc, 1) (size_t size)
{
MYOTRACE ("myoSharedMalloc");
assert (false);
return 0;
}
MYOACCESSAPI MyoError
SYMBOL_VERSION (myoiLibInit, 1) (void *args,
void *init_func)
{
MYOTRACE ("myoiLibInit");
assert (false);
return MYO_ERROR;
}
MYOACCESSAPI void
SYMBOL_VERSION (myoiLibFini, 1) ()
{
MYOTRACE ("myoiLibFini");
assert (false);
}
MyoError
SYMBOL_VERSION (myoiMicVarTableRegister, 1) (void *table,
int num)
{
MYOTRACE ("myoiMicVarTableRegister");
assert (false);
return MYO_ERROR;
}
MYOACCESSAPI MyoError
SYMBOL_VERSION (myoiRemoteFuncRegister, 1) (MyoiRemoteFuncType type,
const char *name)
{
MYOTRACE ("myoiRemoteFuncRegister");
/* Looks like we have nothing to do here. */
return MYO_SUCCESS;
}
MyoError
SYMBOL_VERSION (myoiTargetFptrTableRegister, 1) (void *table,
int num,
int ordered)
{
MYOTRACE ("myoiTargetFptrTableRegister");
assert (false);
return MYO_ERROR;
}
} // extern "C"

View File

@ -0,0 +1,63 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef MYO_SERVICE_H_INCLUDED
#define MYO_SERVICE_H_INCLUDED
#include <myo.h>
#include <myoimpl.h>
#include <myotypes.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#define SYMBOL_VERSION(SYMBOL,VERSION) SYMBOL ## VERSION
#define MYOERROR(...) \
{ \
fprintf (stderr, "MYO ERROR - TARGET: "); \
fprintf (stderr, __VA_ARGS__); \
fprintf (stderr, "\n"); \
perror (NULL); \
return MYO_ERROR; \
}
#ifdef DEBUG
#define MYOTRACE(...) \
{ \
fprintf (stderr, "MYO TRACE - TARGET: "); \
fprintf (stderr, __VA_ARGS__); \
fprintf (stderr, "\n"); \
}
#else
#define MYOTRACE(...) {}
#endif
#endif // MYO_SERVICE_H_INCLUDED

View File

@ -0,0 +1,53 @@
/*
* Copyright 2010-2013 Intel Corporation.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, version 2.1.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* Disclaimer: The codes contained in these modules may be specific
* to the Intel Software Development Platform codenamed Knights Ferry,
* and the Intel product codenamed Knights Corner, and are not backward
* compatible with other Intel products. Additionally, Intel will NOT
* support the codes or instruction set in future products.
*
* Intel offers no warranty of any kind regarding the code. This code is
* licensed on an "AS IS" basis and Intel is not obligated to provide
* any support, assistance, installation, training, or other services
* of any kind. Intel is also not obligated to provide any updates,
* enhancements or extensions. Intel specifically disclaims any warranty
* of merchantability, non-infringement, fitness for any particular
* purpose, and any other warranty.
*
* Further, Intel disclaims all liability of any kind, including but
* not limited to liability for infringement of any proprietary rights,
* relating to the use of the code, even if Intel is notified of the
* possibility of such liability. Except as expressly stated in an Intel
* license agreement provided with this code and agreed upon with Intel,
* no license, express or implied, by estoppel or otherwise, to any
* intellectual property rights is granted herein.
*/
__asm__ (".symver myoAcquire1,myoAcquire@@MYO_1.0");
__asm__ (".symver myoRelease1,myoRelease@@MYO_1.0");
__asm__ (".symver myoSharedAlignedFree1,myoSharedAlignedFree@@MYO_1.0");
__asm__ (".symver myoSharedAlignedMalloc1,myoSharedAlignedMalloc@@MYO_1.0");
__asm__ (".symver myoSharedFree1,myoSharedFree@@MYO_1.0");
__asm__ (".symver myoSharedMalloc1,myoSharedMalloc@@MYO_1.0");
__asm__ (".symver myoiLibInit1,myoiLibInit@@MYO_1.0");
__asm__ (".symver myoiLibFini1,myoiLibFini@@MYO_1.0");
__asm__ (".symver myoiMicVarTableRegister1,myoiMicVarTableRegister@@MYO_1.0");
__asm__ (".symver myoiRemoteFuncRegister1,myoiRemoteFuncRegister@@MYO_1.0");
__asm__ (".symver myoiTargetFptrTableRegister1,myoiTargetFptrTableRegister@@MYO_1.0");

View File

@ -0,0 +1,60 @@
/*
* Copyright 2010-2013 Intel Corporation.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, version 2.1.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301 USA.
*
* Disclaimer: The codes contained in these modules may be specific
* to the Intel Software Development Platform codenamed Knights Ferry,
* and the Intel product codenamed Knights Corner, and are not backward
* compatible with other Intel products. Additionally, Intel will NOT
* support the codes or instruction set in future products.
*
* Intel offers no warranty of any kind regarding the code. This code is
* licensed on an "AS IS" basis and Intel is not obligated to provide
* any support, assistance, installation, training, or other services
* of any kind. Intel is also not obligated to provide any updates,
* enhancements or extensions. Intel specifically disclaims any warranty
* of merchantability, non-infringement, fitness for any particular
* purpose, and any other warranty.
*
* Further, Intel disclaims all liability of any kind, including but
* not limited to liability for infringement of any proprietary rights,
* relating to the use of the code, even if Intel is notified of the
* possibility of such liability. Except as expressly stated in an Intel
* license agreement provided with this code and agreed upon with Intel,
* no license, express or implied, by estoppel or otherwise, to any
* intellectual property rights is granted herein.
*/
MYO_1.0
{
global:
myoAcquire;
myoRelease;
myoSharedAlignedFree;
myoSharedAlignedMalloc;
myoSharedFree;
myoSharedMalloc;
myoiLibInit;
myoiLibFini;
myoiMicVarTableRegister;
myoiRemoteFuncRegister;
myoiTargetFptrTableRegister;
local:
*;
};

View File

@ -0,0 +1,475 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#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_malloc:
write_message(stderr, msg_c_malloc, 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();
}
}

View File

@ -0,0 +1,297 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#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_malloc,
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)

View File

@ -0,0 +1,67 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.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, va_list args_p) {
va_list args;
char buf[1024];
va_copy(args, args_p);
buf[0] = '\n';
vsnprintf(buf + 1, sizeof(buf) - 2,
MESSAGE_TABLE_NAME[ msgCode ], args);
strcat(buf, "\n");
va_end(args);
fputs(buf, file);
fflush(file);
}
char const *offload_get_message_str(int msgCode) {
return MESSAGE_TABLE_NAME[ msgCode ];
}

View File

@ -0,0 +1,348 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// 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_malloc,
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 = 153,
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_malloc */ "offload error: memory allocation failed",
/* 6 msg_c_offload_malloc */ "offload error: memory allocation failed (requested=%lld bytes, align %lld)",
/* 7 msg_c_offload1 */ "offload error: device %d does not have a pending signal for wait(%p)",
/* 8 msg_c_unknown_var_type */ "offload error: unknown variable type %d",
/* 9 msg_c_invalid_env_var_value */ "offload warning: ignoring invalid value specified for %s",
/* 10 msg_c_invalid_env_var_int_value */ "offload warning: specify an integer value for %s",
/* 11 msg_c_invalid_env_report_value */ "offload warning: ignoring %s setting; use a value in range 1-3",
/* 12 msg_c_offload_signaled1 */ "offload error: invalid device number %d specified in _Offload_signaled",
/* 13 msg_c_offload_signaled2 */ "offload error: invalid signal %p specified for _Offload_signaled",
/* 14 msg_c_myowrapper_checkresult */ "offload error: %s failed with error %d",
/* 15 msg_c_myotarget_checkresult */ "offload error: %s failed with error %d",
/* 16 msg_c_offload_descriptor_offload */ "offload error: cannot find offload entry %s",
/* 17 msg_c_merge_var_descs1 */ "offload error: unexpected number of variable descriptors",
/* 18 msg_c_merge_var_descs2 */ "offload error: unexpected variable type",
/* 19 msg_c_mic_parse_env_var_list1 */ "offload_error: MIC environment variable must begin with an alpabetic character",
/* 20 msg_c_mic_parse_env_var_list2 */ "offload_error: MIC environment variable value must be specified with \'=\'",
/* 21 msg_c_mic_process_exit_ret */ "offload error: process on the device %d unexpectedly exited with code %d",
/* 22 msg_c_mic_process_exit_sig */ "offload error: process on the device %d was terminated by signal %d (%s)",
/* 23 msg_c_mic_process_exit */ "offload error: process on the device %d was unexpectedly terminated",
/* 24 msg_c_mic_init3 */ "offload warning: ignoring MIC_STACKSIZE setting; use a value >= 16K and a multiple of 4K",
/* 25 msg_c_mic_init4 */ "offload error: thread key create failed with error %d",
/* 26 msg_c_mic_init5 */ "offload warning: specify OFFLOAD_DEVICES as comma-separated physical device numbers or 'none'",
/* 27 msg_c_mic_init6 */ "offload warning: OFFLOAD_DEVICES device number %d does not correspond to a physical device",
/* 28 msg_c_no_static_var_data */ "offload error: cannot find data associated with statically allocated variable %p",
/* 29 msg_c_no_ptr_data */ "offload error: cannot find data associated with pointer variable %p",
/* 30 msg_c_get_engine_handle */ "offload error: cannot get device %d handle (error code %d)",
/* 31 msg_c_get_engine_index */ "offload error: cannot get physical index for logical device %d (error code %d)",
/* 32 msg_c_process_create */ "offload error: cannot start process on the device %d (error code %d)",
/* 33 msg_c_process_get_func_handles */ "offload error: cannot get function handles on the device %d (error code %d)",
/* 34 msg_c_process_wait_shutdown */ "offload error: wait for process shutdown failed on device %d (error code %d)",
/* 35 msg_c_process_proxy_flush */ "offload error: cannot flush process output on device %d (error code %d)",
/* 36 msg_c_load_library */ "offload error: cannot load library to the device %d (error code %d)",
/* 37 msg_c_pipeline_create */ "offload error: cannot create pipeline on the device %d (error code %d)",
/* 38 msg_c_pipeline_run_func */ "offload error: cannot execute function on the device %d (error code %d)",
/* 39 msg_c_pipeline_start_run_funcs */ "offload error: cannot start executing pipeline function on the device %d (error code %d)",
/* 40 msg_c_buf_create */ "offload error: cannot create buffer on device %d (error code %d)",
/* 41 msg_c_buf_create_out_of_mem */ "offload error: cannot create buffer on device %d, out of memory",
/* 42 msg_c_buf_create_from_mem */ "offload error: cannot create buffer from memory on device %d (error code %d)",
/* 43 msg_c_buf_destroy */ "offload error: buffer destroy failed (error code %d)",
/* 44 msg_c_buf_map */ "offload error: buffer map failed (error code %d)",
/* 45 msg_c_buf_unmap */ "offload error: buffer unmap failed (error code %d)",
/* 46 msg_c_buf_read */ "offload error: buffer read failed (error code %d)",
/* 47 msg_c_buf_write */ "offload error: buffer write failed (error code %d)",
/* 48 msg_c_buf_copy */ "offload error: buffer copy failed (error code %d)",
/* 49 msg_c_buf_get_address */ "offload error: cannot get buffer address on device %d (error code %d)",
/* 50 msg_c_buf_add_ref */ "offload error: cannot reuse buffer memory on device %d (error code %d)",
/* 51 msg_c_buf_release_ref */ "offload error: cannot release buffer memory on device %d (error code %d)",
/* 52 msg_c_buf_set_state */ "offload error: buffer set state failed (error code %d)",
/* 53 msg_c_event_wait */ "offload error: wait for event to become signaled failed (error code %d)",
/* 54 msg_c_zero_or_neg_ptr_len */ "offload error: memory allocation of negative length is not supported",
/* 55 msg_c_zero_or_neg_transfer_size */ "offload error: data transfer of zero or negative size is not supported",
/* 56 msg_c_bad_ptr_mem_range */ "offload error: address range partially overlaps with existing allocation",
/* 57 msg_c_different_src_and_dstn_sizes */ "offload error: size of the source %d differs from size of the destination %d",
/* 58 msg_c_non_contiguous_dope_vector */ "offload error: offload data transfer supports only a single contiguous memory range per variable",
/* 59 msg_c_omp_invalid_device_num_env */ "offload warning: ignoring %s setting; use a non-negative integer value",
/* 60 msg_c_omp_invalid_device_num */ "offload error: device number should be a non-negative integer value",
/* 61 msg_c_unknown_binary_type */ "offload error: unexpected embedded target binary type, expected either an executable or shared library",
/* 62 msg_c_multiple_target_exes */ "offload error: more that one target executable found",
/* 63 msg_c_no_target_exe */ "offload error: target executable is not available",
/* 64 msg_c_report_unknown_timer_node */ "offload error: unknown timer node",
/* 65 msg_c_report_unknown_trace_node */ "offload error: unknown trace node",
/* 66 msg_c_report_host */ "HOST",
/* 67 msg_c_report_mic */ "MIC",
/* 68 msg_c_report_title */ "timer data (sec)",
/* 69 msg_c_report_seconds */ "(seconds)",
/* 70 msg_c_report_bytes */ "(bytes)",
/* 71 msg_c_report_cpu_time */ "CPU Time",
/* 72 msg_c_report_mic_time */ "MIC Time",
/* 73 msg_c_report_tag */ "Tag",
/* 74 msg_c_report_from_file */ "Offload from file",
/* 75 msg_c_report_file */ "File",
/* 76 msg_c_report_line */ "Line",
/* 77 msg_c_report_cpu_to_mic_data */ "CPU->MIC Data",
/* 78 msg_c_report_mic_to_cpu_data */ "MIC->CPU Data",
/* 79 msg_c_report_offload */ "Offload",
/* 80 msg_c_report_w_tag */ "Tag %d",
/* 81 msg_c_report_state */ "State",
/* 82 msg_c_report_start */ "Start target",
/* 83 msg_c_report_init */ "Initialize",
/* 84 msg_c_report_logical_card */ "logical card",
/* 85 msg_c_report_physical_card */ "physical card",
/* 86 msg_c_report_register */ "Register static data tables",
/* 87 msg_c_report_init_func */ "Setup target entry",
/* 88 msg_c_report_create_buf_host */ "Create host buffer",
/* 89 msg_c_report_create_buf_mic */ "Create target buffer",
/* 90 msg_c_report_send_pointer_data */ "Send pointer data",
/* 91 msg_c_report_sent_pointer_data */ "Host->target pointer data",
/* 92 msg_c_report_gather_copyin_data */ "Gather copyin data",
/* 93 msg_c_report_copyin_data */ "Host->target copyin data",
/* 94 msg_c_report_state_signal */ "Signal",
/* 95 msg_c_report_signal */ "signal :",
/* 96 msg_c_report_wait */ "waits :",
/* 97 msg_c_report_compute */ "Execute task on target",
/* 98 msg_c_report_receive_pointer_data */ "Receive pointer data",
/* 99 msg_c_report_received_pointer_data */ "Target->host pointer data",
/* 100 msg_c_report_start_target_func */ "Start target entry",
/* 101 msg_c_report_var */ "Var",
/* 102 msg_c_report_scatter_copyin_data */ "Scatter copyin data",
/* 103 msg_c_report_gather_copyout_data */ "Gather copyout data",
/* 104 msg_c_report_scatter_copyout_data */ "Scatter copyout data",
/* 105 msg_c_report_copyout_data */ "Target->host copyout data",
/* 106 msg_c_report_unregister */ "Unregister data tables",
/* 107 msg_c_report_destroy */ "Destroy",
/* 108 msg_c_report_myoinit */ "Initialize MYO",
/* 109 msg_c_report_myoregister */ "Register MYO tables",
/* 110 msg_c_report_myofini */ "Finalize MYO",
/* 111 msg_c_report_mic_myo_shared */ "MIC MYO shared table register",
/* 112 msg_c_report_mic_myo_fptr */ "MIC MYO fptr table register",
/* 113 msg_c_report_myosharedmalloc */ "MYO shared malloc",
/* 114 msg_c_report_myosharedfree */ "MYO shared free",
/* 115 msg_c_report_myosharedalignedmalloc */ "MYO shared aligned malloc",
/* 116 msg_c_report_myosharedalignedfree */ "MYO shared aligned free",
/* 117 msg_c_report_myoacquire */ "MYO acquire",
/* 118 msg_c_report_myorelease */ "MYO release",
/* 119 msg_c_report_host_total_offload_time */ "host: total offload time",
/* 120 msg_c_report_host_initialize */ "host: initialize target",
/* 121 msg_c_report_host_target_acquire */ "host: acquire target",
/* 122 msg_c_report_host_wait_deps */ "host: wait dependencies",
/* 123 msg_c_report_host_setup_buffers */ "host: setup buffers",
/* 124 msg_c_report_host_alloc_buffers */ "host: allocate buffers",
/* 125 msg_c_report_host_setup_misc_data */ "host: setup misc_data",
/* 126 msg_c_report_host_alloc_data_buffer */ "host: allocate buffer",
/* 127 msg_c_report_host_send_pointers */ "host: send pointers",
/* 128 msg_c_report_host_gather_inputs */ "host: gather inputs",
/* 129 msg_c_report_host_map_in_data_buffer */ "host: map IN data buffer",
/* 130 msg_c_report_host_unmap_in_data_buffer */ "host: unmap IN data buffer",
/* 131 msg_c_report_host_start_compute */ "host: initiate compute",
/* 132 msg_c_report_host_wait_compute */ "host: wait compute",
/* 133 msg_c_report_host_start_buffers_reads */ "host: initiate pointer reads",
/* 134 msg_c_report_host_scatter_outputs */ "host: scatter outputs",
/* 135 msg_c_report_host_map_out_data_buffer */ "host: map OUT data buffer",
/* 136 msg_c_report_host_unmap_out_data_buffer */ "host: unmap OUT data buffer",
/* 137 msg_c_report_host_wait_buffers_reads */ "host: wait pointer reads",
/* 138 msg_c_report_host_destroy_buffers */ "host: destroy buffers",
/* 139 msg_c_report_target_total_time */ "target: total time",
/* 140 msg_c_report_target_descriptor_setup */ "target: setup offload descriptor",
/* 141 msg_c_report_target_func_lookup */ "target: entry lookup",
/* 142 msg_c_report_target_func_time */ "target: entry time",
/* 143 msg_c_report_target_scatter_inputs */ "target: scatter inputs",
/* 144 msg_c_report_target_add_buffer_refs */ "target: add buffer reference",
/* 145 msg_c_report_target_compute */ "target: compute",
/* 146 msg_c_report_target_gather_outputs */ "target: gather outputs",
/* 147 msg_c_report_target_release_buffer_refs */ "target: remove buffer reference",
/* 148 msg_c_coi_pipeline_max_number */ "number of host threads doing offload exceeds maximum of %d",
/* 149 msg_c_ranges_dont_match */ "ranges of source and destination don't match together",
/* 150 msg_c_destination_is_over */ "insufficient destination memory to transfer source",
/* 151 msg_c_slice_of_noncont_array */ "a non-contiguous slice may be taken of contiguous arrays only",
/* 152 msg_c_pointer_array_mismatch */ "number of %s elements is less than described by the source",
};

View File

@ -0,0 +1,282 @@
!
! Copyright (c) 2014 Intel Corporation. All Rights Reserved.
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions
! are met:
!
! * Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
! * Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
! * Neither the name of Intel Corporation nor the names of its
! contributors may be used to endorse or promote products derived
! from this software without specific prior written permission.
!
! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
! "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
! LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
! A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
! HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
! SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
! LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
! DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
! THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
! (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
! OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
!
! **********************************************************************************
! * 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
end interface
end module mic_lib

View File

@ -0,0 +1,371 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* 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) __GOMP_NOTHROW;
extern int omp_get_default_device(void) __GOMP_NOTHROW;
extern int omp_get_num_devices(void) __GOMP_NOTHROW;
/* 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
);
#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 */

View File

@ -0,0 +1,190 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#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;
}

View File

@ -0,0 +1,475 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*! \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>
#if (defined(LINUX) || defined(FREEBSD)) && !defined(__INTEL_COMPILER)
#include <mm_malloc.h>
#endif
#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>
// Use secure getenv if it's supported
#ifdef HAVE_SECURE_GETENV
#define getenv(x) secure_getenv(x)
#elif HAVE___SECURE_GETENV
#define getenv(x) __secure_getenv(x)
#endif
// 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

View File

@ -0,0 +1,551 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#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,
&params, 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,
&params.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);
}

View File

@ -0,0 +1,502 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#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 - begining 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

View File

@ -0,0 +1,378 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#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 occured
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);
if (env_var_def == NULL)
LIBOFFLOAD_ERROR(c_malloc);
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 begining 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*));
if (rez == NULL)
LIBOFFLOAD_ERROR(c_malloc);
std::copy(new_env.begin(), new_env.end(), rez);
rez[new_env_size] = 0;
return rez;
}

View File

@ -0,0 +1,111 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#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

View File

@ -0,0 +1,363 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*! \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 recieve_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

View File

@ -0,0 +1,829 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#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);
if (args == NULL)
LIBOFFLOAD_ERROR(c_malloc);
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);
if (args == NULL)
LIBOFFLOAD_ERROR(c_malloc);
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);
}
}

View File

@ -0,0 +1,100 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#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

View File

@ -0,0 +1,204 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#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();
}

View File

@ -0,0 +1,74 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#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

View File

@ -0,0 +1,485 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <omp.h>
#include "offload.h"
#include "compiler_if_host.h"
// OpenMP API
void omp_set_default_device(int num) __GOMP_NOTHROW
{
if (num >= 0) {
__omp_device_num = num;
}
}
int omp_get_default_device(void) __GOMP_NOTHROW
{
return __omp_device_num;
}
int omp_get_num_devices() __GOMP_NOTHROW
{
__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;
}

View File

@ -0,0 +1,560 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <omp.h>
#include "offload.h"
#include "compiler_if_target.h"
// OpenMP API
void omp_set_default_device(int num) __GOMP_NOTHROW
{
}
int omp_get_default_device(void) __GOMP_NOTHROW
{
return mic_index;
}
int omp_get_num_devices() __GOMP_NOTHROW
{
return mic_engines_total;
}
// OpenMP API wrappers
static void omp_send_int_to_host(
void *ofld_,
int setting
)
{
OFFLOAD ofld = (OFFLOAD) 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].ptr = &setting;
OFFLOAD_TARGET_ENTER(ofld, 1, vars, NULL);
OFFLOAD_TARGET_LEAVE(ofld);
}
static int omp_get_int_from_host(
void *ofld_
)
{
OFFLOAD ofld = (OFFLOAD) ofld_;
VarDesc vars[1] = {0};
int setting;
vars[0].type.src = c_data;
vars[0].type.dst = c_data;
vars[0].direction.bits = c_parameter_in;
vars[0].ptr = &setting;
OFFLOAD_TARGET_ENTER(ofld, 1, vars, NULL);
OFFLOAD_TARGET_LEAVE(ofld);
return setting;
}
void omp_set_num_threads_lrb(
void *ofld
)
{
int num_threads;
num_threads = omp_get_int_from_host(ofld);
omp_set_num_threads(num_threads);
}
void omp_get_max_threads_lrb(
void *ofld
)
{
int num_threads;
num_threads = omp_get_max_threads();
omp_send_int_to_host(ofld, num_threads);
}
void omp_get_num_procs_lrb(
void *ofld
)
{
int num_procs;
num_procs = omp_get_num_procs();
omp_send_int_to_host(ofld, num_procs);
}
void omp_set_dynamic_lrb(
void *ofld
)
{
int dynamic;
dynamic = omp_get_int_from_host(ofld);
omp_set_dynamic(dynamic);
}
void omp_get_dynamic_lrb(
void *ofld
)
{
int dynamic;
dynamic = omp_get_dynamic();
omp_send_int_to_host(ofld, dynamic);
}
void omp_set_nested_lrb(
void *ofld
)
{
int nested;
nested = omp_get_int_from_host(ofld);
omp_set_nested(nested);
}
void omp_get_nested_lrb(
void *ofld
)
{
int nested;
nested = omp_get_nested();
omp_send_int_to_host(ofld, nested);
}
void omp_set_schedule_lrb(
void *ofld_
)
{
OFFLOAD ofld = (OFFLOAD) ofld_;
VarDesc vars[2] = {0};
omp_sched_t kind;
int modifier;
vars[0].type.src = c_data;
vars[0].type.dst = c_data;
vars[0].direction.bits = c_parameter_in;
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].ptr = &modifier;
OFFLOAD_TARGET_ENTER(ofld, 2, vars, NULL);
omp_set_schedule(kind, modifier);
OFFLOAD_TARGET_LEAVE(ofld);
}
void omp_get_schedule_lrb(
void *ofld_
)
{
OFFLOAD ofld = (OFFLOAD) ofld_;
VarDesc vars[2] = {0};
omp_sched_t kind;
int modifier;
vars[0].type.src = c_data;
vars[0].type.dst = c_data;
vars[0].direction.bits = c_parameter_out;
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].ptr = &modifier;
OFFLOAD_TARGET_ENTER(ofld, 2, vars, NULL);
omp_get_schedule(&kind, &modifier);
OFFLOAD_TARGET_LEAVE(ofld);
}
// lock API functions
void omp_init_lock_lrb(
void *ofld_
)
{
OFFLOAD ofld = (OFFLOAD) ofld_;
VarDesc vars[1] = {0};
omp_lock_target_t lock;
vars[0].type.src = c_data;
vars[0].type.dst = c_data;
vars[0].direction.bits = c_parameter_out;
vars[0].ptr = &lock;
OFFLOAD_TARGET_ENTER(ofld, 1, vars, NULL);
omp_init_lock(&lock.lock);
OFFLOAD_TARGET_LEAVE(ofld);
}
void omp_destroy_lock_lrb(
void *ofld_
)
{
OFFLOAD ofld = (OFFLOAD) ofld_;
VarDesc vars[1] = {0};
omp_lock_target_t lock;
vars[0].type.src = c_data;
vars[0].type.dst = c_data;
vars[0].direction.bits = c_parameter_in;
vars[0].ptr = &lock;
OFFLOAD_TARGET_ENTER(ofld, 1, vars, NULL);
omp_destroy_lock(&lock.lock);
OFFLOAD_TARGET_LEAVE(ofld);
}
void omp_set_lock_lrb(
void *ofld_
)
{
OFFLOAD ofld = (OFFLOAD) ofld_;
VarDesc vars[1] = {0};
omp_lock_target_t lock;
vars[0].type.src = c_data;
vars[0].type.dst = c_data;
vars[0].direction.bits = c_parameter_inout;
vars[0].ptr = &lock;
OFFLOAD_TARGET_ENTER(ofld, 1, vars, NULL);
omp_set_lock(&lock.lock);
OFFLOAD_TARGET_LEAVE(ofld);
}
void omp_unset_lock_lrb(
void *ofld_
)
{
OFFLOAD ofld = (OFFLOAD) ofld_;
VarDesc vars[1] = {0};
omp_lock_target_t lock;
vars[0].type.src = c_data;
vars[0].type.dst = c_data;
vars[0].direction.bits = c_parameter_inout;
vars[0].ptr = &lock;
OFFLOAD_TARGET_ENTER(ofld, 1, vars, NULL);
omp_unset_lock(&lock.lock);
OFFLOAD_TARGET_LEAVE(ofld);
}
void omp_test_lock_lrb(
void *ofld_
)
{
OFFLOAD ofld = (OFFLOAD) ofld_;
VarDesc vars[2] = {0};
omp_lock_target_t lock;
int result;
vars[0].type.src = c_data;
vars[0].type.dst = c_data;
vars[0].direction.bits = c_parameter_inout;
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].ptr = &result;
OFFLOAD_TARGET_ENTER(ofld, 2, vars, NULL);
result = omp_test_lock(&lock.lock);
OFFLOAD_TARGET_LEAVE(ofld);
}
// nested lock API functions
void omp_init_nest_lock_lrb(
void *ofld_
)
{
OFFLOAD ofld = (OFFLOAD) ofld_;
VarDesc vars[1] = {0};
omp_nest_lock_target_t lock;
vars[0].type.src = c_data;
vars[0].type.dst = c_data;
vars[0].direction.bits = c_parameter_out;
vars[0].ptr = &lock;
OFFLOAD_TARGET_ENTER(ofld, 1, vars, NULL);
omp_init_nest_lock(&lock.lock);
OFFLOAD_TARGET_LEAVE(ofld);
}
void omp_destroy_nest_lock_lrb(
void *ofld_
)
{
OFFLOAD ofld = (OFFLOAD) ofld_;
VarDesc vars[1] = {0};
omp_nest_lock_target_t lock;
vars[0].type.src = c_data;
vars[0].type.dst = c_data;
vars[0].direction.bits = c_parameter_in;
vars[0].ptr = &lock;
OFFLOAD_TARGET_ENTER(ofld, 1, vars, NULL);
omp_destroy_nest_lock(&lock.lock);
OFFLOAD_TARGET_LEAVE(ofld);
}
void omp_set_nest_lock_lrb(
void *ofld_
)
{
OFFLOAD ofld = (OFFLOAD) ofld_;
VarDesc vars[1] = {0};
omp_nest_lock_target_t lock;
vars[0].type.src = c_data;
vars[0].type.dst = c_data;
vars[0].direction.bits = c_parameter_inout;
vars[0].ptr = &lock;
OFFLOAD_TARGET_ENTER(ofld, 1, vars, NULL);
omp_set_nest_lock(&lock.lock);
OFFLOAD_TARGET_LEAVE(ofld);
}
void omp_unset_nest_lock_lrb(
void *ofld_
)
{
OFFLOAD ofld = (OFFLOAD) ofld_;
VarDesc vars[1] = {0};
omp_nest_lock_target_t lock;
vars[0].type.src = c_data;
vars[0].type.dst = c_data;
vars[0].direction.bits = c_parameter_inout;
vars[0].ptr = &lock;
OFFLOAD_TARGET_ENTER(ofld, 1, vars, NULL);
omp_unset_nest_lock(&lock.lock);
OFFLOAD_TARGET_LEAVE(ofld);
}
void omp_test_nest_lock_lrb(
void *ofld_
)
{
OFFLOAD ofld = (OFFLOAD) ofld_;
VarDesc vars[2] = {0};
omp_nest_lock_target_t lock;
int result;
vars[0].type.src = c_data;
vars[0].type.dst = c_data;
vars[0].direction.bits = c_parameter_inout;
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].ptr = &result;
OFFLOAD_TARGET_ENTER(ofld, 2, vars, NULL);
result = omp_test_nest_lock(&lock.lock);
OFFLOAD_TARGET_LEAVE(ofld);
}
// Target-side stubs for the host functions (to avoid unresolveds)
// These are needed for the offloadm table
void omp_set_num_threads_target(
TARGET_TYPE target_type,
int target_number,
int num_threads
)
{
}
int omp_get_max_threads_target(
TARGET_TYPE target_type,
int target_number
)
{
return 0;
}
int omp_get_num_procs_target(
TARGET_TYPE target_type,
int target_number
)
{
return 0;
}
void omp_set_dynamic_target(
TARGET_TYPE target_type,
int target_number,
int num_threads
)
{
}
int omp_get_dynamic_target(
TARGET_TYPE target_type,
int target_number
)
{
return 0;
}
void omp_set_nested_target(
TARGET_TYPE target_type,
int target_number,
int num_threads
)
{
}
int omp_get_nested_target(
TARGET_TYPE target_type,
int target_number
)
{
return 0;
}
void omp_set_schedule_target(
TARGET_TYPE target_type,
int target_number,
omp_sched_t kind,
int modifier
)
{
}
void omp_get_schedule_target(
TARGET_TYPE target_type,
int target_number,
omp_sched_t *kind,
int *modifier
)
{
}
void omp_init_lock_target(
TARGET_TYPE target_type,
int target_number,
omp_lock_target_t *lock
)
{
}
void omp_destroy_lock_target(
TARGET_TYPE target_type,
int target_number,
omp_lock_target_t *lock
)
{
}
void omp_set_lock_target(
TARGET_TYPE target_type,
int target_number,
omp_lock_target_t *lock
)
{
}
void omp_unset_lock_target(
TARGET_TYPE target_type,
int target_number,
omp_lock_target_t *lock
)
{
}
int omp_test_lock_target(
TARGET_TYPE target_type,
int target_number,
omp_lock_target_t *lock
)
{
return 0;
}
void omp_init_nest_lock_target(
TARGET_TYPE target_type,
int target_number,
omp_nest_lock_target_t *lock
)
{
}
void omp_destroy_nest_lock_target(
TARGET_TYPE target_type,
int target_number,
omp_nest_lock_target_t *lock
)
{
}
void omp_set_nest_lock_target(
TARGET_TYPE target_type,
int target_number,
omp_nest_lock_target_t *lock
)
{
}
void omp_unset_nest_lock_target(
TARGET_TYPE target_type,
int target_number,
omp_nest_lock_target_t *lock
)
{
}
int omp_test_nest_lock_target(
TARGET_TYPE target_type,
int target_number,
omp_nest_lock_target_t *lock
)
{
return 0;
}

View File

@ -0,0 +1,104 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#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

View File

@ -0,0 +1,45 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#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

View File

@ -0,0 +1,331 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#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*);
// 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,
(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);
}

View File

@ -0,0 +1,321 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*! \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

View File

@ -0,0 +1,776 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#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);
if (ofld.m_vars == NULL)
LIBOFFLOAD_ERROR(c_malloc);
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;
}

View File

@ -0,0 +1,120 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// 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

View File

@ -0,0 +1,37 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
extern "C" void __offload_target_main(void);
int main(int argc, char ** argv)
{
__offload_target_main();
return 0;
}

View File

@ -0,0 +1,192 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#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

View File

@ -0,0 +1,379 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#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

View File

@ -0,0 +1,87 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#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

View File

@ -0,0 +1,329 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#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;
}

View File

@ -0,0 +1,72 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// 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
};

View File

@ -0,0 +1,226 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#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;
}

View File

@ -0,0 +1,173 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#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

View File

@ -0,0 +1,184 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#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);
}

View File

@ -0,0 +1,97 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#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

View File

@ -0,0 +1,241 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#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

View File

@ -0,0 +1,357 @@
/*
Copyright (c) 2014 Intel Corporation. All Rights Reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#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: */

View File

@ -0,0 +1 @@
ORSL-lite 0.7

View File

@ -0,0 +1 @@
2.1.6720-13