protected void SafeCall(curandStatus status, DevicePtrEx ptrEx = null) { if(ptrEx != null) Free(ptrEx); if (status != curandStatus.CURAND_STATUS_SUCCESS) throw new CudafyMathException(CudafyMathException.csRAND_ERROR_X, status.ToString()); }
protected override DevicePtrEx GetDevicePtr(Array array, ref int n) { DevicePtrEx ptrEx = _gpu.GetDeviceMemory(array) as DevicePtrEx; if (n == 0) { n = ptrEx.TotalSize; } return(ptrEx); }
/// <summary> /// Creates a version of hostObject on the device with any fields which are reference types converted /// to pointers to device memory (IntPtrs) and any arrays copied to the device. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="gpu"></param> /// <param name="hostObject"></param> /// <returns>THe device object (that can then be used in kernal calls).</returns> public static object CreateDeviceObject <T>(GPGPU gpu, T hostObject) { if (!deviceObjectFromHostObject.ContainsKey(gpu)) { deviceObjectFromHostObject.Add(gpu, new Dictionary <object, object>()); } Type hostObjectType = hostObject.GetType(); Type newTypeToCreate; if (hostObjectType.IsArray) { newTypeToCreate = hostObjectType.GetElementType(); // if this is a value type array if (newTypeToCreate.IsValueType) { return(CopyArrayToDevice(gpu, hostObject as Array)); } else { return(CopyArrayOfReferenceTypeToDevice(gpu, hostObject as Array)); } } else { newTypeToCreate = hostObjectType; } // if reference type fields are not on the device already we must copy them to the device and overwrite these fields with // pointers to the device memory. CopyReferenceTypeFieldsToDevice <T>(gpu, hostObject); var deviceTypeInfo = CreateDeviceType(newTypeToCreate); var deviceObject = Activator.CreateInstance(deviceTypeInfo.DeviceType); // For each element of the array, we need to do this: AssignPointerFields(gpu, hostObject, deviceObject, deviceTypeInfo.PointerFields); AssignNonPointerFields(hostObject, deviceObject, deviceTypeInfo.NonPointerFields); var deviceObjectArray = Array.CreateInstance(deviceTypeInfo.DeviceType, 1); deviceObjectArray.SetValue(deviceObject, 0); var copy1DArrayToDevice = CopyArrayToDevice(deviceTypeInfo.DeviceType, 1); object deviceObjectArrayPointer = copy1DArrayToDevice.Invoke(gpu, new object[] { deviceObjectArray }); MapDeviceMemoryToObject(gpu, deviceObjectArrayPointer, hostObject); // this is not really an array, but it is a reference type, so make 0D to avoid addition of array length in kernel call. DevicePtrEx deviceObjectPointer = gpu.TryGetDeviceMemory(deviceObjectArrayPointer); typeof(DevicePtrEx).GetProperty("Dimensions").SetValue(deviceObjectPointer, 0, null); return(deviceObjectArrayPointer); }
protected void SafeCall(curandStatus status, DevicePtrEx ptrEx = null) { if (ptrEx != null) { Free(ptrEx); } if (status != curandStatus.CURAND_STATUS_SUCCESS) { throw new CudafyMathException(CudafyMathException.csRAND_ERROR_X, status.ToString()); } }
/// <summary> /// Does the copy from device async. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="devArray">The dev array.</param> /// <param name="devOffset">The dev offset.</param> /// <param name="hostArray">The host array.</param> /// <param name="hostOffset">The host offset.</param> /// <param name="count">The count.</param> /// <param name="streamId">The stream id.</param> protected override void DoCopyFromDeviceAsync <T>(DevicePtrEx devArray, int devOffset, IntPtr hostArray, int hostOffset, int count, int streamId) { var ptrEx = devArray as EmuDevicePtrEx; int size = MSizeOf(typeof(T)); //if (!_hostHandles.ContainsKey(hostArray)) // throw new CudafyHostException(CudafyHostException.csDATA_IS_NOT_HOST_ALLOCATED); GCHandle handle = _hostHandles[hostArray]; IntPtr hostArrayPtr = handle.AddrOfPinnedObject(); IntPtr devOffsetPtr = new IntPtr(ptrEx.Pointer.ToInt64() + devOffset * size); IntPtr hostOffsetPtr = new IntPtr(hostArrayPtr.ToInt64() + hostOffset * size); try { CopyMemory(hostOffsetPtr, devOffsetPtr, (uint)(count * MSizeOf(typeof(T)))); } finally { ptrEx.FreeHandle(); } }
private unsafe static void Main(string[] args) { GPGPU gpuCuda = CudafyHost.GetDevice(eGPUType.Cuda, 0); CudafyModule km = CudafyTranslator.Cudafy(); gpuCuda.LoadModule(km); TestStruct[] host_array = new TestStruct[1]; host_array[0] = new TestStruct(); int[] host_intArray = new[] { 1, 8, 3 }; int[] dev_intArray = gpuCuda.CopyToDevice(host_intArray); DevicePtrEx p = gpuCuda.GetDeviceMemory(dev_intArray); IntPtr pointer = p.Pointer; host_array[0].dataPointer = pointer.ToInt64(); TestStruct[] dev_array = gpuCuda.Allocate(host_array); gpuCuda.CopyToDevice(host_array, dev_array); gpuCuda.Launch().kernelTest(dev_array, dev_intArray); gpuCuda.CopyFromDevice(dev_array, host_array); Console.WriteLine(host_array[0].value); Console.ReadKey(); }
protected override void DoCopyOnDeviceAsync <T>(DevicePtrEx srcDevArray, int srcOffset, DevicePtrEx dstDevArray, int dstOffet, int count, int streamId) { throw new NotImplementedException(); }
protected override void Free(DevicePtrEx ptrEx) { Debug.Assert(ptrEx is EmuDevicePtrEx); (ptrEx as EmuDevicePtrEx).FreeHandle(); }
protected abstract void Free(DevicePtrEx ptrEx);
protected override void Free(DevicePtrEx ptrEx) { // Nothing to do }
public override void GenerateUniform(double[] array, int n = 0) { DevicePtrEx ptrEx = GetDevicePtr(array, ref n); SafeCall(_driver.GenerateUniformDouble(_gen, ptrEx.Pointer, n), ptrEx); }
public override void GenerateNormal(double[] array, float mean, float stddev, int n = 0) { DevicePtrEx ptrEx = GetDevicePtr(array, ref n); SafeCall(_driver.GenerateNormalDouble(_gen, ptrEx.Pointer, n, mean, stddev), ptrEx); }
public override void Generate(ulong[] array, int n = 0) { DevicePtrEx ptrEx = GetDevicePtr(array, ref n); SafeCall(_driver.Generate(_gen, ptrEx.Pointer, n), ptrEx); }