【问题标题】:multiple kernel calls in for loopfor循环中的多个内核调用
【发布时间】:2016-07-19 07:59:32
【问题描述】:

我想在一个循环中执行多个内核调用。我试过的代码如下:

   id<MTLDevice> device = MTLCreateSystemDefaultDevice();
   NSLog(@"Device: %@", [device name]);

   id<MTLCommandQueue> commandQueue = [device newCommandQueue];

   NSError * ns_error = nil;
   //id<MTLLibrary> defaultLibrary = [device newDefaultLibrary];
   id<MTLLibrary>defaultLibrary = [device    newLibraryWithFile:@"/Users/i/tmp/tmp6/s.metallib" error:&ns_error];
   //get fuction
   id<MTLFunction> newfunc = [ defaultLibrary newFunctionWithName:@"sigmoid" ];

   // Buffer for storing encoded commands that are sent to GPU
   id<MTLCommandBuffer> commandBuffer = [commandQueue commandBuffer];

   //set input and output data
   float tmpbuf[2][1000];
   float outbuf[2][1000];
   float final_out[2][1000];
   for( int i = 0; i < 1000; i++ )
   {
      tmpbuf[0][i] = i;
      outbuf[0][i] = 0;
      tmpbuf[1][i] = 10*i;
      outbuf[1][i] = 0;
    }

    int tmp_length = 1000*sizeof(float);
    //get pipelinestat
    id<MTLComputePipelineState> cpipeline[2];
    cpipeline[0]    = [device newComputePipelineStateWithFunction: newfunc error:&ns_error ];
    cpipeline[1]    = [device newComputePipelineStateWithFunction: newfunc error:&ns_error ];
    id<MTLBuffer> inVectorBuffer[2];
    id<MTLBuffer> outVectorBuffer[2];
    id <MTLComputeCommandEncoder> computeCommandEncoder[2];
    computeCommandEncoder[0] = [commandBuffer computeCommandEncoder];
    computeCommandEncoder[1] = [commandBuffer computeCommandEncoder];

    MTLSize ts= {10, 1, 1}; 
    MTLSize numThreadgroups = {100, 1, 1};

    for( int k = 0; k < 2; k++ )
    {
         inVectorBuffer[k]  = [device newBufferWithBytes: tmpbuf[k] length: tmp_length options: MTLResourceOptionCPUCacheModeDefault ];
         [computeCommandEncoder[k] setBuffer: inVectorBuffer[k] offset: 0 atIndex: 0 ];
         outVectorBuffer[k] = [device newBufferWithBytes: outbuf[k] length: tmp_length options: MTLResourceOptionCPUCacheModeDefault ];
         [computeCommandEncoder[k] setBuffer: outVectorBuffer[k] offset: 0 atIndex: 1 ];


         [computeCommandEncoder[k] setComputePipelineState:cpipeline[k] ];
         [computeCommandEncoder[k] dispatchThreadgroups:numThreadgroups threadsPerThreadgroup:ts];
         [computeCommandEncoder[k] endEncoding ];

    }

    [ commandBuffer commit];
    [ commandBuffer waitUntilCompleted];enter code here

它无法正常工作。运行时,复制了以下信息

/Library/Caches/com.apple.xbs/Sources/GPUDriversIntel/GPUDriversIntel-10.14.58/Common/MTLRenderer/Intel/ivb/MTLIGAccelCommandBuffer.m:240: failed assertion `Already have uncommitted encoder'
 Abort trap: 6

谁能指出问题所在。提前致谢。

【问题讨论】:

  • 在循环内部,您将在每次迭代中结束编码,但您从不提交,只有一次,在循环之外。

标签: ios macos metal


【解决方案1】:

您一次只能激活一个计算命令编码器(每个命令缓冲区)。与其在循环外创建多个编码器,不如考虑在循环内部创建命令编码器,并在下一次循环迭代之前结束其编码。

【讨论】:

  • 沃伦是对的。一个 computeCommandEncoder 对应一个任务,应该在循环内创建。
  • 您还可以反复使用相同的计算命令编码器。这里没有理由在循环中调用 endEncoding。这将允许您在循环之外制作命令编码器。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多