www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Second class pointers

reply Nicholas Wilson <iamthewilsonator hotmail.com> writes:
So as part of my effort to get D running on GPUs I need to make a 
"second class" pointer type that I can alter in the backend of 
LDC to the correct address space. to that end I have made the 
following

module dcompute.types.pointer;

enum Private = 0;
enum Global = 1;
enum Shared = 2;
enum Constant = 3;
enum Generic = 4;

pure  trusted nothrow  nogc
struct Pointer(uint p, T) if(p <= Generic)
{
     T* ptr;
     ref T opUnary(string op)() if(op=="*")
     {
         return *ptr;
     }
     ref T opIndex(size_t i)
     {
         return *(ptr+i);
     }
     auto opBinary(string op)(ptrdiff_t i) if(op=="+" || op == "-")
     {
          return Pointer!(p, T) (ptr + i);
     }
}

is there anything else that I'm missing that you can do with a 
raw pointer?
Jul 07 2016
parent reply Nicholas Wilson <iamthewilsonator hotmail.com> writes:
On Friday, 8 July 2016 at 05:53:21 UTC, Nicholas Wilson wrote:
 So as part of my effort to get D running on GPUs I need to make 
 a "second class" pointer type that I can alter in the backend 
 of LDC to the correct address space. to that end I have made 
 the following

 module dcompute.types.pointer;

 enum Private = 0;
 enum Global = 1;
 enum Shared = 2;
 enum Constant = 3;
 enum Generic = 4;

 pure  trusted nothrow  nogc
 struct Pointer(uint p, T) if(p <= Generic)
 {
     T* ptr;
     ref T opUnary(string op)() if(op=="*")
     {
         return *ptr;
     }
     ref T opIndex(size_t i)
     {
         return *(ptr+i);
     }
     auto opBinary(string op)(ptrdiff_t i) if(op=="+" || op == 
 "-")
     {
          return Pointer!(p, T) (ptr + i);
     }
 }

 is there anything else that I'm missing that you can do with a 
 raw pointer?
That should be mixin("ptr"~op~"i") I need compound add and compound subtract as well.
Jul 07 2016
parent reply ZombineDev <petar.p.kirov gmail.com> writes:
On Friday, 8 July 2016 at 06:17:43 UTC, Nicholas Wilson wrote:
 On Friday, 8 July 2016 at 05:53:21 UTC, Nicholas Wilson wrote:
 So as part of my effort to get D running on GPUs I need to 
 make a "second class" pointer type that I can alter in the 
 backend of LDC to the correct address space. to that end I 
 have made the following

 module dcompute.types.pointer;

 enum Private = 0;
 enum Global = 1;
 enum Shared = 2;
 enum Constant = 3;
 enum Generic = 4;

 pure  trusted nothrow  nogc
 struct Pointer(uint p, T) if(p <= Generic)
 {
     T* ptr;
     ref T opUnary(string op)() if(op=="*")
     {
         return *ptr;
     }
     ref T opIndex(size_t i)
     {
         return *(ptr+i);
     }
     auto opBinary(string op)(ptrdiff_t i) if(op=="+" || op == 
 "-")
     {
          return Pointer!(p, T) (ptr + i);
     }
 }

 ...
That should be mixin("ptr"~op~"i") I need compound add and compound subtract as well.
Why not make the address (memory) space a strongly-typed enum, e.g.: enum AddressSpace { threadLocal = 0, groupLocal = 1, global = 2, constant = 3, texture = 4 generic = 5 } struct Pointer(T, AddressSpace type = AddressSpace.Generic) // ... ?
 is there anything else that I'm missing that you can do with a 
 raw pointer?
Slicing: // Pseudo OpenCL-D groupLocal T* ptr1; groupLocal T[] slice1 = ptr1[2 .. 10]; global T* ptr2; groupLocal T[] slice2 = ptr2[0 .. 2]; // Error
Jul 08 2016
parent Nicholas Wilson <iamthewilsonator hotmail.com> writes:
On Friday, 8 July 2016 at 11:05:36 UTC, ZombineDev wrote:
 On Friday, 8 July 2016 at 06:17:43 UTC, Nicholas Wilson wrote:
 On Friday, 8 July 2016 at 05:53:21 UTC, Nicholas Wilson wrote:
 So as part of my effort to get D running on GPUs I need to 
 make a "second class" pointer type that I can alter in the 
 backend of LDC to the correct address space. to that end I 
 have made the following

 module dcompute.types.pointer;

 enum Private = 0;
 enum Global = 1;
 enum Shared = 2;
 enum Constant = 3;
 enum Generic = 4;

 pure  trusted nothrow  nogc
 struct Pointer(uint p, T) if(p <= Generic)
 {
     T* ptr;
     ref T opUnary(string op)() if(op=="*")
     {
         return *ptr;
     }
     ref T opIndex(size_t i)
     {
         return *(ptr+i);
     }
     auto opBinary(string op)(ptrdiff_t i) if(op=="+" || op == 
 "-")
     {
          return Pointer!(p, T) (ptr + i);
     }
 }

 ...
That should be mixin("ptr"~op~"i") I need compound add and compound subtract as well.
Why not make the address (memory) space a strongly-typed enum, e.g.: enum AddressSpace { threadLocal = 0, groupLocal = 1, global = 2, constant = 3, texture = 4 generic = 5 }
because it'll change the mangling and I just want to get it working first, also there will be aliases for all the things anyway. (also AFAIU there is no texture address space its just fancy caching)
 struct Pointer(T, AddressSpace type = AddressSpace.Generic)
 // ...

 ?

 is there anything else that I'm missing that you can do with 
 a raw pointer?
Slicing:
That's creating a new variable based on the pointer as {$-offset, ptr + offset} not a primitive, but I take your point.
 // Pseudo OpenCL-D

 groupLocal T* ptr1;
 groupLocal T[] slice1 = ptr1[2 .. 10];

 global T* ptr2;
 groupLocal T[] slice2 = ptr2[0 .. 2]; // Error
I REALLY want to avoid having to make them qualifiers and that means I have to hack DMDFE as well as LDC.
Jul 08 2016