美文网首页
ND4J/工作间

ND4J/工作间

作者: hello风一样的男子 | 来源:发表于2019-04-03 10:08 被阅读0次
    package org.nd4j.examples;
    
    import org.nd4j.linalg.api.memory.MemoryWorkspace;
    import org.nd4j.linalg.api.memory.conf.WorkspaceConfiguration;
    import org.nd4j.linalg.api.memory.enums.AllocationPolicy;
    import org.nd4j.linalg.api.memory.enums.LearningPolicy;
    import org.nd4j.linalg.api.memory.enums.ResetPolicy;
    import org.nd4j.linalg.api.ndarray.INDArray;
    import org.nd4j.linalg.factory.Nd4j;
    import org.slf4j.Logger;
    
    /**
     * 
     * 这个例子展示了如何将内存工作空间与nd4j一起用于循环工作负载。
     * 背景:
     *
     * ND4J工作间是一个内存块,分配一次,然后在上面重复使用。基本上,如果使用循环工作负载,它为避免堆外内存的垃圾收集提供了一种方法。
     *请注意:工作间是可选的。如果你更喜欢使用原始的基于GC的内存管理器,那么你可以使用它而不会出现任何问题。
     *请注意:使用工作间时,你负责跟踪作用域等。你不应该访问附加到某些工作间之外的任何INDArray。结果将是不可预测的,直到JVM崩溃。
     *
     * @author raver119@gmail.com
     */
    public class Nd4jEx15_Workspaces {
        private static final Logger log = org.slf4j.LoggerFactory.getLogger(Nd4jEx15_Workspaces.class);
    
        public static void main(String[] args) throws Exception {
           
            /**
             * 每个工作间都通过ID绑定到一个JVM线程。因此,不同线程中的相同ID将指向不同的实际工作区。
             * 每个工作区都是使用某些配置创建的,不同的工作区既可以共享相同的配置,也可以拥有自己的配置。
             */
           
            //我们创建了一个预先分配了10MB内存空间的配置
            WorkspaceConfiguration initialConfig = WorkspaceConfiguration.builder()
                .initialSize(10 * 1024L * 1024L)
                .policyAllocation(AllocationPolicy.STRICT)
                .policyLearning(LearningPolicy.NONE)
                .build();
    
    
            INDArray result = null;
    
            // 我们使用
            try(MemoryWorkspace ws = Nd4j.getWorkspaceManager().getAndActivateWorkspace(initialConfig, "SOME_ID")) {
               
                //现在,在此try块中创建的每个INDArray都将从此工作区池中分配
                INDArray array = Nd4j.rand(10, 10);
    
           
                //查看此数组是否连接到某个工作间的最简单方法。我们希望这里打印出TRUE。
                log.info("Array attached? {}", array.isAttached());
    
               
                //请注意,新的数组平均值也将附加到此工作间
                INDArray mean = array.mean(1);
    
             
    
                /**
                 * 请注意:如果在工作间上执行了一些操作之后,你希望从中获得结果,那么应该利用它,或者分离
                 */
                result = mean.detach();
            }
    
           
            //因为我们分离了数组,所以我们希望在这里输出false。所以,结果数组现在由GC管理。
            log.info("Array attached? {}", result.isAttached());
    
    
    
            /**
             * 
             * 工作间最初可以预先分配,如上图所示,或者可以随着时间的推移或在第一个循环之后学习其所需的大小。
             */
    
            WorkspaceConfiguration learningConfig = WorkspaceConfiguration.builder()
                 //<--此选项禁用过度分配行为   
                .policyAllocation(AllocationPolicy.STRICT) 
                 //<--此选项使工作间在第一个循环后学习
                .policyLearning(LearningPolicy.FIRST_LOOP)
                .build();
    
            for (int x = 0; x < 10; x++) {
                try (MemoryWorkspace ws = Nd4j.getWorkspaceManager().getAndActivateWorkspace(learningConfig, "OTHER_ID")) {
                    INDArray array = Nd4j.create(100);
    
                    /**
                     * 在第一次迭代时,工作间将所有配额作为独立的内存块,但在此次迭代完成后,工作间将被分配,以匹配所有
                     * 此次循环中要求的配额。所以,更多的迭代将一次次重复使用工作间内存。
                     */
                }
            }
    
    
            /**
             * 
             * 工作间可以嵌套。如果需要,INDArrays可以在它们之间迁移
             */
    
            try(MemoryWorkspace ws1 = Nd4j.getWorkspaceManager().getAndActivateWorkspace(initialConfig, "SOME_ID")) {
                INDArray array = Nd4j.create(10, 10).assign(1.0f);
                INDArray sumRes;
    
                try(MemoryWorkspace ws2 = Nd4j.getWorkspaceManager().getAndActivateWorkspace(initialConfig, "THIRD_ID")) {
                    //请注意:只有当内存尚未关闭/重置时,我们才能从父工作间访问内存,而不会出现任何问题。
                    INDArray res = array.sum(1);
    
                  
                    //数组在ws1处分配,而res在ws2中分配。但我们可以在需要时迁移它们。
                    sumRes = res.leverageTo("SOME_ID");
                }
    
                // at this point sumRes contains valid data, allocated in current workspace. We expect 100 printed here.
                //此时,sumRes包含当前工作间中分配的有效数据。我们希望这里能打印100。
                log.info("Sum: {}", sumRes.sumNumber().floatValue());
            }
    
    
            /**
             * 
             * 如果出于某种原因需要用GC处理部分计算,则可以中断工作区流。
             */
            try(MemoryWorkspace ws1 = Nd4j.getWorkspaceManager().getAndActivateWorkspace(initialConfig, "SOME_ID")) {
                INDArray array1 = Nd4j.create(10, 10).assign(1.0f);
                INDArray array2;
    
                try(MemoryWorkspace ws = Nd4j.getWorkspaceManager().scopeOutOfWorkspaces()) {
                   
                    //此try块中分配的任何内容都将由GC管理
                    array2 = Nd4j.create(10, 10).assign(2.0f);
                }
    
    
               
                //此时,sumRes包含当前工作间中分配的有效数据。我们希望这里能打印300。
                log.info("Sum: {}", array1.addi(array2).sumNumber().floatValue());
            }
    
    
            /**
             * 
             * 还可以构建充当循环缓冲区的工作间。
             */
            WorkspaceConfiguration circularConfig = WorkspaceConfiguration.builder()
                .initialSize(10 * 1024L * 1024L)
                .policyAllocation(AllocationPolicy.STRICT)
                 // <--- 此选项将禁用工作间随时间的重新分配
                .policyLearning(LearningPolicy.NONE)   
                 //<---此选项使工作间充当循环缓冲区,请注意。
                .policyReset(ResetPolicy.ENDOFBUFFER_REACHED) 
                .build();
    
            for (int x = 0; x < 10; x++) {
              
                //因为这个工作间是循环的,所以我们知道在缓冲区结束之前分配的所有指针都是可行的。
                try (MemoryWorkspace ws1 = Nd4j.getWorkspaceManager().getAndActivateWorkspace(circularConfig, "CIRCULAR_ID")) {
                    INDArray array = Nd4j.create(100);
                   //所以,只要确定缓冲区没有重置,就可以在任何地方使用这个数组。
                   //换句话说:如果你负责流,它适合于生产者/消费者模式使用
                }
            }
        }
    }
    
    
    
    

    翻译:风一样的男子

    image

    相关文章

      网友评论

          本文标题:ND4J/工作间

          本文链接:https://www.haomeiwen.com/subject/fmhabqtx.html