示例#1
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);
        }
示例#2
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);
        }
示例#3
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));
            }
        }
示例#4
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);
        }