<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Dec 12, 2020 at 10:44 AM Barry Smith <<a href="mailto:bsmith@petsc.dev">bsmith@petsc.dev</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br>
   Currently we use PetscScalar and PetscScalar * to refer to variables that could be in any memory space. On the CPU, on the GPU, in Kokkos, etc.<br>
<br>
   Would it make sense to use typedef to indicate at each location the true type of the memory location when possible? <br></blockquote><div><br></div><div>No. Absolutely not.</div><div><br></div><div>Because Cuda is simple C code (eg, printf is provided but few standard libs are provided and you can't call non-device functions from the device), you can put kernels in a header file and include it in the .cu file to get Cuda code. You need to #define things like the device declaration syntax (eg __device__) and things like atomicAdd. This is how MatSetValuesDevice works.</div><div><br></div><div>The way I do deep copies in Cuda I declare a host a device struct, like:</div><div><br></div><div>Mat h_mat, *d_mat.</div><div><br></div><div>Then do cuda mallocs into pointers in h_mat, then a cuda malloc on to get d_mat. Then a cuda copy-to-device to put any data (cuda malloced) or metadata (eg, array size, dim, etc) from h_mat into d_mat. I don't know how I could do this if h_mat and d_mat are not the same without even more gymnastics.</div><div><br></div><div>The Kokkos people have been working with this for a long time and I think they have probably learned the hard way what works. I would look at what they do. If they or SYCL does it I would take a look.</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
   typedef PetscReal PetscKokkosReal   means the variable is in the Kokkos memory space<br></blockquote><div><br></div><div>There is no such thing. THere is the default execution space, default host space, Cuda memory space, etc.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
   typedef PetscReal PetscCUDAReal<br>
   typedef PetscReal PetscNVSHEMReal<br>
<br>
   etc. <br>
<br>
  Then one could write things like <br>
<br>
  struct {<br>
     ...<br>
     PetscNVSHEMReal *values;<br>
  }<br>
<br>
  Similarly inside kernels one would use the type type associated with the kernel, cuda with cuda etc. <br>
<br>
  I think the resulting code will be much clearer and easier to dive into, then having to first figure out where each variable lives.<br>
<br>
  I find the current code confusing because one cannot immediately see a variable declaration and know where it lives, even though it does live somewhere in particular..<br>
<br>
  Barry<br>
<br>
<br>
<br>
<br>
<br>
</blockquote></div></div>