mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-26 21:33:59 +08:00
[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:
parent
f84e7fd6cb
commit
5f52081962
10
ChangeLog
10
ChangeLog
@ -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>
|
||||
|
@ -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; };
|
||||
|
497
Makefile.in
497
Makefile.in
@ -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
|
||||
|
||||
|
||||
|
@ -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
12
config/target-posix
Normal 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
66
configure
vendored
@ -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
|
||||
|
||||
|
57
configure.ac
57
configure.ac
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
94
liboffloadmic/ChangeLog
Normal 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
172
liboffloadmic/Makefile.am
Normal 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
1254
liboffloadmic/Makefile.in
Normal file
File diff suppressed because it is too large
Load Diff
979
liboffloadmic/aclocal.m4
vendored
Normal file
979
liboffloadmic/aclocal.m4
vendored
Normal 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
16957
liboffloadmic/configure
vendored
Normal file
File diff suppressed because it is too large
Load Diff
131
liboffloadmic/configure.ac
Normal file
131
liboffloadmic/configure.ac
Normal 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
|
39
liboffloadmic/configure.tgt
Normal file
39
liboffloadmic/configure.tgt
Normal 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
|
2328
liboffloadmic/doc/doxygen/config
Normal file
2328
liboffloadmic/doc/doxygen/config
Normal file
File diff suppressed because it is too large
Load Diff
90
liboffloadmic/doc/doxygen/header.tex
Normal file
90
liboffloadmic/doc/doxygen/header.tex
Normal 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}
|
108
liboffloadmic/include/coi/common/COIEngine_common.h
Normal file
108
liboffloadmic/include/coi/common/COIEngine_common.h
Normal 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 */
|
||||
|
||||
/*! @} */
|
69
liboffloadmic/include/coi/common/COIMacros_common.h
Normal file
69
liboffloadmic/include/coi/common/COIMacros_common.h
Normal 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 */
|
87
liboffloadmic/include/coi/common/COIPerf_common.h
Normal file
87
liboffloadmic/include/coi/common/COIPerf_common.h
Normal 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 */
|
145
liboffloadmic/include/coi/common/COIResult_common.h
Normal file
145
liboffloadmic/include/coi/common/COIResult_common.h
Normal 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 */
|
||||
|
||||
/*! @} */
|
85
liboffloadmic/include/coi/common/COITypes_common.h
Normal file
85
liboffloadmic/include/coi/common/COITypes_common.h
Normal 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 */
|
130
liboffloadmic/include/coi/sink/COIBuffer_sink.h
Normal file
130
liboffloadmic/include/coi/sink/COIBuffer_sink.h
Normal 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 */
|
||||
|
||||
/*! @} */
|
137
liboffloadmic/include/coi/sink/COIPipeline_sink.h
Normal file
137
liboffloadmic/include/coi/sink/COIPipeline_sink.h
Normal 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 */
|
||||
|
||||
/*! @} */
|
103
liboffloadmic/include/coi/sink/COIProcess_sink.h
Normal file
103
liboffloadmic/include/coi/sink/COIProcess_sink.h
Normal 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 */
|
||||
|
||||
/*! @} */
|
1311
liboffloadmic/include/coi/source/COIBuffer_source.h
Normal file
1311
liboffloadmic/include/coi/source/COIBuffer_source.h
Normal file
File diff suppressed because it is too large
Load Diff
247
liboffloadmic/include/coi/source/COIEngine_source.h
Normal file
247
liboffloadmic/include/coi/source/COIEngine_source.h
Normal 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 */
|
||||
|
||||
/*! @} */
|
192
liboffloadmic/include/coi/source/COIEvent_source.h
Normal file
192
liboffloadmic/include/coi/source/COIEvent_source.h
Normal 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 */
|
||||
|
||||
/*! @} */
|
426
liboffloadmic/include/coi/source/COIPipeline_source.h
Normal file
426
liboffloadmic/include/coi/source/COIPipeline_source.h
Normal 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 */
|
||||
|
||||
/*! @} */
|
971
liboffloadmic/include/coi/source/COIProcess_source.h
Normal file
971
liboffloadmic/include/coi/source/COIProcess_source.h
Normal 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 */
|
||||
|
||||
/*! @} */
|
619
liboffloadmic/include/myo/myo.h
Normal file
619
liboffloadmic/include/myo/myo.h
Normal 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
|
||||
**/
|
||||
|
||||
/*! @} */
|
538
liboffloadmic/include/myo/myoimpl.h
Normal file
538
liboffloadmic/include/myo/myoimpl.h
Normal 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_
|
||||
/*! @} */
|
116
liboffloadmic/include/myo/myotypes.h
Normal file
116
liboffloadmic/include/myo/myotypes.h
Normal 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_
|
||||
/*! @} */
|
3
liboffloadmic/liboffloadmic_host.spec.in
Normal file
3
liboffloadmic/liboffloadmic_host.spec.in
Normal 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@
|
3
liboffloadmic/liboffloadmic_target.spec.in
Normal file
3
liboffloadmic/liboffloadmic_target.spec.in
Normal 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@
|
366
liboffloadmic/runtime/cean_util.cpp
Normal file
366
liboffloadmic/runtime/cean_util.cpp
Normal 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
|
116
liboffloadmic/runtime/cean_util.h
Normal file
116
liboffloadmic/runtime/cean_util.h
Normal 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
|
370
liboffloadmic/runtime/coi/coi_client.cpp
Normal file
370
liboffloadmic/runtime/coi/coi_client.cpp
Normal 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
|
138
liboffloadmic/runtime/coi/coi_client.h
Normal file
138
liboffloadmic/runtime/coi/coi_client.h
Normal 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
|
150
liboffloadmic/runtime/coi/coi_server.cpp
Normal file
150
liboffloadmic/runtime/coi/coi_server.cpp
Normal 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
|
94
liboffloadmic/runtime/coi/coi_server.h
Normal file
94
liboffloadmic/runtime/coi/coi_server.h
Normal 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
|
343
liboffloadmic/runtime/compiler_if_host.cpp
Normal file
343
liboffloadmic/runtime/compiler_if_host.cpp
Normal 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;
|
||||
}
|
153
liboffloadmic/runtime/compiler_if_host.h
Normal file
153
liboffloadmic/runtime/compiler_if_host.h
Normal 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
|
64
liboffloadmic/runtime/compiler_if_target.cpp
Normal file
64
liboffloadmic/runtime/compiler_if_target.cpp
Normal 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");
|
||||
}
|
70
liboffloadmic/runtime/compiler_if_target.h
Normal file
70
liboffloadmic/runtime/compiler_if_target.h
Normal 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
|
153
liboffloadmic/runtime/dv_util.cpp
Normal file
153
liboffloadmic/runtime/dv_util.cpp
Normal 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
|
83
liboffloadmic/runtime/dv_util.h
Normal file
83
liboffloadmic/runtime/dv_util.h
Normal 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
|
140
liboffloadmic/runtime/emulator/coi_common.h
Normal file
140
liboffloadmic/runtime/emulator/coi_common.h
Normal 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
|
330
liboffloadmic/runtime/emulator/coi_device.cpp
Normal file
330
liboffloadmic/runtime/emulator/coi_device.cpp
Normal 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"
|
||||
|
56
liboffloadmic/runtime/emulator/coi_device.h
Normal file
56
liboffloadmic/runtime/emulator/coi_device.h
Normal 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
|
1214
liboffloadmic/runtime/emulator/coi_host.cpp
Normal file
1214
liboffloadmic/runtime/emulator/coi_host.cpp
Normal file
File diff suppressed because it is too large
Load Diff
55
liboffloadmic/runtime/emulator/coi_host.h
Normal file
55
liboffloadmic/runtime/emulator/coi_host.h
Normal 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
|
68
liboffloadmic/runtime/emulator/coi_version_asm.h
Normal file
68
liboffloadmic/runtime/emulator/coi_version_asm.h
Normal 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");
|
||||
|
79
liboffloadmic/runtime/emulator/coi_version_linker_script.map
Normal file
79
liboffloadmic/runtime/emulator/coi_version_linker_script.map
Normal 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;
|
||||
|
31
liboffloadmic/runtime/emulator/myo_client.cpp
Normal file
31
liboffloadmic/runtime/emulator/myo_client.cpp
Normal 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. */
|
||||
|
159
liboffloadmic/runtime/emulator/myo_service.cpp
Normal file
159
liboffloadmic/runtime/emulator/myo_service.cpp
Normal 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"
|
||||
|
63
liboffloadmic/runtime/emulator/myo_service.h
Normal file
63
liboffloadmic/runtime/emulator/myo_service.h
Normal 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
|
53
liboffloadmic/runtime/emulator/myo_version_asm.h
Normal file
53
liboffloadmic/runtime/emulator/myo_version_asm.h
Normal 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");
|
||||
|
60
liboffloadmic/runtime/emulator/myo_version_linker_script.map
Normal file
60
liboffloadmic/runtime/emulator/myo_version_linker_script.map
Normal 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:
|
||||
*;
|
||||
};
|
||||
|
475
liboffloadmic/runtime/liboffload_error.c
Normal file
475
liboffloadmic/runtime/liboffload_error.c
Normal 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();
|
||||
}
|
||||
}
|
297
liboffloadmic/runtime/liboffload_error_codes.h
Normal file
297
liboffloadmic/runtime/liboffload_error_codes.h
Normal 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)
|
67
liboffloadmic/runtime/liboffload_msg.c
Normal file
67
liboffloadmic/runtime/liboffload_msg.c
Normal 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 ];
|
||||
}
|
348
liboffloadmic/runtime/liboffload_msg.h
Normal file
348
liboffloadmic/runtime/liboffload_msg.h
Normal 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",
|
||||
};
|
282
liboffloadmic/runtime/mic_lib.f90
Normal file
282
liboffloadmic/runtime/mic_lib.f90
Normal 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
|
371
liboffloadmic/runtime/offload.h
Normal file
371
liboffloadmic/runtime/offload.h
Normal 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 */
|
190
liboffloadmic/runtime/offload_common.cpp
Normal file
190
liboffloadmic/runtime/offload_common.cpp
Normal 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;
|
||||
}
|
475
liboffloadmic/runtime/offload_common.h
Normal file
475
liboffloadmic/runtime/offload_common.h
Normal 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
|
551
liboffloadmic/runtime/offload_engine.cpp
Normal file
551
liboffloadmic/runtime/offload_engine.cpp
Normal 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,
|
||||
¶ms, sizeof(params),
|
||||
&event);
|
||||
check_result(res, c_pipeline_run_func, m_index, res);
|
||||
|
||||
res = COI::EventWait(1, &event, -1, 1, 0, 0);
|
||||
check_result(res, c_event_wait, res);
|
||||
|
||||
if (params.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// create buffer for target entries and copy data to host
|
||||
COIBUFFER buffer;
|
||||
res = COI::BufferCreate(params.length, COI_BUFFER_NORMAL, 0, 0, 1,
|
||||
&m_process, &buffer);
|
||||
check_result(res, c_buf_create, m_index, res);
|
||||
|
||||
COI_ACCESS_FLAGS flags = COI_SINK_WRITE;
|
||||
res = COI::PipelineRunFunction(get_pipeline(),
|
||||
m_funcs[c_func_var_table_copy],
|
||||
1, &buffer, &flags,
|
||||
0, 0,
|
||||
¶ms.nelems, sizeof(params.nelems),
|
||||
0, 0,
|
||||
&event);
|
||||
check_result(res, c_pipeline_run_func, m_index, res);
|
||||
|
||||
res = COI::EventWait(1, &event, -1, 1, 0, 0);
|
||||
check_result(res, c_event_wait, res);
|
||||
|
||||
// patch names in target data
|
||||
VarList::BufEntry *target_table;
|
||||
COIMAPINSTANCE map_inst;
|
||||
res = COI::BufferMap(buffer, 0, params.length, COI_MAP_READ_ONLY, 0, 0,
|
||||
0, &map_inst,
|
||||
reinterpret_cast<void**>(&target_table));
|
||||
check_result(res, c_buf_map, res);
|
||||
|
||||
VarList::table_patch_names(target_table, params.nelems);
|
||||
|
||||
// and sort entries
|
||||
std::sort(target_table, target_table + params.nelems, target_entry_cmp);
|
||||
std::sort(host_table.begin(), host_table.end(), host_entry_cmp);
|
||||
|
||||
// merge host and target entries and enter matching vars map
|
||||
std::vector<const VarTable::Entry*>::const_iterator hi =
|
||||
host_table.begin();
|
||||
std::vector<const VarTable::Entry*>::const_iterator he =
|
||||
host_table.end();
|
||||
const VarList::BufEntry *ti = target_table;
|
||||
const VarList::BufEntry *te = target_table + params.nelems;
|
||||
|
||||
while (hi != he && ti != te) {
|
||||
int res = strcmp((*hi)->name, reinterpret_cast<const char*>(ti->name));
|
||||
if (res == 0) {
|
||||
// add matching entry to var map
|
||||
std::pair<PtrSet::iterator, bool> res =
|
||||
m_ptr_set.insert(PtrData((*hi)->addr, (*hi)->size));
|
||||
|
||||
// store address for new entries
|
||||
if (res.second) {
|
||||
PtrData *ptr = const_cast<PtrData*>(res.first.operator->());
|
||||
ptr->mic_addr = ti->addr;
|
||||
ptr->is_static = true;
|
||||
}
|
||||
|
||||
hi++;
|
||||
ti++;
|
||||
}
|
||||
else if (res < 0) {
|
||||
hi++;
|
||||
}
|
||||
else {
|
||||
ti++;
|
||||
}
|
||||
}
|
||||
|
||||
// cleanup
|
||||
res = COI::BufferUnmap(map_inst, 0, 0, 0);
|
||||
check_result(res, c_buf_unmap, res);
|
||||
|
||||
res = COI::BufferDestroy(buffer);
|
||||
check_result(res, c_buf_destroy, res);
|
||||
}
|
||||
|
||||
COIRESULT Engine::compute(
|
||||
const std::list<COIBUFFER> &buffers,
|
||||
const void* data,
|
||||
uint16_t data_size,
|
||||
void* ret,
|
||||
uint16_t ret_size,
|
||||
uint32_t num_deps,
|
||||
const COIEVENT* deps,
|
||||
COIEVENT* event
|
||||
) /* const */
|
||||
{
|
||||
COIBUFFER *bufs;
|
||||
COI_ACCESS_FLAGS *flags;
|
||||
COIRESULT res;
|
||||
|
||||
// convert buffers list to array
|
||||
int num_bufs = buffers.size();
|
||||
if (num_bufs > 0) {
|
||||
bufs = (COIBUFFER*) alloca(num_bufs * sizeof(COIBUFFER));
|
||||
flags = (COI_ACCESS_FLAGS*) alloca(num_bufs *
|
||||
sizeof(COI_ACCESS_FLAGS));
|
||||
|
||||
int i = 0;
|
||||
for (std::list<COIBUFFER>::const_iterator it = buffers.begin();
|
||||
it != buffers.end(); it++) {
|
||||
bufs[i] = *it;
|
||||
|
||||
// TODO: this should be fixed
|
||||
flags[i++] = COI_SINK_WRITE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
bufs = 0;
|
||||
flags = 0;
|
||||
}
|
||||
|
||||
// start computation
|
||||
res = COI::PipelineRunFunction(get_pipeline(),
|
||||
m_funcs[c_func_compute],
|
||||
num_bufs, bufs, flags,
|
||||
num_deps, deps,
|
||||
data, data_size,
|
||||
ret, ret_size,
|
||||
event);
|
||||
return res;
|
||||
}
|
||||
|
||||
pid_t Engine::init_device(void)
|
||||
{
|
||||
struct init_data {
|
||||
int device_index;
|
||||
int devices_total;
|
||||
int console_level;
|
||||
int offload_report_level;
|
||||
} data;
|
||||
COIRESULT res;
|
||||
COIEVENT event;
|
||||
pid_t pid;
|
||||
|
||||
OFFLOAD_DEBUG_TRACE_1(2, 0, c_offload_init,
|
||||
"Initializing device with logical index %d "
|
||||
"and physical index %d\n",
|
||||
m_index, m_physical_index);
|
||||
|
||||
// setup misc data
|
||||
data.device_index = m_index;
|
||||
data.devices_total = mic_engines_total;
|
||||
data.console_level = console_enabled;
|
||||
data.offload_report_level = offload_report_level;
|
||||
|
||||
res = COI::PipelineRunFunction(get_pipeline(),
|
||||
m_funcs[c_func_init],
|
||||
0, 0, 0, 0, 0,
|
||||
&data, sizeof(data),
|
||||
&pid, sizeof(pid),
|
||||
&event);
|
||||
check_result(res, c_pipeline_run_func, m_index, res);
|
||||
|
||||
res = COI::EventWait(1, &event, -1, 1, 0, 0);
|
||||
check_result(res, c_event_wait, res);
|
||||
|
||||
OFFLOAD_DEBUG_TRACE(2, "Device process pid is %d\n", pid);
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
// data associated with each thread
|
||||
struct Thread {
|
||||
Thread(long* addr_coipipe_counter) {
|
||||
m_addr_coipipe_counter = addr_coipipe_counter;
|
||||
memset(m_pipelines, 0, sizeof(m_pipelines));
|
||||
}
|
||||
|
||||
~Thread() {
|
||||
#ifndef TARGET_WINNT
|
||||
__sync_sub_and_fetch(m_addr_coipipe_counter, 1);
|
||||
#else // TARGET_WINNT
|
||||
_InterlockedDecrement(m_addr_coipipe_counter);
|
||||
#endif // TARGET_WINNT
|
||||
for (int i = 0; i < mic_engines_total; i++) {
|
||||
if (m_pipelines[i] != 0) {
|
||||
COI::PipelineDestroy(m_pipelines[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
COIPIPELINE get_pipeline(int index) const {
|
||||
return m_pipelines[index];
|
||||
}
|
||||
|
||||
void set_pipeline(int index, COIPIPELINE pipeline) {
|
||||
m_pipelines[index] = pipeline;
|
||||
}
|
||||
|
||||
AutoSet& get_auto_vars() {
|
||||
return m_auto_vars;
|
||||
}
|
||||
|
||||
private:
|
||||
long* m_addr_coipipe_counter;
|
||||
AutoSet m_auto_vars;
|
||||
COIPIPELINE m_pipelines[MIC_ENGINES_MAX];
|
||||
};
|
||||
|
||||
COIPIPELINE Engine::get_pipeline(void)
|
||||
{
|
||||
Thread* thread = (Thread*) thread_getspecific(mic_thread_key);
|
||||
if (thread == 0) {
|
||||
thread = new Thread(&m_proc_number);
|
||||
thread_setspecific(mic_thread_key, thread);
|
||||
}
|
||||
|
||||
COIPIPELINE pipeline = thread->get_pipeline(m_index);
|
||||
if (pipeline == 0) {
|
||||
COIRESULT res;
|
||||
int proc_num;
|
||||
|
||||
#ifndef TARGET_WINNT
|
||||
proc_num = __sync_fetch_and_add(&m_proc_number, 1);
|
||||
#else // TARGET_WINNT
|
||||
proc_num = _InterlockedIncrement(&m_proc_number);
|
||||
#endif // TARGET_WINNT
|
||||
|
||||
if (proc_num > COI_PIPELINE_MAX_PIPELINES) {
|
||||
LIBOFFLOAD_ERROR(c_coipipe_max_number, COI_PIPELINE_MAX_PIPELINES);
|
||||
LIBOFFLOAD_ABORT;
|
||||
}
|
||||
// create pipeline for this thread
|
||||
res = COI::PipelineCreate(m_process, 0, mic_stack_size, &pipeline);
|
||||
check_result(res, c_pipeline_create, m_index, res);
|
||||
|
||||
thread->set_pipeline(m_index, pipeline);
|
||||
}
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
AutoSet& Engine::get_auto_vars(void)
|
||||
{
|
||||
Thread* thread = (Thread*) thread_getspecific(mic_thread_key);
|
||||
if (thread == 0) {
|
||||
thread = new Thread(&m_proc_number);
|
||||
thread_setspecific(mic_thread_key, thread);
|
||||
}
|
||||
|
||||
return thread->get_auto_vars();
|
||||
}
|
||||
|
||||
void Engine::destroy_thread_data(void *data)
|
||||
{
|
||||
delete static_cast<Thread*>(data);
|
||||
}
|
502
liboffloadmic/runtime/offload_engine.h
Normal file
502
liboffloadmic/runtime/offload_engine.h
Normal 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
|
378
liboffloadmic/runtime/offload_env.cpp
Normal file
378
liboffloadmic/runtime/offload_env.cpp
Normal 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;
|
||||
}
|
111
liboffloadmic/runtime/offload_env.h
Normal file
111
liboffloadmic/runtime/offload_env.h
Normal 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
|
4402
liboffloadmic/runtime/offload_host.cpp
Normal file
4402
liboffloadmic/runtime/offload_host.cpp
Normal file
File diff suppressed because it is too large
Load Diff
363
liboffloadmic/runtime/offload_host.h
Normal file
363
liboffloadmic/runtime/offload_host.h
Normal 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
|
829
liboffloadmic/runtime/offload_myo_host.cpp
Normal file
829
liboffloadmic/runtime/offload_myo_host.cpp
Normal 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);
|
||||
}
|
||||
}
|
100
liboffloadmic/runtime/offload_myo_host.h
Normal file
100
liboffloadmic/runtime/offload_myo_host.h
Normal 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
|
204
liboffloadmic/runtime/offload_myo_target.cpp
Normal file
204
liboffloadmic/runtime/offload_myo_target.cpp
Normal 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();
|
||||
}
|
74
liboffloadmic/runtime/offload_myo_target.h
Normal file
74
liboffloadmic/runtime/offload_myo_target.h
Normal 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
|
485
liboffloadmic/runtime/offload_omp_host.cpp
Normal file
485
liboffloadmic/runtime/offload_omp_host.cpp
Normal 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;
|
||||
}
|
560
liboffloadmic/runtime/offload_omp_target.cpp
Normal file
560
liboffloadmic/runtime/offload_omp_target.cpp
Normal 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;
|
||||
}
|
104
liboffloadmic/runtime/offload_orsl.cpp
Normal file
104
liboffloadmic/runtime/offload_orsl.cpp
Normal 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
|
45
liboffloadmic/runtime/offload_orsl.h
Normal file
45
liboffloadmic/runtime/offload_orsl.h
Normal 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
|
331
liboffloadmic/runtime/offload_table.cpp
Normal file
331
liboffloadmic/runtime/offload_table.cpp
Normal 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);
|
||||
}
|
321
liboffloadmic/runtime/offload_table.h
Normal file
321
liboffloadmic/runtime/offload_table.h
Normal 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
|
776
liboffloadmic/runtime/offload_target.cpp
Normal file
776
liboffloadmic/runtime/offload_target.cpp
Normal 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;
|
||||
}
|
120
liboffloadmic/runtime/offload_target.h
Normal file
120
liboffloadmic/runtime/offload_target.h
Normal 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
|
37
liboffloadmic/runtime/offload_target_main.cpp
Normal file
37
liboffloadmic/runtime/offload_target_main.cpp
Normal 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;
|
||||
}
|
192
liboffloadmic/runtime/offload_timer.h
Normal file
192
liboffloadmic/runtime/offload_timer.h
Normal 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
|
379
liboffloadmic/runtime/offload_timer_host.cpp
Normal file
379
liboffloadmic/runtime/offload_timer_host.cpp
Normal 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
|
87
liboffloadmic/runtime/offload_timer_target.cpp
Normal file
87
liboffloadmic/runtime/offload_timer_target.cpp
Normal 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
|
329
liboffloadmic/runtime/offload_trace.cpp
Normal file
329
liboffloadmic/runtime/offload_trace.cpp
Normal 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;
|
||||
}
|
72
liboffloadmic/runtime/offload_trace.h
Normal file
72
liboffloadmic/runtime/offload_trace.h
Normal 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
|
||||
};
|
226
liboffloadmic/runtime/offload_util.cpp
Normal file
226
liboffloadmic/runtime/offload_util.cpp
Normal 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;
|
||||
}
|
173
liboffloadmic/runtime/offload_util.h
Normal file
173
liboffloadmic/runtime/offload_util.h
Normal 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
|
184
liboffloadmic/runtime/ofldbegin.cpp
Normal file
184
liboffloadmic/runtime/ofldbegin.cpp
Normal 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);
|
||||
}
|
97
liboffloadmic/runtime/ofldend.cpp
Normal file
97
liboffloadmic/runtime/ofldend.cpp
Normal 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
|
241
liboffloadmic/runtime/orsl-lite/include/orsl-lite.h
Normal file
241
liboffloadmic/runtime/orsl-lite/include/orsl-lite.h
Normal 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
|
357
liboffloadmic/runtime/orsl-lite/lib/orsl-lite.c
Normal file
357
liboffloadmic/runtime/orsl-lite/lib/orsl-lite.c
Normal 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: */
|
1
liboffloadmic/runtime/orsl-lite/version.txt
Normal file
1
liboffloadmic/runtime/orsl-lite/version.txt
Normal file
@ -0,0 +1 @@
|
||||
ORSL-lite 0.7
|
1
liboffloadmic/runtime/use_mpss2.txt
Normal file
1
liboffloadmic/runtime/use_mpss2.txt
Normal file
@ -0,0 +1 @@
|
||||
2.1.6720-13
|
Loading…
Reference in New Issue
Block a user