Beispiel #1
0
 public DataRangeCopy(Buffer buffer, DeviceMemorySpace space, DataRange range)
 {
     Buffer            = buffer;
     DeviceMemorySpace = space;
     Range             = range;
     ReadingTasks      = new HashSet <Task>();
 }
        internal static OpenCLComputeDevice Create(Int32 id, Context context, Device device, double hostTransferSpeed)
        {
            CommandQueue      queue = new CommandQueue(context, device, CommandQueueFlags.None);
            DeviceMemorySpace space = new DeviceMemorySpace(hostTransferSpeed, queue);

            return(new OpenCLComputeDevice(id, device, queue, space));
        }
Beispiel #3
0
        internal Object GetCodeletArgumentForMemorySpace(DataRange range, DeviceMemorySpace space)
        {
            if (_disposed)
            {
                throw new ObjectDisposedException(typeof(Data).FullName);
            }
            Debug.Assert(space != null);
            DataRangeCopy copy = FindDataRangeCopy(range, space);

            return(copy.Buffer);
        }
Beispiel #4
0
        DataRangeCopy FindDataRangeCopy(DataRange range, DeviceMemorySpace space)
        {
            DataRangeCopy copy = null;

            foreach (DataRangeCopy otherCopy in DataRangeCopies)
            {
                if (range == otherCopy.Range && space == otherCopy.DeviceMemorySpace)
                {
                    copy = otherCopy;
                    break; // i hate that thing
                }
            }
            return(copy);
        }
Beispiel #5
0
        internal void FinishTask(Task task, DataRange range, DataAccess access, DeviceMemorySpace space)
        {
            DataRangeCopy copy = FindDataRangeCopy(range, space);

            Debug.Assert(copy != null);
            if ((access & DataAccess.Write) == DataAccess.Write)
            {
                Debug.Assert(copy.WritingTask == task);
                copy.WritingTask = null;
            }
            else
            {
                Debug.Assert(copy.ReadingTasks.Remove(task));
            }
        }
Beispiel #6
0
        internal DateTime GetAvailabilityTime(DataRange range, DataAccess access, DeviceMemorySpace memorySpace)
        {
            if (_disposed)
            {
                throw new ObjectDisposedException(typeof(Data).FullName);
            }
            Debug.Assert(memorySpace != null);
            if (!IsRangeValid(range))
            {
                throw new ArgumentOutOfRangeException();
            }
            Boolean  transfer = false;
            DateTime result   = DateTime.Now;

            foreach (DataRangeCopy copy in DataRangeCopies)
            {
                if (range.Intersects(copy.Range))
                {
                    DateTime rangeLastFinishTime = DateTime.Now;
                    // maintain consistency
                    if (copy.WritingTask != null)
                    {
                        rangeLastFinishTime = Max(rangeLastFinishTime, copy.WritingTask.ScheduledTaskInfo.FinishTime);
                    }
                    if ((access & DataAccess.Write) == DataAccess.Write)
                    {
                        // task will be writing, so we also have to wait for reading tasks
                        foreach (Task task in copy.ReadingTasks)
                        {
                            rangeLastFinishTime = Max(rangeLastFinishTime, task.ScheduledTaskInfo.FinishTime);
                        }
                    }
                    if ((range != copy.Range || memorySpace != copy.DeviceMemorySpace) && copy.Dirty)
                    {
                        // copy is dirty, needs to transfer this copy to the host
                        rangeLastFinishTime += TimeSpan.FromSeconds(GetRangeSize(copy.Range) / copy.DeviceMemorySpace.HostTransferSpeed);
                        transfer             = true;
                    }
                    result = Max(result, rangeLastFinishTime);
                }
            }
            if (transfer)
            {
                // host data was modified, transfer fresh bytes to the range
                result += TimeSpan.FromSeconds(GetRangeSize(range) / memorySpace.HostTransferSpeed);
            }
            return(result);
        }
