/// <summary> /// Allocates an nD buffer on the given accelerator and transfers memory /// to and from the buffer. /// </summary> /// <param name="accelerator">The target accelerator.</param> /// <param name="valueConverter">A value converter to convert values of type MyIndex4 to type T.</param> static void AllocND <T>(Accelerator accelerator, Func <MyIndex4, MyIndex4, T> valueConverter) where T : struct, IEquatable <T> { Console.WriteLine($"Performing nD allocation on {accelerator.Name}"); var data = new T[Dimension.Size]; for (int i = 0; i < AllocationSize1D; ++i) { for (int j = 0; j < AllocationSize2D; ++j) { for (int k = 0; k < AllocationSize3D; ++k) { for (int l = 0; l < AllocationSize4D; ++l) { var index = new MyIndex4(i, j, k, l); data[index.ComputeLinearIndex(Dimension)] = valueConverter(index, Dimension); } } } } var targetData = new T[Dimension.Size]; using (var buffer = accelerator.Allocate <T, MyIndex4>(new MyIndex4(AllocationSize1D + 2, Dimension.X, Dimension.Y, Dimension.Z))) { // Copy to accelerator buffer.CopyFrom( data, // data source 0, // source index in the scope of the data source new MyIndex4(2, 0, 0, 0), // target index in the scope of the buffer data.Length); // the number of elements to copy // Copy from accelerator buffer.CopyTo( targetData, // data target new MyIndex4(2, 0, 0, 0), // target index in the scope of the buffer 0, // target index in the scope of the data target Dimension); // the number of elements to copy } // Verify data for (int i = 0; i < AllocationSize1D; ++i) { for (int j = 0; j < AllocationSize2D; ++j) { for (int k = 0; k < AllocationSize3D; ++k) { for (int l = 0; l < AllocationSize4D; ++l) { var index = new MyIndex4(i, j, k, l).ComputeLinearIndex(Dimension); if (!data[index].Equals(targetData[index])) { Console.WriteLine($"Error comparing data and target data at {index}: {targetData[index]} found, but {data[index]} expected"); } } } } } }
/// <summary> /// A 1D kernel that will be mapped to our custom 4D implementation. /// </summary> /// <param name="index">The current thread index.</param> /// <param name="dataView">The view pointing to our memory buffer.</param> static void MyKernelND( Index index, ArrayView <int, MyIndex4> dataView) { // Reconstruct a valid 4D index var myIdx = MyIndex4.ReconstructIndex(index, Dimension); // Assign the data at the associated 4D location dataView[myIdx] = index; }