devicescratch.h
Go to the documentation of this file.
1 #ifndef TTG_PARSEC_DEVICESCRATCH_H
2 #define TTG_PARSEC_DEVICESCRATCH_H
3 
4 // TODO: replace with short vector
5 #define TTG_PARSEC_MAX_NUM_DEVICES 4
6 
7 #include <array>
8 #include <parsec.h>
9 #include <parsec/data_internal.h>
10 #include <parsec/mca/device/device.h>
11 #include <parsec/mca/device/device_gpu.h>
12 #include <ttg/devicescope.h>
13 #include "ttg/parsec/task.h"
14 
15 namespace ttg_parsec {
16 
17 namespace detail {
18  // fwd decl
19  template<typename T>
20  parsec_data_t* get_parsec_data(const ttg_parsec::devicescratch<T>&);
21 } // namespace detail
22 
28 template<typename T>
29 struct devicescratch {
30 
31  using element_type = std::decay_t<T>;
32 
33  static_assert(std::is_trivially_copyable_v<element_type>,
34  "Only trivially copyable types are supported for devices.");
35  static_assert(std::is_default_constructible_v<element_type>,
36  "Only default constructible types are supported for devices.");
37 
38 private:
39 
40  parsec_data_t* m_data = nullptr;
41  ttg::scope m_scope;
42 
43  static parsec_data_t* create_parsec_data(void *ptr, size_t count) {
44 
45  parsec_data_t *data = parsec_data_create_with_type(nullptr, 0, ptr,
46  sizeof(element_type)*count,
47  parsec_datatype_int8_t);
48  data->device_copies[0]->flags |= PARSEC_DATA_FLAG_PARSEC_MANAGED;
49  data->device_copies[0]->coherency_state = PARSEC_DATA_COHERENCY_SHARED;
50  return data;
51  }
52 
53  void remove_from_flow() {
54  /* remove the scratch from the gpu-task flow */
55  assert(nullptr != detail::parsec_ttg_caller);
56  parsec_task_t *parsec_task = &detail::parsec_ttg_caller->parsec_task;
57  parsec_flow_t *flows = detail::parsec_ttg_caller->dev_ptr->flows;
58  for (int i = 0; i < MAX_PARAM_COUNT; ++i) {
59  if (nullptr != parsec_task->data[i].data_in && parsec_task->data[i].data_in->original == m_data) {
60  flows[i].flow_flags = PARSEC_FLOW_ACCESS_NONE; // disable this flow
61  break;
62  }
63  }
64  }
65 
66  friend parsec_data_t* detail::get_parsec_data<T>(const ttg_parsec::devicescratch<T>&);
67 
68 public:
69 
70  /* Constructing a devicescratch using application-managed memory.
71  * The memory pointed to by ptr must be accessible during
72  * the life-time of the devicescratch. */
74  : m_data(create_parsec_data(ptr, count))
75  , m_scope(scope)
76  {
77  if (ttg::scope::SyncIn == scope) {
78  /* increment the version to force the first initial transfer */
79  m_data->device_copies[0]->version = 1;
80  }
81  }
82 
83  /* don't allow moving */
85 
86  /* don't allow copying */
87  devicescratch(const devicescratch& db) = delete;
88 
89  /* don't allow moving */
91 
92  /* don't allow copying */
93  devicescratch& operator=(const devicescratch& db) = delete;
94 
96  /* remove data from flow */
97  //remove_from_flow();
98  if (nullptr != m_data) {
99  //parsec_data_destroy(m_data);
100  //parsec_data_copy_detach(m_data, parsec_data_get_copy(m_data, 0), 0);
101  //auto *copy = parsec_data_get_copy(m_data, 0);
102  //PARSEC_OBJ_RELEASE(copy);
103  }
104  //parsec_data_destroy(m_data);
105  m_data = nullptr;
106  }
107 
108  /* get the current device pointer */
110  assert(is_valid());
111  return static_cast<element_type*>(m_data->device_copies[m_data->owner_device]->device_private);
112  }
113 
114  /* get the current device pointer */
115  const element_type* device_ptr() const {
116  assert(is_valid());
117  return static_cast<element_type*>(m_data->device_copies[m_data->owner_device]->device_private);
118  }
119 
120  bool is_valid() const {
121  // TODO: how to get the current device
122  // return (m_data->owner_device == parsec_current_device);
123  return true;
124  }
125 
126  ttg::scope scope() const {
127  return m_scope;
128  }
129 
130  std::size_t size() const {
131  return (m_data->nb_elts / sizeof(element_type));
132  }
133 
134 };
135 
136 namespace detail {
137  template<typename T>
138  parsec_data_t* get_parsec_data(const ttg_parsec::devicescratch<T>& scratch) {
139  return const_cast<parsec_data_t*>(scratch.m_data);
140  }
141 } // namespace detail
142 
143 } // namespace ttg_parsec
144 
145 #endif // TTG_PARSEC_DEVICESCRATCH_H
constexpr auto data(C &c) -> decltype(c.data())
Definition: span.h:189
parsec_data_t * get_parsec_data(const ttg_parsec::Buffer< T, A > &db)
Definition: buffer.h:393
thread_local parsec_ttg_task_base_t * parsec_ttg_caller
Definition: thread_local.h:12
this contains PaRSEC-based TTG functionality
Definition: fwd.h:18
scope
Definition: devicescope.h:5
parsec_flow_t * flows
Definition: task.h:15
std::decay_t< T > element_type
Definition: devicescratch.h:31
devicescratch & operator=(devicescratch &&)=delete
devicescratch(devicescratch &&)=delete
ttg::scope scope() const
devicescratch(const devicescratch &db)=delete
devicescratch(element_type *ptr, ttg::scope scope=ttg::scope::SyncIn, std::size_t count=1)
Definition: devicescratch.h:73
devicescratch & operator=(const devicescratch &db)=delete
element_type * device_ptr()
const element_type * device_ptr() const
std::size_t size() const