Beispiel #7
0
        internal Object StartPrepareRange(Task task, DataRange range, DataAccess access, DeviceMemorySpace space)
        {
            if (_disposed)
            {
                throw new ObjectDisposedException(typeof(Data).FullName);
            }
            Debug.Assert(WaitingTasks.Count > 0);
            Debug.Assert(WaitingTasks[0].Task == task);
            if (!IsRangeValid(range))
            {
                throw new ArgumentOutOfRangeException();
            }
            List <Object> rangeConditions = new List <Object>();
            Boolean       writing         = (access & DataAccess.Write) == DataAccess.Write;
            Boolean       oneWasDirty     = false;

            foreach (DataRangeCopy copyStuckInClusore in DataRangeCopies)
            {
                DataRangeCopy copy = copyStuckInClusore;
                if (range.Intersects(copy.Range))
                {
                    List <Object> predecessorConditions = new List <Object>();
                    // must wait for all conflicting reads/writes
                    if (copy.WritingTask != null)
                    {
                        predecessorConditions.Add(copy.WritingTask);
                    }
                    if (writing)
                    {
                        foreach (Task readingTask in copy.ReadingTasks)
                        {
                            predecessorConditions.Add(readingTask);
                        }
                    }
                    Object rangeCondition = new Object();
                    DependencyManager.RegisterOperation(rangeCondition);
                    DependencyManager.RegisterContinuation(predecessorConditions, () => {
                        // all conflicting tasks in this copy finished
                        Debug.Assert(copy.WritingTask == null);
                        if (writing)
                        {
                            Debug.Assert(copy.ReadingTasks.Count == 0);
                        }
                        if (range == copy.Range && space == copy.DeviceMemorySpace)
                        {
                            // current copy will be the one used for the task
                            DependencyManager.FinishOperationLocked(rangeCondition);
                        }
                        else
                        {
                            Object copyOrDeleteCondition = null;
                            if (copy.Dirty)
                            {
                                // transfer bytes to host
                                Object readCondition  = StartReadBufferRange(copy.Buffer, copy.Range, copy.DeviceMemorySpace.CommandQueue);
                                copyOrDeleteCondition = DependencyManager.ContinueOneWith(readCondition, () => {
                                    copy.Dirty = false;
                                });
                                oneWasDirty = true;
                            }
                            if (writing)
                            {
                                copyOrDeleteCondition = DependencyManager.ContinueOneWith(copyOrDeleteCondition, () => {
                                    // copying is not necessary or is finished
                                    Debug.Assert(copy.Dirty == false);
                                    copy.Buffer.Dispose();
                                    Debug.Assert(DataRangeCopies.Remove(copy));
                                });
                            }
                            DependencyManager.RegisterOneContinuation(copyOrDeleteCondition, () => {
                                DependencyManager.FinishOperationLocked(rangeCondition);
                            });
                        }
                    });
                    rangeConditions.Add(rangeCondition);
                }
            }
            // dependencies of all conflicting ranges are in rangeConditions
            Object waitFinishedCondition = WaitingTasks[0].Condition;

            DependencyManager.RegisterContinuation(rangeConditions, () => {
                // now there should not be any conflicting ranges anymore
                // try to find the matching copy
                DataRangeCopy copy       = FindDataRangeCopy(range, space);
                Object transferCondition = null;
                if (oneWasDirty || copy == null)
                {
                    if (copy == null)
                    {
                        Buffer buffer = ComputeManager.Context.CreateBuffer(GetRangeSize(range), BufferFlags.ReadWrite);
                        copy          = new DataRangeCopy(buffer, space, range);
                        DataRangeCopies.Add(copy);
                    }
                    // transfer host data to buffer
                    transferCondition = StartWriteBufferRange(copy.Buffer, range, space.CommandQueue);
                }
                DependencyManager.RegisterOneContinuation(transferCondition, () => {
                    // range was transferred to buffer or no transfer was necessary
                    Debug.Assert(WaitingTasks.Count > 0);
                    Debug.Assert(WaitingTasks[0].Task == task);
                    Debug.Assert(copy.WritingTask == null);
                    if (writing)
                    {
                        copy.WritingTask = task;
                        copy.Dirty       = true;
                    }
                    else
                    {
                        copy.ReadingTasks.Add(task);
                    }
                    WaitingTasks.RemoveAt(0);
                    DependencyManager.FinishOperationLocked(waitFinishedCondition);
                });
            });
            return(waitFinishedCondition);
        }
 internal ComputeDevice(Int32 id, DeviceMemorySpace memorySpace)
 {
     Id          = id;
     MemorySpace = memorySpace;
     _tasks      = new List <Task>();
 }
 OpenCLComputeDevice(Int32 id, Device device, CommandQueue queue, DeviceMemorySpace memorySpace)
     : base(id, memorySpace)
 {
     CommandQueue = queue;
     _device      = device;
 }