offload_common.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. /*
  2. Copyright (c) 2014 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 common to host and target
  28. */
  29. #ifndef OFFLOAD_COMMON_H_INCLUDED
  30. #define OFFLOAD_COMMON_H_INCLUDED
  31. #include <stdio.h>
  32. #include <stdlib.h>
  33. #include <string.h>
  34. #include <memory.h>
  35. #if (defined(LINUX) || defined(FREEBSD)) && !defined(__INTEL_COMPILER)
  36. #include <mm_malloc.h>
  37. #endif
  38. #include "offload.h"
  39. #include "offload_table.h"
  40. #include "offload_trace.h"
  41. #include "offload_timer.h"
  42. #include "offload_util.h"
  43. #include "cean_util.h"
  44. #include "dv_util.h"
  45. #include "liboffload_error_codes.h"
  46. #include <stdarg.h>
  47. // Use secure getenv if it's supported
  48. #ifdef HAVE_SECURE_GETENV
  49. #define getenv(x) secure_getenv(x)
  50. #elif HAVE___SECURE_GETENV
  51. #define getenv(x) __secure_getenv(x)
  52. #endif
  53. // The debug routines
  54. // Host console and file logging
  55. extern int console_enabled;
  56. extern int offload_report_level;
  57. #define OFFLOAD_DO_TRACE (offload_report_level == 3)
  58. extern const char *prefix;
  59. extern int offload_number;
  60. #if !HOST_LIBRARY
  61. extern int mic_index;
  62. #endif
  63. #if HOST_LIBRARY
  64. void Offload_Report_Prolog(OffloadHostTimerData* timer_data);
  65. void Offload_Report_Epilog(OffloadHostTimerData* timer_data);
  66. void offload_report_free_data(OffloadHostTimerData * timer_data);
  67. void Offload_Timer_Print(void);
  68. #ifndef TARGET_WINNT
  69. #define OFFLOAD_DEBUG_INCR_OFLD_NUM() \
  70. __sync_add_and_fetch(&offload_number, 1)
  71. #else
  72. #define OFFLOAD_DEBUG_INCR_OFLD_NUM() \
  73. _InterlockedIncrement(reinterpret_cast<long*>(&offload_number))
  74. #endif
  75. #define OFFLOAD_DEBUG_PRINT_TAG_PREFIX() \
  76. printf("%s: ", prefix);
  77. #define OFFLOAD_DEBUG_PRINT_PREFIX() \
  78. printf("%s: ", prefix);
  79. #else
  80. #define OFFLOAD_DEBUG_PRINT_PREFIX() \
  81. printf("%s%d: ", prefix, mic_index);
  82. #endif // HOST_LIBRARY
  83. #define OFFLOAD_TRACE(trace_level, ...) \
  84. if (console_enabled >= trace_level) { \
  85. OFFLOAD_DEBUG_PRINT_PREFIX(); \
  86. printf(__VA_ARGS__); \
  87. fflush(NULL); \
  88. }
  89. #if OFFLOAD_DEBUG > 0
  90. #define OFFLOAD_DEBUG_TRACE(level, ...) \
  91. OFFLOAD_TRACE(level, __VA_ARGS__)
  92. #define OFFLOAD_REPORT(level, offload_number, stage, ...) \
  93. if (OFFLOAD_DO_TRACE) { \
  94. offload_stage_print(stage, offload_number, __VA_ARGS__); \
  95. fflush(NULL); \
  96. }
  97. #define OFFLOAD_DEBUG_TRACE_1(level, offload_number, stage, ...) \
  98. if (OFFLOAD_DO_TRACE) { \
  99. offload_stage_print(stage, offload_number, __VA_ARGS__); \
  100. fflush(NULL); \
  101. } \
  102. if (!OFFLOAD_DO_TRACE) { \
  103. OFFLOAD_TRACE(level, __VA_ARGS__) \
  104. }
  105. #define OFFLOAD_DEBUG_DUMP_BYTES(level, a, b) \
  106. __dump_bytes(level, a, b)
  107. extern void __dump_bytes(
  108. int level,
  109. const void *data,
  110. int len
  111. );
  112. #else
  113. #define OFFLOAD_DEBUG_LOG(level, ...)
  114. #define OFFLOAD_DEBUG_DUMP_BYTES(level, a, b)
  115. #endif
  116. // Runtime interface
  117. #define OFFLOAD_PREFIX(a) __offload_##a
  118. #define OFFLOAD_MALLOC OFFLOAD_PREFIX(malloc)
  119. #define OFFLOAD_FREE(a) _mm_free(a)
  120. // Forward functions
  121. extern void *OFFLOAD_MALLOC(size_t size, size_t align);
  122. // The Marshaller
  123. //! \enum Indicator for the type of entry on an offload item list.
  124. enum OffloadItemType {
  125. c_data = 1, //!< Plain data
  126. c_data_ptr, //!< Pointer data
  127. c_func_ptr, //!< Function pointer
  128. c_void_ptr, //!< void*
  129. c_string_ptr, //!< C string
  130. c_dv, //!< Dope vector variable
  131. c_dv_data, //!< Dope-vector data
  132. c_dv_data_slice, //!< Dope-vector data's slice
  133. c_dv_ptr, //!< Dope-vector variable pointer
  134. c_dv_ptr_data, //!< Dope-vector pointer data
  135. c_dv_ptr_data_slice,//!< Dope-vector pointer data's slice
  136. c_cean_var, //!< CEAN variable
  137. c_cean_var_ptr, //!< Pointer to CEAN variable
  138. c_data_ptr_array, //!< Pointer to data pointer array
  139. c_func_ptr_array, //!< Pointer to function pointer array
  140. c_void_ptr_array, //!< Pointer to void* pointer array
  141. c_string_ptr_array //!< Pointer to char* pointer array
  142. };
  143. #define VAR_TYPE_IS_PTR(t) ((t) == c_string_ptr || \
  144. (t) == c_data_ptr || \
  145. (t) == c_cean_var_ptr || \
  146. (t) == c_dv_ptr)
  147. #define VAR_TYPE_IS_SCALAR(t) ((t) == c_data || \
  148. (t) == c_void_ptr || \
  149. (t) == c_cean_var || \
  150. (t) == c_dv)
  151. #define VAR_TYPE_IS_DV_DATA(t) ((t) == c_dv_data || \
  152. (t) == c_dv_ptr_data)
  153. #define VAR_TYPE_IS_DV_DATA_SLICE(t) ((t) == c_dv_data_slice || \
  154. (t) == c_dv_ptr_data_slice)
  155. //! \enum Specify direction to copy offloaded variable.
  156. enum OffloadParameterType {
  157. c_parameter_unknown = -1, //!< Unknown clause
  158. c_parameter_nocopy, //!< Variable listed in "nocopy" clause
  159. c_parameter_in, //!< Variable listed in "in" clause
  160. c_parameter_out, //!< Variable listed in "out" clause
  161. c_parameter_inout //!< Variable listed in "inout" clause
  162. };
  163. //! An Offload Variable descriptor
  164. struct VarDesc {
  165. //! OffloadItemTypes of source and destination
  166. union {
  167. struct {
  168. uint8_t dst : 4; //!< OffloadItemType of destination
  169. uint8_t src : 4; //!< OffloadItemType of source
  170. };
  171. uint8_t bits;
  172. } type;
  173. //! OffloadParameterType that describes direction of data transfer
  174. union {
  175. struct {
  176. uint8_t in : 1; //!< Set if IN or INOUT
  177. uint8_t out : 1; //!< Set if OUT or INOUT
  178. };
  179. uint8_t bits;
  180. } direction;
  181. uint8_t alloc_if; //!< alloc_if modifier value
  182. uint8_t free_if; //!< free_if modifier value
  183. uint32_t align; //!< MIC alignment requested for pointer data
  184. //! Not used by compiler; set to 0
  185. /*! Used by runtime as offset to data from start of MIC buffer */
  186. uint32_t mic_offset;
  187. //! Flags describing this variable
  188. union {
  189. struct {
  190. //! source variable has persistent storage
  191. uint32_t is_static : 1;
  192. //! destination variable has persistent storage
  193. uint32_t is_static_dstn : 1;
  194. //! has length for c_dv && c_dv_ptr
  195. uint32_t has_length : 1;
  196. //! persisted local scalar is in stack buffer
  197. uint32_t is_stack_buf : 1;
  198. //! buffer address is sent in data
  199. uint32_t sink_addr : 1;
  200. //! alloc displacement is sent in data
  201. uint32_t alloc_disp : 1;
  202. //! source data is noncontiguous
  203. uint32_t is_noncont_src : 1;
  204. //! destination data is noncontiguous
  205. uint32_t is_noncont_dst : 1;
  206. };
  207. uint32_t bits;
  208. } flags;
  209. //! Not used by compiler; set to 0
  210. /*! Used by runtime as offset to base from data stored in a buffer */
  211. int64_t offset;
  212. //! Element byte-size of data to be transferred
  213. /*! For dope-vector, the size of the dope-vector */
  214. int64_t size;
  215. union {
  216. //! Set to 0 for array expressions and dope-vectors
  217. /*! Set to 1 for scalars */
  218. /*! Set to value of length modifier for pointers */
  219. int64_t count;
  220. //! Displacement not used by compiler
  221. int64_t disp;
  222. };
  223. //! This field not used by OpenMP 4.0
  224. /*! The alloc section expression in #pragma offload */
  225. union {
  226. void *alloc;
  227. int64_t ptr_arr_offset;
  228. };
  229. //! This field not used by OpenMP 4.0
  230. /*! The into section expression in #pragma offload */
  231. /*! For c_data_ptr_array this is the into ptr array */
  232. void *into;
  233. //! For an ordinary variable, address of the variable
  234. /*! For c_cean_var (C/C++ array expression),
  235. pointer to arr_desc, which is an array descriptor. */
  236. /*! For c_data_ptr_array (array of data pointers),
  237. pointer to ptr_array_descriptor,
  238. which is a descriptor for pointer array transfers. */
  239. void *ptr;
  240. };
  241. //! Auxiliary struct used when -g is enabled that holds variable names
  242. struct VarDesc2 {
  243. const char *sname; //!< Source name
  244. const char *dname; //!< Destination name (when "into" is used)
  245. };
  246. /*! When the OffloadItemType is c_data_ptr_array
  247. the ptr field of the main descriptor points to this struct. */
  248. /*! The type in VarDesc1 merely says c_cean_data_ptr, but the pointer
  249. type can be c_data_ptr, c_func_ptr, c_void_ptr, or c_string_ptr.
  250. Therefore the actual pointer type is in the flags field of VarDesc3. */
  251. /*! If flag_align_is_array/flag_alloc_if_is_array/flag_free_if_is_array
  252. is 0 then alignment/alloc_if/free_if are specified in VarDesc1. */
  253. /*! If flag_align_is_array/flag_alloc_if_is_array/flag_free_if_is_array
  254. is 1 then align_array/alloc_if_array/free_if_array specify
  255. the set of alignment/alloc_if/free_if values. */
  256. /*! For the other fields, if neither the scalar nor the array flag
  257. is set, then that modifier was not specified. If the bits are set
  258. they specify which modifier was set and whether it was a
  259. scalar or an array expression. */
  260. struct VarDesc3
  261. {
  262. void *ptr_array; //!< Pointer to arr_desc of array of pointers
  263. void *align_array; //!< Scalar value or pointer to arr_desc
  264. void *alloc_if_array; //!< Scalar value or pointer to arr_desc
  265. void *free_if_array; //!< Scalar value or pointer to arr_desc
  266. void *extent_start; //!< Scalar value or pointer to arr_desc
  267. void *extent_elements; //!< Scalar value or pointer to arr_desc
  268. void *into_start; //!< Scalar value or pointer to arr_desc
  269. void *into_elements; //!< Scalar value or pointer to arr_desc
  270. void *alloc_start; //!< Scalar value or pointer to arr_desc
  271. void *alloc_elements; //!< Scalar value or pointer to arr_desc
  272. /*! Flags that describe the pointer type and whether each field
  273. is a scalar value or an array expression. */
  274. /*! First 6 bits are pointer array element type:
  275. c_data_ptr, c_func_ptr, c_void_ptr, c_string_ptr */
  276. /*! Then single bits specify: */
  277. /*! align_array is an array */
  278. /*! alloc_if_array is an array */
  279. /*! free_if_array is an array */
  280. /*! extent_start is a scalar expression */
  281. /*! extent_start is an array expression */
  282. /*! extent_elements is a scalar expression */
  283. /*! extent_elements is an array expression */
  284. /*! into_start is a scalar expression */
  285. /*! into_start is an array expression */
  286. /*! into_elements is a scalar expression */
  287. /*! into_elements is an array expression */
  288. /*! alloc_start is a scalar expression */
  289. /*! alloc_start is an array expression */
  290. /*! alloc_elements is a scalar expression */
  291. /*! alloc_elements is an array expression */
  292. uint32_t array_fields;
  293. };
  294. const int flag_align_is_array = 6;
  295. const int flag_alloc_if_is_array = 7;
  296. const int flag_free_if_is_array = 8;
  297. const int flag_extent_start_is_scalar = 9;
  298. const int flag_extent_start_is_array = 10;
  299. const int flag_extent_elements_is_scalar = 11;
  300. const int flag_extent_elements_is_array = 12;
  301. const int flag_into_start_is_scalar = 13;
  302. const int flag_into_start_is_array = 14;
  303. const int flag_into_elements_is_scalar = 15;
  304. const int flag_into_elements_is_array = 16;
  305. const int flag_alloc_start_is_scalar = 17;
  306. const int flag_alloc_start_is_array = 18;
  307. const int flag_alloc_elements_is_scalar = 19;
  308. const int flag_alloc_elements_is_array = 20;
  309. // The Marshaller
  310. class Marshaller
  311. {
  312. private:
  313. // Start address of buffer
  314. char *buffer_start;
  315. // Current pointer within buffer
  316. char *buffer_ptr;
  317. // Physical size of data sent (including flags)
  318. long long buffer_size;
  319. // User data sent/received
  320. long long tfr_size;
  321. public:
  322. // Constructor
  323. Marshaller() :
  324. buffer_start(0), buffer_ptr(0),
  325. buffer_size(0), tfr_size(0)
  326. {
  327. }
  328. // Return count of user data sent/received
  329. long long get_tfr_size() const
  330. {
  331. return tfr_size;
  332. }
  333. // Return pointer to buffer
  334. char *get_buffer_start() const
  335. {
  336. return buffer_start;
  337. }
  338. // Return current size of data in buffer
  339. long long get_buffer_size() const
  340. {
  341. return buffer_size;
  342. }
  343. // Set buffer pointer
  344. void init_buffer(
  345. char *d,
  346. long long s
  347. )
  348. {
  349. buffer_start = buffer_ptr = d;
  350. buffer_size = s;
  351. }
  352. // Send data
  353. void send_data(
  354. const void *data,
  355. int64_t length
  356. );
  357. // Receive data
  358. void receive_data(
  359. void *data,
  360. int64_t length
  361. );
  362. // Send function pointer
  363. void send_func_ptr(
  364. const void* data
  365. );
  366. // Receive function pointer
  367. void receive_func_ptr(
  368. const void** data
  369. );
  370. };
  371. // End of the Marshaller
  372. // The offloaded function descriptor.
  373. // Sent from host to target to specify which function to run.
  374. // Also, sets console and file tracing levels.
  375. struct FunctionDescriptor
  376. {
  377. // Input data size.
  378. long long in_datalen;
  379. // Output data size.
  380. long long out_datalen;
  381. // Whether trace is requested on console.
  382. // A value of 1 produces only function name and data sent/received.
  383. // Values > 1 produce copious trace information.
  384. uint8_t console_enabled;
  385. // Flag controlling timing on the target side.
  386. // Values > 0 enable timing on sink.
  387. uint8_t timer_enabled;
  388. int offload_report_level;
  389. int offload_number;
  390. // number of variable descriptors
  391. int vars_num;
  392. // inout data offset if data is passed as misc/return data
  393. // otherwise it should be zero.
  394. int data_offset;
  395. // The name of the offloaded function
  396. char data[];
  397. };
  398. // typedef OFFLOAD.
  399. // Pointer to OffloadDescriptor.
  400. typedef struct OffloadDescriptor *OFFLOAD;
  401. #endif // OFFLOAD_COMMON_H_INCLUDED