Search in sources :

Example 1 with LRUCacheMap

use of org.apache.sysml.utils.LRUCacheMap in project incubator-systemml by apache.

the class GPUContext method evict.

/**
   * Memory on the GPU is tried to be freed up until either a chunk of needed size is freed up
   * or it fails.
   * First the set of reusable blocks is freed up. If that isn't enough, the set of allocated matrix
   * blocks with zero locks on them is freed up.
   * The process cycles through the sorted list of allocated {@link GPUObject} instances. Sorting is based on
   * number of (read) locks that have been obtained on it (reverse order). It repeatedly frees up
   * blocks on which there are zero locks until the required size has been freed up.
   * // TODO: update it with hybrid policy
   *
   * @param instructionName name of the instruction for which performance measurements are made
   * @param neededSize      desired size to be freed up on the GPU
   * @throws DMLRuntimeException If no reusable memory blocks to free up or if not enough matrix blocks with zero locks on them.
   */
protected void evict(String instructionName, final long neededSize) throws DMLRuntimeException {
    LOG.trace("GPU : evict called from " + instructionName + " for size " + neededSize + " on " + this);
    GPUStatistics.cudaEvictionCount.addAndGet(1);
    // Release the set of free blocks maintained in a GPUObject.freeCUDASpaceMap
    // to free up space
    LRUCacheMap<Long, LinkedList<Pointer>> lruCacheMap = freeCUDASpaceMap;
    while (lruCacheMap.size() > 0) {
        if (neededSize <= getAvailableMemory())
            break;
        Map.Entry<Long, LinkedList<Pointer>> toFreeListPair = lruCacheMap.removeAndGetLRUEntry();
        LinkedList<Pointer> toFreeList = toFreeListPair.getValue();
        Long size = toFreeListPair.getKey();
        Pointer toFree = toFreeList.pop();
        if (toFreeList.isEmpty())
            lruCacheMap.remove(size);
        cudaFreeHelper(instructionName, toFree, true);
    }
    if (neededSize <= getAvailableMemory())
        return;
    if (allocatedGPUObjects.size() == 0) {
        throw new DMLRuntimeException("There is not enough memory on device for this matrix, request (" + neededSize + ")");
    }
    Collections.sort(allocatedGPUObjects, new Comparator<GPUObject>() {

        @Override
        public int compare(GPUObject p1, GPUObject p2) {
            long p1Val = p1.locks.get();
            long p2Val = p2.locks.get();
            if (p1Val > 0 && p2Val > 0) {
                // Both are locked, so don't sort
                return 0;
            } else if (p1Val > 0 || p2Val > 0) {
                // Put the unlocked one to RHS
                return Long.compare(p2Val, p1Val);
            } else {
                if (evictionPolicy == EvictionPolicy.MIN_EVICT) {
                    long p1Size = 0;
                    long p2Size = 0;
                    try {
                        p1Size = p1.getSizeOnDevice() - neededSize;
                        p2Size = p2.getSizeOnDevice() - neededSize;
                    } catch (DMLRuntimeException e) {
                        throw new RuntimeException(e);
                    }
                    if (p1Size >= 0 && p2Size >= 0) {
                        return Long.compare(p2Size, p1Size);
                    } else {
                        return Long.compare(p1Size, p2Size);
                    }
                } else if (evictionPolicy == EvictionPolicy.LRU || evictionPolicy == EvictionPolicy.LFU) {
                    return Long.compare(p2.timestamp.get(), p1.timestamp.get());
                } else {
                    throw new RuntimeException("Unsupported eviction policy:" + evictionPolicy.name());
                }
            }
        }
    });
    while (neededSize > getAvailableMemory() && allocatedGPUObjects.size() > 0) {
        GPUObject toBeRemoved = allocatedGPUObjects.get(allocatedGPUObjects.size() - 1);
        if (toBeRemoved.locks.get() > 0) {
            throw new DMLRuntimeException("There is not enough memory on device for this matrix, request (" + neededSize + ")");
        }
        if (toBeRemoved.dirty) {
            toBeRemoved.copyFromDeviceToHost();
        }
        toBeRemoved.clearData(true);
    }
}
Also used : Pointer(jcuda.Pointer) LinkedList(java.util.LinkedList) DMLRuntimeException(org.apache.sysml.runtime.DMLRuntimeException) DMLRuntimeException(org.apache.sysml.runtime.DMLRuntimeException) LRUCacheMap(org.apache.sysml.utils.LRUCacheMap) HashMap(java.util.HashMap) Map(java.util.Map)

Aggregations

HashMap (java.util.HashMap)1 LinkedList (java.util.LinkedList)1 Map (java.util.Map)1 Pointer (jcuda.Pointer)1 DMLRuntimeException (org.apache.sysml.runtime.DMLRuntimeException)1 LRUCacheMap (org.apache.sysml.utils.LRUCacheMap)1