device_wrapper.hpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /**
  2. * \file device_wrapper.hpp
  3. * \author Dhairya Malhotra, dhairya.malhotra@gmail.com
  4. * \date 6-5-2013
  5. * \brief This file contains definition of DeviceWrapper.
  6. */
  7. #include <cstdlib>
  8. #include <stdint.h>
  9. // Cuda Headers
  10. #if defined(PVFMM_HAVE_CUDA)
  11. #include <cuda_runtime_api.h>
  12. #include <cublas_v2.h>
  13. #endif
  14. #include <pvfmm_common.hpp>
  15. #include <vector.hpp>
  16. #ifndef _PVFMM_DEVICE_WRAPPER_HPP_
  17. #define _PVFMM_DEVICE_WRAPPER_HPP_
  18. #ifdef __INTEL_OFFLOAD
  19. #pragma offload_attribute(push,target(mic))
  20. #endif
  21. namespace pvfmm{
  22. namespace DeviceWrapper{
  23. void* host_malloc(size_t size);
  24. void host_free(void*);
  25. uintptr_t alloc_device(char* dev_handle, size_t len);
  26. void free_device(char* dev_handle, uintptr_t dev_ptr);
  27. template <int SYNC=__DEVICE_SYNC__>
  28. int host2device(char* host_ptr, char* dev_handle, uintptr_t dev_ptr, size_t len);
  29. template <int SYNC=__DEVICE_SYNC__>
  30. int device2host(char* dev_handle, uintptr_t dev_ptr, char* host_ptr, size_t len);
  31. void wait(int lock_idx);
  32. }//end namespace
  33. /*
  34. Usage of 'MIC_Lock' in Asynchronous Offloads
  35. --------------------------------------------
  36. Note: Any MIC offload section should look like this:
  37. int wait_lock_idx=MIC_Lock::curr_lock();
  38. int lock_idx=MIC_Lock::get_lock();
  39. #pragma offload target(mic:0) signal(&MIC_Lock::lock_vec[lock_idx])
  40. {
  41. MIC_Lock::wait_lock(wait_lock_idx);
  42. // Offload code here...
  43. MIC_Lock::release_lock(lock_idx);
  44. }
  45. #ifdef __DEVICE_SYNC__
  46. MIC_Lock::wait_lock(lock_idx);
  47. #endif
  48. This ensures the execution of offloaded code does not overlap with other
  49. asynchronous offloaded code and that data transfers from host to mic have
  50. completed before the data is accessed. You will however, need to be careful
  51. not to overwrite data on mic which may be transferring to the host, or data on
  52. the host which may be transferring to the mic.
  53. On the host, to wait for the last asynchronous offload section or data
  54. transfer, use:
  55. int wait_lock_idx=MIC_Lock::curr_lock();
  56. MIC_Lock::wait_lock(wait_lock_idx);
  57. */
  58. class MIC_Lock{
  59. public:
  60. static void init();
  61. static int get_lock();
  62. static void release_lock(int idx);
  63. static void wait_lock(int idx);
  64. static int curr_lock();
  65. static Vector<char> lock_vec;
  66. static Vector<char>::Device lock_vec_;
  67. private:
  68. MIC_Lock(){}; // private constructor for static class.
  69. static int lock_idx;
  70. };
  71. #if defined(PVFMM_HAVE_CUDA)
  72. class CUDA_Lock {
  73. public:
  74. static void init(size_t num_stream=1);
  75. static void finalize();
  76. static cudaStream_t *acquire_stream(int idx=0);
  77. static cublasHandle_t *acquire_handle();
  78. static void wait(int idx=0);
  79. private:
  80. CUDA_Lock();
  81. static std::vector<cudaStream_t> stream;
  82. static cublasHandle_t handle;
  83. };
  84. #endif
  85. }//end namespace
  86. #ifdef __INTEL_OFFLOAD
  87. #pragma offload_attribute(pop)
  88. #endif
  89. #include <device_wrapper.txx>
  90. #endif //_PVFMM_DEVICE_WRAPPER_HPP_