4

I have encountered unusual NullReferenceException while working with Alea GPU on my project, everything was working fine until i have added Parallel.For with some code after Gpu.Default.For, here is minimal code i could get to reproduce the error:

[GpuManaged]
void fun()
{
    int[] gpu_arr = new int[5];
    Gpu.Default.For(0, 5, x =>
    {
        gpu_arr[x] = 1;
    });

    int[] arr = new int[10]; //moving this line above Gpu.Default.For solves the problem
    Parallel.For(0, 10, y =>
    {
        arr[y] = 1; //the exception won't be thrown after deleting this line
    });
}

Exception detail:

System.NullReferenceException was unhandled by user code
  HResult=-2147467261
  Message=Object reference not set to an instance of an object.
  Source=Alea
  StackTrace:
       at Alea.Builders.ToUnmanagedMarshaler.ca3c0a8545c9ef8bb625e1642f06cc3b0(ToUnmanagedMarshalContext c51dcb01051c4c98d3eeb37994cb59840, IRType cced00522c9c21aa0da268f3a19ebc3a4, Object cfc437ec92b1c7022feaad7b85c894b89, IntPtr c935f4057f51a7fe14b62c80b19464d48)
       at Alea.Builders.clo@4253-523.Invoke(ToUnmanagedMarshalContext ctx, IRType irType, Object clrObject, IntPtr buffer)
       at Alea.Constructs.IRStructType.MarshalToUnmanaged(ToUnmanagedMarshalContext ctx, Object[] clrFields, IntPtr buffer, FSharpFunc`2 marshal)
       at Alea.Builders.ToUnmanagedMarshaler.ca3c0a8545c9ef8bb625e1642f06cc3b0(ToUnmanagedMarshalContext c51dcb01051c4c98d3eeb37994cb59840, IRType cced00522c9c21aa0da268f3a19ebc3a4, Object cfc437ec92b1c7022feaad7b85c894b89, IntPtr c935f4057f51a7fe14b62c80b19464d48)
       at Alea.Builders.Marshal@4304.Invoke(IRType irType, Object clrObject, IntPtr buffer)
       at Alea.Builders.ToUnmanagedMarshaler.Marshal[b](ToUnmanagedMarshalContext ctx, IRType irType, b clrObject, IntPtr buffer)
       at A.cf5aded17df9f7cc4c132234dda010fa7.clo@2275-622.Invoke(Int32 i, Object param)
       at Microsoft.FSharp.Primitives.Basics.List.loop@504-16[T](FSharpFunc`3 f, Int32 n, FSharpList`1 x)
       at Microsoft.FSharp.Primitives.Basics.List.iteri[T](FSharpFunc`2 action, FSharpList`1 x)
       at A.cf5aded17df9f7cc4c132234dda010fa7.clo@2272-621.Invoke(Unit _arg59)
       at Alea.Context.LockEval[e,f](e l, FSharpFunc`2 f)
       at Alea.Kernel.c771089de7170797e4f5abe71ebafe73a(FSharpOption`1 ca0018dd2e778e1acd84b6ef7eb063a47, LaunchParam cecd3f8288b62aa7a1097708339c27039, FSharpList`1 ca4856957094a49b77a445a80fc96b563)
       at Alea.Kernel.LaunchRaw(LaunchParam lp, FSharpOption`1 instanceOpt, FSharpList`1 args)
       at Alea.Parallel.Device.DeviceFor.For(Gpu gpu, Int32 fromInclusive, Int32 toExclusive, Action`1 op)
       at Alea.Parallel.GpuExtension.For(Gpu gpu, Int32 fromInclusive, Int32 toExclusive, Action`1 op)

I have tested it with both console and windows forms, same result. So, what did i do wrong? or is this a bug?

Ahmed Osama
  • 854
  • 1
  • 8
  • 17
  • 1
    Can you post the stack trace and exception message? – Kobi Dec 24 '17 at 13:43
  • Yes sure, i have edited the post. – Ahmed Osama Dec 24 '17 at 13:58
  • What if you add `lock(arr)` around the assignment inside the parallel block? Is the first `GPU.Default.For` block relevant? – Wai Ha Lee Dec 24 '17 at 14:50
  • Same result with `lock`. But i discovered strange thing (workaround), moving `int[] arr = new int[10];` above `Gpu.Default.For` solves the problem! So it looks like that Alea was accessing `arr` before it was initialized, (wasn't it?) But why was it accessing an array that isn't even in `Gpu.Default.For` scope? Is it a problem in Alea automatic memory management system? I hope someone explains that. – Ahmed Osama Dec 24 '17 at 16:01
  • @AhmedOsama Isn't `Parallel.For` running in the "normal" C# thread pool and not in the GPU related memory/thread? This would mean that the array is created in the GPU related memory (as far as I understand [Alea GPU manual](http://www.aleagpu.com/release/3_0_3/doc/advanced_features_csharp.html#auto_copy_control)), but the iterations are running in "normal" C# space. Rearranging the array initialization might change the actual byte allocation and the `For` statements running on them. Why do you have `Parallel.For` in a `[GpuManaged]` block (with array access) anyway? – Progman Dec 24 '17 at 21:35
  • That is the unclear thing, that `arr` is never accessed by a GPU in the code, but Alea memory manager is trying to copy it to the GPU memory once it gets to `Gpu.Default.For` line, also, deleting `[GpuManaged]` doesn't change anything, because "`Gpu.For` have the attribute" as mentioned in the document, but it should manage only `Gpu.For` scope, shouldn't it? – Ahmed Osama Dec 26 '17 at 09:54
  • Also by looking into the stack trace you will see that `Gpu.Default.For` is which throws the exception not `Parallel.For`. – Ahmed Osama Dec 26 '17 at 10:33

0 Answers0