Metal Compute Kernel не работает с двумя аргументами текстуры - PullRequest
0 голосов
/ 23 января 2019

У меня есть металлическое вычислительное ядро, которое принимает две текстуры для аргументов.Тем не менее, я столкнулся с проблемой, когда ядро ​​не работает.Я сократил проблему до этого простого ядра.

#include <metal_stdlib>
using namespace metal;

kernel void test_texture(       texture2d<float, access::sample>  tex1 [[texture(0)]],
                                texture2d<float, access::sample>  tex2 [[texture(1)]],
                         device float                            *buf  [[buffer(0)]],
                                uint                              idx  [[thread_position_in_grid]]) {
    buf[idx] = 100;
}

И следующий код хоста.

#import <Metal/Metal.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        const size_t max_buffer = 128000000;
        const size_t max_texture = 16384;

        id<MTLDevice> device = MTLCreateSystemDefaultDevice();
        id<MTLLibrary> library = [device newDefaultLibrary];
        id<MTLCommandQueue> queue = [device newCommandQueue];

        id<MTLBuffer> buffer = [device newBufferWithLength:sizeof(float)*max_buffer
                                                   options:MTLResourceCPUCacheModeDefaultCache |
                                                           MTLResourceStorageModeManaged];

        MTLTextureDescriptor *textureDescriptor = [[MTLTextureDescriptor alloc] init];
        textureDescriptor.textureType = MTLTextureType2D;
        textureDescriptor.pixelFormat = MTLPixelFormatR32Float;
        textureDescriptor.width = max_texture;
        textureDescriptor.height = max_texture;
        textureDescriptor.depth = 1;
        textureDescriptor.mipmapLevelCount = 1;
        textureDescriptor.sampleCount = 1;
        textureDescriptor.arrayLength = 1;
        textureDescriptor.resourceOptions = MTLResourceStorageModePrivate |
        MTLResourceCPUCacheModeDefaultCache;
        textureDescriptor.cpuCacheMode = MTLCPUCacheModeDefaultCache;
        textureDescriptor.storageMode = MTLStorageModePrivate;
        textureDescriptor.usage = MTLTextureUsageShaderRead;
        id<MTLTexture> texture1 = [device newTextureWithDescriptor:textureDescriptor];
        id<MTLTexture> texture2 = [device newTextureWithDescriptor:textureDescriptor];

        MTLComputePipelineDescriptor *discriptor = [[MTLComputePipelineDescriptor alloc] init];
        discriptor.computeFunction = [library newFunctionWithName:@"test_texture"];
        discriptor.threadGroupSizeIsMultipleOfThreadExecutionWidth = YES;

        id<MTLComputePipelineState> pipeline = [device newComputePipelineStateWithDescriptor:discriptor
                                                                                     options:MTLPipelineOptionNone
                                                                                  reflection:NULL
                                                                                       error:NULL];

        id<MTLCommandBuffer> command_buffer = queue.commandBuffer;
        id<MTLComputeCommandEncoder> compute_encoder = [command_buffer computeCommandEncoder];
        [compute_encoder setComputePipelineState:pipeline];
        [compute_encoder setTexture:texture1 atIndex:0];
        [compute_encoder setTexture:texture2 atIndex:1];
        [compute_encoder setBuffer:buffer offset:0 atIndex:0];
        [compute_encoder dispatchThreads:MTLSizeMake(max_buffer, 1, 1) threadsPerThreadgroup:MTLSizeMake(1024, 1, 1)];
        [compute_encoder endEncoding];

        id<MTLBlitCommandEncoder> blit_encoder = [command_buffer blitCommandEncoder];
        [blit_encoder synchronizeResource:buffer];
        [blit_encoder endEncoding];

        [command_buffer commit];
        [command_buffer waitUntilCompleted];

        float *result = (float *)buffer.contents;
        NSLog(@"%f",result[0]);
    }
    return 0;
}

Если я закомментирую второй аргумент текстуры, я получу ожидаемое значениекогда я читаю буфер результатов.Однако, когда я оставляю второй аргумент текстуры нетронутым, создается впечатление, что ядро ​​не работает, а значение в результате получается равным нулю.Есть ли ограничение на количество текстур, которые могут быть выбраны в вычислительном ядре на MacOS?Или проблема вызвана тем, что я использовал максимальные размеры текстур в обеих текстурах (у меня не хватает памяти текстур)? сильный текст

1 Ответ

0 голосов
/ 23 января 2019

В вашем случае ошибка, скорее всего, произошла из-за того, что текстуры занимают весь бюджет видеопамяти.16384 x 16384 * sizeof (float) = 1024 МБ памяти на текстуру.Поскольку вы используете MTLStorageModePrivate, ресурс хранится только в видеопамяти.

...