nd4j-backends/nd4j-backend-impls/nd4j-cuda/src/main/java/org/nd4j/jita/memory/impl/CudaFullCachingProvider.java
@Override
    public void free(AllocationPoint point) {
        if (point.getAllocationStatus() == AllocationStatus.DEVICE) {
            if (point.isConstant())
                return;

            AllocationShape shape = point.getShape();
            int deviceId = point.getDeviceId();
            long address = point.getDevicePointer().address();
            long reqMemory = AllocationUtils.getRequiredMemory(shape);
            // we don't cache too big objects

            if (reqMemory > CudaEnvironment.getInstance().getConfiguration().getMaximumDeviceCacheableLength() || deviceCachedAmount.get(deviceId).get() >= CudaEnvironment.getInstance().getConfiguration().getMaximumHostCache()) {
                //log.info("DEVICE_{} memory purging: {} bytes; MS: {}; MT: {}", deviceId, reqMemory, MAX_GPU_ALLOCATION, MAX_GPU_CACHE);
                super.free(point);
                return;
            }

//            log.info("Saving HOST memory into cache...");

            ensureDeviceCacheHolder(deviceId, shape);

            CacheHolder cache = deviceCache.get(deviceId).get(shape);



            if (point.getDeviceId() != deviceId)
                throw new RuntimeException("deviceId changed!");

            // memory chunks < threshold will be cached no matter what
            if (reqMemory <= FORCED_CACHE_THRESHOLD) {
                cache.put(new CudaPointer(point.getDevicePointer().address()));
                return;
            } else {
                long cacheEntries = cache.size();
                long cacheHeight = deviceCache.get(deviceId).size();

                // total memory allocated within this bucket
                long cacheDepth = cacheEntries * reqMemory;

                //if (cacheDepth < MAX_CACHED_MEMORY / cacheHeight) {
                cache.put(new CudaPointer(point.getDevicePointer().address()));
                return;
                //} else {
                //    super.free(point);
                // }
            }
        }
        super.free(point);
    }
@Override
    public void free(AllocationPoint point) {
        if (point.getAllocationStatus() == AllocationStatus.DEVICE) {
            if (point.isConstant())
                return;

            AllocationShape shape = point.getShape();
            int deviceId = point.getDeviceId();
            long address = point.getDevicePointer().address();
            long reqMemory = AllocationUtils.getRequiredMemory(shape);
            // we don't cache too big objects

            if (reqMemory > CudaEnvironment.getInstance().getConfiguration().getMaximumDeviceCacheableLength() || deviceCachedAmount.get(deviceId).get() >= CudaEnvironment.getInstance().getConfiguration().getMaximumHostCache()) {
                //log.info("DEVICE_{} memory purging: {} bytes; MS: {}; MT: {}", deviceId, reqMemory, MAX_GPU_ALLOCATION, MAX_GPU_CACHE);
                super.free(point);
                return;
            }

//            log.info("Saving HOST memory into cache...");

            ensureDeviceCacheHolder(deviceId, shape);

            CacheHolder cache = deviceCache.get(deviceId).get(shape);



            if (point.getDeviceId() != deviceId)
                throw new RuntimeException("deviceId changed!");

            // memory chunks < threshold will be cached no matter what
            if (reqMemory <= FORCED_CACHE_THRESHOLD) {
                cache.put(new CudaPointer(point.getDevicePointer().address()));
                return;
            } else {
                long cacheEntries = cache.size();
                long cacheHeight = deviceCache.get(deviceId).size();

                // total memory allocated within this bucket
                long cacheDepth = cacheEntries * reqMemory;

                //if (cacheDepth < MAX_CACHED_MEMORY / cacheHeight) {
                cache.put(new CudaPointer(point.getDevicePointer().address()));
                return;
                //} else {
                //    super.free(point);
                // }
            }
        }
        super.free(point);
    }
@ Override public void free ( AllocationPoint point ) { if ( point . getAllocationStatus ( ) == AllocationStatus . DEVICE ) { if ( point . isConstant ( ) ) return ; AllocationShape shape = point . getShape ( ) ; int deviceId = point . getDeviceId ( ) ; long address = point . getDevicePointer ( ) . address ( ) ; long reqMemory = AllocationUtils . getRequiredMemory ( shape ) ; // we don't cache too big objects if ( reqMemory > CudaEnvironment . getInstance ( ) . getConfiguration ( ) . getMaximumDeviceCacheableLength ( ) || deviceCachedAmount . get ( deviceId ) . get ( ) >= CudaEnvironment . getInstance ( ) . getConfiguration ( ) . getMaximumHostCache ( ) ) { //log.info("DEVICE_{} memory purging: {} bytes; MS: {}; MT: {}", deviceId, reqMemory, MAX_GPU_ALLOCATION, MAX_GPU_CACHE); super . free ( point ) ; return ; } //            log.info("Saving HOST memory into cache..."); ensureDeviceCacheHolder ( deviceId , shape ) ; CacheHolder cache = deviceCache . get ( deviceId ) . get ( shape ) ; if ( point . getDeviceId ( ) != deviceId ) throw new RuntimeException ( "deviceId changed!" ) ; // memory chunks < threshold will be cached no matter what if ( reqMemory <= FORCED_CACHE_THRESHOLD ) { cache . put ( new CudaPointer ( point . getDevicePointer ( ) . address ( ) ) ) ; return ; } else { long cacheEntries = cache . size ( ) ; long cacheHeight = deviceCache . get ( deviceId ) . size ( ) ; // total memory allocated within this bucket long cacheDepth = cacheEntries * reqMemory ; //if (cacheDepth < MAX_CACHED_MEMORY / cacheHeight) { cache . put ( new CudaPointer ( point . getDevicePointer ( ) . address ( ) ) ) ; return ; //} else { //    super.free(point); // } } } super . free ( point ) ; }
This method frees specific chunk of memory, described by AllocationPoint passed in

PLEASE NOTE: This method can actually ignore free, and keep released memory chunk for future reuse.

@param point
This method frees specific chunk of memory described by AllocationPoint passed in