offload_host.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541
  1. /*
  2. Copyright (c) 2014-2016 Intel Corporation. All Rights Reserved.
  3. Redistribution and use in source and binary forms, with or without
  4. modification, are permitted provided that the following conditions
  5. are met:
  6. * Redistributions of source code must retain the above copyright
  7. notice, this list of conditions and the following disclaimer.
  8. * Redistributions in binary form must reproduce the above copyright
  9. notice, this list of conditions and the following disclaimer in the
  10. documentation and/or other materials provided with the distribution.
  11. * Neither the name of Intel Corporation nor the names of its
  12. contributors may be used to endorse or promote products derived
  13. from this software without specific prior written permission.
  14. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  15. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  16. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  17. A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  18. HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  19. SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  20. LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  21. DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  22. THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  24. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. /*! \file
  27. \brief The parts of the runtime library used only on the host
  28. */
  29. #ifndef OFFLOAD_HOST_H_INCLUDED
  30. #define OFFLOAD_HOST_H_INCLUDED
  31. #ifndef TARGET_WINNT
  32. #include <unistd.h>
  33. #endif // TARGET_WINNT
  34. #include "offload_common.h"
  35. #include "offload_util.h"
  36. #include "offload_engine.h"
  37. #include "offload_env.h"
  38. #include "offload_orsl.h"
  39. #include "coi/coi_client.h"
  40. // MIC engines.
  41. DLL_LOCAL extern Engine* mic_engines;
  42. DLL_LOCAL extern uint32_t mic_engines_total;
  43. // DMA channel count used by COI and set via
  44. // OFFLOAD_DMA_CHANNEL_COUNT environment variable
  45. DLL_LOCAL extern uint32_t mic_dma_channel_count;
  46. //! The target image is packed as follows.
  47. /*! 1. 8 bytes containing the size of the target binary */
  48. /*! 2. a null-terminated string which is the binary name */
  49. /*! 3. <size> number of bytes that are the contents of the image */
  50. /*! The address of symbol __offload_target_image
  51. is the address of this structure. */
  52. struct Image {
  53. int64_t size; //!< Size in bytes of the target binary name and contents
  54. char data[]; //!< The name and contents of the target image
  55. };
  56. // The offload descriptor.
  57. class OffloadDescriptor
  58. {
  59. public:
  60. enum OmpAsyncLastEventType {
  61. c_last_not, // not last event
  62. c_last_write, // the last event that is write
  63. c_last_read, // the last event that is read
  64. c_last_runfunc // the last event that is runfunction
  65. };
  66. OffloadDescriptor(
  67. int index,
  68. _Offload_status *status,
  69. bool is_mandatory,
  70. bool is_openmp,
  71. OffloadHostTimerData * timer_data
  72. ) :
  73. m_device(mic_engines[index == -1 ? 0 : index % mic_engines_total]),
  74. m_is_mandatory(is_mandatory),
  75. m_is_openmp(is_openmp),
  76. m_inout_buf(0),
  77. m_func_desc(0),
  78. m_func_desc_size(0),
  79. m_num_in_dependencies(0),
  80. m_p_in_dependencies(0),
  81. m_in_deps(0),
  82. m_in_deps_total(0),
  83. m_in_deps_allocated(0),
  84. m_out_deps(0),
  85. m_out_deps_total(0),
  86. m_out_deps_allocated(0),
  87. m_vars(0),
  88. m_vars_extra(0),
  89. m_status(status),
  90. m_timer_data(timer_data),
  91. m_out_with_preallocated(false),
  92. m_preallocated_alloc(false),
  93. m_traceback_called(false),
  94. m_stream(-1),
  95. m_signal(0),
  96. m_has_signal(0),
  97. m_omp_async_last_event_type(c_last_not)
  98. {
  99. m_wait_all_devices = index == -1;
  100. }
  101. ~OffloadDescriptor()
  102. {
  103. if (m_in_deps != 0) {
  104. free(m_in_deps);
  105. }
  106. if (m_out_deps != 0) {
  107. free(m_out_deps);
  108. }
  109. if (m_func_desc != 0) {
  110. free(m_func_desc);
  111. }
  112. if (m_vars != 0) {
  113. free(m_vars);
  114. free(m_vars_extra);
  115. }
  116. }
  117. bool offload(const char *name, bool is_empty,
  118. VarDesc *vars, VarDesc2 *vars2, int vars_total,
  119. const void **waits, int num_waits, const void **signal,
  120. int entry_id, const void *stack_addr,
  121. OffloadFlags offload_flags);
  122. bool offload_finish(bool is_traceback);
  123. bool is_signaled();
  124. OffloadHostTimerData* get_timer_data() const {
  125. return m_timer_data;
  126. }
  127. void set_stream(_Offload_stream stream) {
  128. m_stream = stream;
  129. }
  130. _Offload_stream get_stream() {
  131. return(m_stream);
  132. }
  133. Engine& get_device() {
  134. return m_device;
  135. }
  136. void* get_signal() {
  137. return(m_signal);
  138. }
  139. void set_signal(const void* signal) {
  140. m_has_signal = 1;
  141. m_signal = const_cast<void*>(signal);
  142. }
  143. void cleanup();
  144. uint32_t m_event_count;
  145. bool m_has_signal;
  146. private:
  147. bool offload_wrap(const char *name, bool is_empty,
  148. VarDesc *vars, VarDesc2 *vars2, int vars_total,
  149. const void **waits, int num_waits, const void **signal,
  150. int entry_id, const void *stack_addr,
  151. OffloadFlags offload_flags);
  152. bool wait_dependencies(const void **waits, int num_waits,
  153. _Offload_stream stream);
  154. bool setup_descriptors(VarDesc *vars, VarDesc2 *vars2, int vars_total,
  155. int entry_id, const void *stack_addr);
  156. bool setup_misc_data(const char *name);
  157. bool send_pointer_data(bool is_async, void* info);
  158. bool send_noncontiguous_pointer_data(
  159. int i,
  160. PtrData* src_buf,
  161. PtrData* dst_buf,
  162. COIEVENT *event,
  163. uint64_t &sent_data,
  164. uint32_t in_deps_amount,
  165. COIEVENT *in_deps
  166. );
  167. bool receive_noncontiguous_pointer_data(
  168. int i,
  169. COIBUFFER dst_buf,
  170. COIEVENT *event,
  171. uint64_t &received_data,
  172. uint32_t in_deps_amount,
  173. COIEVENT *in_deps
  174. );
  175. bool gather_copyin_data();
  176. bool compute(void *);
  177. bool receive_pointer_data(bool is_async, bool first_run, void * info);
  178. bool scatter_copyout_data();
  179. bool find_ptr_data(PtrData* &ptr_data, void *base, int64_t disp,
  180. int64_t length, bool is_targptr,
  181. bool error_does_not_exist = true);
  182. void find_device_ptr( int64_t* &device_ptr,
  183. void *host_ptr);
  184. bool alloc_ptr_data(PtrData* &ptr_data, void *base, int64_t disp,
  185. int64_t length, int64_t alloc_disp, int align,
  186. bool is_targptr, bool is_prealloc, bool pin);
  187. bool create_preallocated_buffer(PtrData* ptr_data, void *base);
  188. bool init_static_ptr_data(PtrData *ptr_data);
  189. bool init_mic_address(PtrData *ptr_data);
  190. bool offload_stack_memory_manager(
  191. const void * stack_begin,
  192. int routine_id,
  193. int buf_size,
  194. int align,
  195. bool thread_specific_function_locals,
  196. bool *is_new);
  197. char *get_this_threads_cpu_stack_addr(
  198. const void * stack_begin,
  199. int routine_id,
  200. bool thread_specific_function_locals);
  201. PtrData *get_this_threads_mic_stack_addr(
  202. const void * stack_begin,
  203. int routine_id,
  204. bool thread_specific_function_locals);
  205. bool nullify_target_stack(COIBUFFER targ_buf, uint64_t size);
  206. bool gen_var_descs_for_pointer_array(int i);
  207. void get_stream_in_dependencies(uint32_t &in_deps_amount,
  208. COIEVENT* &in_deps);
  209. void report_coi_error(error_types msg, COIRESULT res);
  210. _Offload_result translate_coi_error(COIRESULT res) const;
  211. void setup_omp_async_info();
  212. void setup_use_device_ptr(int i);
  213. void register_event_call_back(void (*)(
  214. COIEVENT,
  215. const COIRESULT,
  216. const void*),
  217. const COIEVENT *event,
  218. const void *info);
  219. void register_omp_event_call_back(const COIEVENT *event, const void *info);
  220. private:
  221. typedef std::list<COIBUFFER> BufferList;
  222. // extra data associated with each variable descriptor
  223. struct VarExtra {
  224. PtrData* src_data;
  225. PtrData* dst_data;
  226. AutoData* auto_data;
  227. int64_t cpu_disp;
  228. int64_t cpu_offset;
  229. void *alloc;
  230. union {
  231. CeanReadRanges *read_rng_src;
  232. NonContigDesc *noncont_desc;
  233. };
  234. CeanReadRanges *read_rng_dst;
  235. int64_t ptr_arr_offset;
  236. bool is_arr_ptr_el;
  237. OmpAsyncLastEventType omp_last_event_type;
  238. int64_t pointer_offset;
  239. uint16_t type_src;
  240. uint16_t type_dst;
  241. };
  242. template<typename T> class ReadArrElements {
  243. public:
  244. ReadArrElements():
  245. ranges(NULL),
  246. el_size(sizeof(T)),
  247. offset(0),
  248. count(0),
  249. is_empty(true),
  250. base(NULL)
  251. {}
  252. bool read_next(bool flag)
  253. {
  254. if (flag != 0) {
  255. if (is_empty) {
  256. if (ranges) {
  257. if (!get_next_range(ranges, &offset)) {
  258. // ranges are over
  259. return false;
  260. }
  261. }
  262. // all contiguous elements are over
  263. else if (count != 0) {
  264. return false;
  265. }
  266. length_cur = size;
  267. }
  268. else {
  269. offset += el_size;
  270. }
  271. val = (T)get_el_value(base, offset, el_size);
  272. length_cur -= el_size;
  273. count++;
  274. is_empty = length_cur == 0;
  275. }
  276. return true;
  277. }
  278. public:
  279. CeanReadRanges * ranges;
  280. T val;
  281. int el_size;
  282. int64_t size,
  283. offset,
  284. length_cur;
  285. bool is_empty;
  286. int count;
  287. char *base;
  288. };
  289. // ptr_data for persistent auto objects
  290. PtrData* m_stack_ptr_data;
  291. PtrDataList m_destroy_stack;
  292. // Engine
  293. Engine& m_device;
  294. // true for offload_wait target(mic) stream(0)
  295. bool m_wait_all_devices;
  296. // if true offload is mandatory
  297. bool m_is_mandatory;
  298. // if true offload has openmp origin
  299. const bool m_is_openmp;
  300. // The Marshaller for the inputs of the offloaded region.
  301. Marshaller m_in;
  302. // The Marshaller for the outputs of the offloaded region.
  303. Marshaller m_out;
  304. // List of buffers that are passed to dispatch call
  305. BufferList m_compute_buffers;
  306. // List of buffers that need to be destroyed at the end of offload
  307. BufferList m_destroy_buffers;
  308. // Variable descriptors
  309. VarDesc* m_vars;
  310. VarExtra* m_vars_extra;
  311. int m_vars_total;
  312. // Pointer to a user-specified status variable
  313. _Offload_status *m_status;
  314. // Function descriptor
  315. FunctionDescriptor* m_func_desc;
  316. uint32_t m_func_desc_size;
  317. // Buffer for transferring copyin/copyout data
  318. COIBUFFER m_inout_buf;
  319. // Dependencies
  320. COIEVENT *m_in_deps;
  321. uint32_t m_in_deps_total;
  322. uint32_t m_in_deps_allocated;
  323. COIEVENT *m_out_deps;
  324. uint32_t m_out_deps_total;
  325. uint32_t m_out_deps_allocated;
  326. // 2 variables defines input dependencies for current COI API.
  327. // The calls to routines as BufferWrite/PipelineRunFunction/BufferRead
  328. // is supposed to have input dependencies.
  329. // 2 variables below defines the number and vector of dependencies
  330. // in every current moment of offload.
  331. // So any phase of offload can use its values as input dependencies
  332. // for the COI API that the phase calls.
  333. // It means that all phases (of Write, RunFunction,Read) must keep
  334. // the variables correct to be used by following phase.
  335. // If some consequent offloads are connected (i.e. by the same stream)
  336. // the final 2 variables of the offload is used as initial inputs
  337. // for the next offload.
  338. uint32_t m_num_in_dependencies;
  339. COIEVENT *m_p_in_dependencies;
  340. // Stream
  341. _Offload_stream m_stream;
  342. // Signal
  343. void* m_signal;
  344. // Timer data
  345. OffloadHostTimerData *m_timer_data;
  346. // copyin/copyout data length
  347. uint64_t m_in_datalen;
  348. uint64_t m_out_datalen;
  349. // a boolean value calculated in setup_descriptors. If true we need to do
  350. // a run function on the target. Otherwise it may be optimized away.
  351. bool m_need_runfunction;
  352. // initialized value of m_need_runfunction;
  353. // is used to recognize offload_transfer
  354. bool m_initial_need_runfunction;
  355. // a Boolean value set to true when OUT clauses with preallocated targetptr
  356. // is encountered to indicate that call receive_pointer_data needs to be
  357. // invoked again after call to scatter_copyout_data.
  358. bool m_out_with_preallocated;
  359. // a Boolean value set to true if an alloc_if(1) is used with preallocated
  360. // targetptr to indicate the need to scatter_copyout_data even for
  361. // async offload
  362. bool m_preallocated_alloc;
  363. // a Boolean value set to true if traceback routine is called
  364. bool m_traceback_called;
  365. OmpAsyncLastEventType m_omp_async_last_event_type;
  366. };
  367. // Initialization types for MIC
  368. enum OffloadInitType {
  369. c_init_on_start, // all devices before entering main
  370. c_init_on_offload, // single device before starting the first offload
  371. c_init_on_offload_all // all devices before starting the first offload
  372. };
  373. // Determines if MIC code is an executable or a shared library
  374. extern "C" bool __offload_target_image_is_executable(const void *target_image);
  375. // Initializes library and registers specified offload image.
  376. extern "C" bool __offload_register_image(const void* image);
  377. extern "C" void __offload_unregister_image(const void* image);
  378. // Registers asynchronous task completion callback
  379. extern "C" void __offload_register_task_callback(void (*cb)(void *));
  380. // Initializes offload runtime library.
  381. DLL_LOCAL extern int __offload_init_library(void);
  382. // thread data for associating pipelines with threads
  383. DLL_LOCAL extern pthread_key_t mic_thread_key;
  384. // location of offload_main executable
  385. // To be used if the main application has no offload and is not built
  386. // with -offload but dynamic library linked in has offload pragma
  387. DLL_LOCAL extern char* mic_device_main;
  388. // Environment variables for devices
  389. DLL_LOCAL extern MicEnvVar mic_env_vars;
  390. // CPU frequency
  391. DLL_LOCAL extern uint64_t cpu_frequency;
  392. // LD_LIBRARY_PATH for KNC libraries
  393. DLL_LOCAL extern char* knc_library_path;
  394. // LD_LIBRARY_PATH for KNL libraries
  395. DLL_LOCAL extern char* knl_library_path;
  396. // stack size for target
  397. DLL_LOCAL extern uint32_t mic_stack_size;
  398. // Preallocated memory size for buffers on MIC
  399. DLL_LOCAL extern uint64_t mic_buffer_size;
  400. // Preallocated 4K page memory size for buffers on MIC
  401. DLL_LOCAL extern uint64_t mic_4k_buffer_size;
  402. // Preallocated 2M page memory size for buffers on MIC
  403. DLL_LOCAL extern uint64_t mic_2m_buffer_size;
  404. // Setting controlling inout proxy
  405. DLL_LOCAL extern bool mic_proxy_io;
  406. DLL_LOCAL extern char* mic_proxy_fs_root;
  407. // Threshold for creating buffers with large pages
  408. DLL_LOCAL extern uint64_t __offload_use_2mb_buffers;
  409. // offload initialization type
  410. DLL_LOCAL extern OffloadInitType __offload_init_type;
  411. // Device number to offload to when device is not explicitly specified.
  412. DLL_LOCAL extern int __omp_device_num;
  413. // target executable
  414. DLL_LOCAL extern TargetImage* __target_exe;
  415. // is true if last loaded image is dll
  416. DLL_LOCAL extern bool __current_image_is_dll;
  417. // is true if myo library is loaded when dll is loaded
  418. DLL_LOCAL extern bool __myo_init_in_so;
  419. // IDB support
  420. // Called by the offload runtime after initialization of offload infrastructure
  421. // has been completed.
  422. extern "C" void __dbg_target_so_loaded();
  423. // Called by the offload runtime when the offload infrastructure is about to be
  424. // shut down, currently at application exit.
  425. extern "C" void __dbg_target_so_unloaded();
  426. // Null-terminated string containing path to the process image of the hosting
  427. // application (offload_main)
  428. #define MAX_TARGET_NAME 512
  429. extern "C" char __dbg_target_exe_name[MAX_TARGET_NAME];
  430. // Integer specifying the process id
  431. extern "C" pid_t __dbg_target_so_pid;
  432. // Integer specifying the 0-based device number
  433. extern "C" int __dbg_target_id;
  434. // Set to non-zero by the host-side debugger to enable offload debugging
  435. // support
  436. extern "C" int __dbg_is_attached;
  437. // Major version of the debugger support API
  438. extern "C" const int __dbg_api_major_version;
  439. // Minor version of the debugger support API
  440. extern "C" const int __dbg_api_minor_version;
  441. #endif // OFFLOAD_HOST_H_INCLUDED