Advertisement
Guest User

Untitled

a guest
Mar 30th, 2017
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.67 KB | None | 0 0
  1. #include <iostream>
  2. #include <typeinfo>
  3.  
  4. #include <vtkm/cont/ArrayHandle.h>
  5. #include <vtkm/cont/RuntimeDeviceInformation.h>
  6.  
  7. #include <vtkm/cont/cuda/DeviceAdapterCuda.h>
  8. #include <vtkm/cont/serial/DeviceAdapterSerial.h>
  9. #include <vtkm/cont/TryExecute.h>
  10.  
  11. #include <vtkm/exec/cuda/internal/ArrayPortalFromThrust.h>
  12.  
  13. // Step 1: For each virtual-like method create a function (in a detail
  14. // namespace) that takes a void pointer to a concrete class and then calls the
  15. // method on the class after performing a reinterpret_cast. The function will
  16. // certainly be templated, but should not be overloaded. You need to be able
  17. // to fully specify the function without arguments.
  18. template<typename PortalType>
  19. __device__ __host__
  20. vtkm::Id ArrayPortalVirtualGetNumberOfValues(void *portalPointer)
  21. {
  22. PortalType* portalRef = reinterpret_cast<PortalType*>(portalPointer);
  23. return portalRef->GetNumberOfValues();
  24. }
  25.  
  26.  
  27. template<typename PortalType, typename ValueType>
  28. __device__ __host__
  29. ValueType ArrayPortalVirtualGet(void *portalPointer, vtkm::Id index)
  30. {
  31. PortalType* portalRef = reinterpret_cast<PortalType*>(portalPointer);
  32. return static_cast<ValueType>(portalRef->Get(index));
  33. }
  34.  
  35. template<typename PortalType, typename ValueType>
  36. __device__ __host__
  37. void ArrayPortalVirtualSet(void *portalPointer,
  38. vtkm::Id index,
  39. const ValueType &value)
  40. {
  41. PortalType* portalRef = reinterpret_cast<PortalType*>(portalPointer);
  42. portalRef->Set(index, value);
  43. }
  44.  
  45.  
  46. template<typename PortalType, typename ValueType>
  47. __global__ void construct_functions(void** numvalue, void** get, void** set)
  48. {
  49. typedef vtkm::Id(*GetNumberOfValuesSignature)(void*);
  50. typedef ValueType(*GetSignature)(void *, vtkm::Id);
  51. typedef void(*SetSignature)(void *, vtkm::Id, const ValueType &);
  52.  
  53. {
  54. GetNumberOfValuesSignature* n = reinterpret_cast<GetNumberOfValuesSignature*>(numvalue);
  55. *n = &ArrayPortalVirtualGetNumberOfValues<PortalType>;
  56. printf("From Device: n1 = %p \n", *n);
  57. }
  58.  
  59. {
  60. GetSignature* n = reinterpret_cast<GetSignature*>(get);
  61. *n = &ArrayPortalVirtualGet<PortalType>;
  62. printf("From Device: n2 = %p \n", *n);
  63. }
  64.  
  65. {
  66. SetSignature* n = reinterpret_cast<SetSignature*>(set);
  67. *n = &ArrayPortalVirtualSet<PortalType>;
  68. printf("From Device: n3 = %p \n", *n);
  69. }
  70. }
  71.  
  72.  
  73. // Step 2: Create copy functions for each portal type
  74.  
  75. template<typename PortalType, typename ValueType, typename NumValueSig, typename GetSig, typename SetSig>
  76. inline
  77. void CopyFunctionPointers(NumValueSig& destNumValuePointer,
  78. GetSig& destGetPointer,
  79. SetSig& destSetPointer,
  80. vtkm::cont::DeviceAdapterTagCuda)
  81. {
  82. NumValueSig device_NumValuePointer;
  83. cudaMalloc(&device_NumValuePointer, sizeof(NumValueSig));
  84.  
  85. GetSig device_GetPointer;
  86. cudaMalloc(&device_GetPointer, sizeof(GetSig));
  87.  
  88. SetSig device_SetPointer;
  89. cudaMalloc(&device_SetPointer, sizeof(SetSig));
  90.  
  91. construct_functions<PortalType, ValueType><<<1,1>>>((void**)device_NumValuePointer,
  92. (void**)device_GetPointer,
  93. (void**)device_SetPointer);
  94.  
  95. cudaDeviceSynchronize();
  96. cudaError_t error = cudaGetLastError();
  97. printf("CUDA state after construct launch: %s\n", cudaGetErrorString(error));
  98.  
  99. cudaMemcpy((void**)&destNumValuePointer, (void*)device_NumValuePointer,
  100. sizeof(NumValueSig), cudaMemcpyDeviceToHost);
  101.  
  102. cudaMemcpy((void**)&destGetPointer, (void*)device_GetPointer, sizeof(GetSig),
  103. cudaMemcpyDeviceToHost);
  104.  
  105. cudaMemcpy((void**)&destSetPointer, (void*)device_SetPointer, sizeof(SetSig),
  106. cudaMemcpyDeviceToHost);
  107.  
  108. cudaDeviceSynchronize();
  109. error = cudaGetLastError();
  110. printf("CUDA state after mempcy launch: %s\n", cudaGetErrorString(error));
  111.  
  112. printf("From Host: n1 = %p\n", destNumValuePointer);
  113. printf("From Host: n2 = %p\n", destGetPointer);
  114. printf("From Host: n3 = %p\n", destSetPointer);
  115.  
  116. }
  117.  
  118. template<typename PortalType, typename ValueType, typename NumValueSig, typename GetSig, typename SetSig>
  119. inline
  120. void CopyFunctionPointers(NumValueSig& destNumValuePointer,
  121. GetSig& destGetPointer,
  122. SetSig& destSetPointer,
  123. vtkm::cont::DeviceAdapterTagSerial)
  124. {
  125. destNumValuePointer = &ArrayPortalVirtualGetNumberOfValues<PortalType>;
  126. destGetPointer = &ArrayPortalVirtualGet<PortalType, ValueType>;
  127. destSetPointer = &ArrayPortalVirtualSet<PortalType, ValueType>;
  128. }
  129.  
  130. // Step 3: Create the struct or class that has virtual-like methods as normal.
  131. // There should be no actual virtual methods.
  132.  
  133. template<typename ValueType>
  134. class ArrayPortalVirtual
  135. {
  136.  
  137. // Step 4: For each virtual-like method, create a typedef for the signature
  138. // of the function accessor you created earlier in the class.
  139. typedef vtkm::Id(*GetNumberOfValuesSignature)(void*);
  140. typedef ValueType(*GetSignature)(void *, vtkm::Id);
  141. typedef void(*SetSignature)(void *, vtkm::Id, const ValueType &);
  142.  
  143. // Step 5: For each virtual-like method, create a member variable in the
  144. // class with the type of the associated signature.
  145.  
  146. GetNumberOfValuesSignature GetNumberOfValuesFunction;
  147. GetSignature GetFunction;
  148. SetSignature SetFunction;
  149.  
  150. // Step 6: The class should also have a void* member variable for a
  151. // reference to the concrete class.
  152.  
  153. void *SrcPortal;
  154.  
  155. public:
  156.  
  157. // Step 7: Create a constructor for the class. The constructor should be
  158. // templated on the concrete class you are calling methods on as well as a
  159. // device adapter tag. One of the arguments should be a pointer to an
  160. // instance of the concrete class. The constructor should initialize its
  161. // function pointer members using CopyFunctionPointer.
  162.  
  163. template<typename PortalType, typename Device>
  164. __host__
  165. ArrayPortalVirtual(PortalType *portal, Device)
  166. : SrcPortal(portal)
  167. {
  168. CopyFunctionPointers<PortalType,ValueType>( this->GetNumberOfValuesFunction,
  169. this->GetFunction,
  170. this->SetFunction,
  171. Device());
  172. }
  173.  
  174. // Step 8: For each virtual-like method, create an implementation of that
  175. // method that calls the associated function pointer.
  176. __device__ __host__
  177. vtkm::Id GetNumberOfValues() const
  178. {
  179. return this->GetNumberOfValuesFunction(this->SrcPortal);
  180. }
  181. __device__ __host__
  182. ValueType Get(vtkm::Id index) const
  183. {
  184. return this->GetFunction(this->SrcPortal, index);
  185. }
  186. __device__ __host__
  187. void Set(vtkm::Id index, const ValueType &value) const
  188. {
  189. this->SetFunction(this->SrcPortal, index, value);
  190. }
  191. };
  192.  
  193.  
  194. __global__ void kernel(ArrayPortalVirtual<int> ints,
  195. ArrayPortalVirtual<float> floats)
  196. {
  197. { printf("hello world\n"); }
  198. { printf("i value = %d", ints.Get(1)); }
  199. // { printf("f value = %d", floats.Get(1)); }
  200. }
  201.  
  202.  
  203.  
  204. int main(int, char**)
  205. {
  206. cudaError_t error;
  207.  
  208. //make some cuda memory and map it to a portal
  209. using vtkm::exec::cuda::internal::ArrayPortalFromThrust;
  210. thrust::system::cuda::vector<double> data(1024);
  211. ArrayPortalFromThrust<double> portal(data.data(),data.data()+1023);
  212.  
  213.  
  214. //wrap that cuda memory in two virtual portals
  215. ArrayPortalVirtual<int> virt_int(&portal, vtkm::cont::DeviceAdapterTagCuda());
  216. ArrayPortalVirtual<float> virt_float(&portal, vtkm::cont::DeviceAdapterTagCuda());
  217.  
  218. //need to launch a kernel to verify everything is working properly
  219. cudaDeviceSynchronize();
  220. error = cudaGetLastError();
  221. printf("CUDA state before kernel launch: %s\n", cudaGetErrorString(error));
  222.  
  223. kernel<<<1,1>>>(virt_int, virt_float);
  224. cudaDeviceSynchronize();
  225. error = cudaGetLastError();
  226. printf("CUDA state after kernel launch: %s\n", cudaGetErrorString(error));
  227.  
  228. return 0;
  229. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement