Получить вывод ISPC с помощью genrule

Я пытаюсь использовать ISPC (неявный компилятор программ SPMD ) с помощью Bazel. Поэтому я начал реализовывать rules_ispc.

К сожалению, я столкнулся с проблемой создания файлов с помощью.

Вы можете воспроизвести мою проблему:

      git clone https://github.com/Vertexwahn/rules_ispc.git
cd rules_ispc
cd tests
bazel build //example:main

Будет сгенерирована следующая ошибка:

ОШИБКА:/home/vertexwahn/rules_ispc/tests/example/BUILD.bazel:3:16: объявленный вывод «example/square.o» не был создан genrule. Вероятно, это связано с тем, что genrule на самом деле не создавал этот вывод, или потому что вывод был каталогом, а genrule запускался удаленно (обратите внимание, что только содержимое объявленных выходных файлов копируется из genrule, запускаемых удаленно) ОШИБКА:/home/vertexwahn/rules_ispc/tests/example/BUILD.bazel:3:16: объявленный вывод «example/square.h» не был создан genrule. Вероятно, это связано с тем, что genrule на самом деле не создавал этот вывод, или потому что вывод был каталогом, а genrule запускался удаленно (обратите внимание, что только содержимое объявленных выходных файлов копируется из genrule, запускаемых удаленно) ОШИБКА:/home/vertexwahn/rules_ispc/tests/example/BUILD.bazel:3:16: Выполнение общего правила //пример:

Я вижу ту же ошибку в Ubuntu 20.04 , Ubuntu 22.04 , Windows Server 2019 , Windows Server 2022 , macOS 11 и macOS 12 . Подробнее см. мой рабочий процесс CI .

Мой файл BUILD.bazel выглядит так:

      load("@rules_ispc//:ispc.bzl", "ispc_cc_library")

ispc_cc_library(
    name = "square",
    srcs = ["square.ispc"],
)

cc_binary(
    name = "main",
    srcs = ["main.cpp"],
    deps = [":square"],
)

вызывает внутренний ISPC для создания файла заголовка и файла o:

      def ispc_cc_library(name, srcs,  target_compatible_with = [], **kwargs):
    for ispc_source_file in srcs:
        generted_header_filename = name + ".h"
        native.genrule(
            name = "%s_ispc_gen" % name,
            srcs = [ispc_source_file],
            outs = [name + ".o", generted_header_filename],
            cmd = select({
                "@platforms//os:linux": "$(location @ispc_linux_x86_64//:ispc) --target=avx2 --arch=x86-64 $(locations %s) --header-outfile=%s -o %s.o" % (ispc_source_file, generted_header_filename, name),
                "@platforms//os:osx": "$(location @ispc_osx_x86_64//:ispc) --target=avx2 --arch=x86-64 $(locations %s) --header-outfile=%s -o %s.o" % (ispc_source_file, generted_header_filename, name),
                "@platforms//os:windows": "$(location @ispc_windows_x86_64//:ispc) --target=avx2 --target-os=windows --arch=x86-64 $(locations %s) --header-outfile=%s -o %s.o" % (ispc_source_file, generted_header_filename, name),
            }),
            tools = select({
                "@platforms//os:linux": ["@ispc_linux_x86_64//:ispc"],
                "@platforms//os:osx": ["@ispc_osx_x86_64//:ispc"],
                "@platforms//os:windows": ["@ispc_windows_x86_64//:ispc"],
            }),
            target_compatible_with = target_compatible_with,
        )
        native.cc_library(
            name = name,
            srcs = [name + ".o"],
            hdrs = [name + ".h"],
            target_compatible_with = target_compatible_with,
            **kwargs
        )

Интересно, как правильно получить сгенерированные файлы ISPC с помощью. Любые подсказки приветствуются!

Подробнее:

квадрат.ispc:

      export void square(uniform float vin[], uniform float vout[],
                   uniform int count) {
    foreach (index = 0 ... count) {
        float v = vin[index];
        v = v * v;
        vout[index] = v;
    }
}

Заголовок, сгенерированный ISPC, должен выглядеть следующим образом:

кв.ч

      //
// C:/rules_ispc/tests/example/square.h
// (Header automatically generated by the ispc compiler.)
// DO NOT EDIT THIS FILE.
//

#pragma once
#include <stdint.h>



#ifdef __cplusplus
namespace ispc { /* namespace */
#endif // __cplusplus

#ifndef __ISPC_ALIGN__
#if defined(__clang__) || !defined(_MSC_VER)
// Clang, GCC, ICC
#define __ISPC_ALIGN__(s) __attribute__((aligned(s)))
#define __ISPC_ALIGNED_STRUCT__(s) struct __ISPC_ALIGN__(s)
#else
// Visual Studio
#define __ISPC_ALIGN__(s) __declspec(align(s))
#define __ISPC_ALIGNED_STRUCT__(s) __ISPC_ALIGN__(s) struct
#endif
#endif


///////////////////////////////////////////////////////////////////////////
// Functions exported from ispc code
///////////////////////////////////////////////////////////////////////////
#if defined(__cplusplus) && (! defined(__ISPC_NO_EXTERN_C) || !__ISPC_NO_EXTERN_C )
extern "C" {
#endif // __cplusplus
    extern void square(float * vin, float * vout, int32_t count);
#if defined(__cplusplus) && (! defined(__ISPC_NO_EXTERN_C) || !__ISPC_NO_EXTERN_C )
} /* end extern C */
#endif // __cplusplus


#ifdef __cplusplus
} /* namespace */
#endif // __cplusplus

Если я ищу сгенерированный заголовочный файл square.h в каталогах, сгенерированных Bazel, кажется, что этот файл не существует, т.е. не сгенерирован.

1 ответ

Вам нужно выполнить$(location)расширение выходов, так как Bazel будет назначать им пути вbazel-out/выходное дерево.

      diff --git a/ispc.bzl b/ispc.bzl
index 1fca9b4..a1b9450 100644
--- a/ispc.bzl
+++ b/ispc.bzl
@@ -6,9 +6,9 @@ def ispc_cc_library(name, srcs,  target_compatible_with = [], **kwargs):
             srcs = [ispc_source_file],
             outs = [name + ".o", generted_header_filename],
             cmd = select({
-                "@platforms//os:linux": "$(location @ispc_linux_x86_64//:ispc) --target=avx2 --arch=x86-64 $(locations %s) --header-outfile=%s -o %s.o" % (ispc_source_file, generted_header_filename, name),
-                "@platforms//os:osx": "$(location @ispc_osx_x86_64//:ispc) --target=avx2 --arch=x86-64 $(locations %s) --header-outfile=%s -o %s.o" % (ispc_source_file, generted_header_filename, name),
-                "@platforms//os:windows": "$(location @ispc_windows_x86_64//:ispc) --target=avx2 --target-os=windows --arch=x86-64 $(locations %s) --header-outfile=%s -o %s.o" % (ispc_source_file, generted_header_filename, name),
+                "@platforms//os:linux": "$(location @ispc_linux_x86_64//:ispc) --target=avx2 --arch=x86-64 $(locations %s) --header-outfile=$(location %s) -o $(location %s.o)" % (ispc_source_file, generted_header_filename, name),
+                "@platforms//os:osx": "$(location @ispc_osx_x86_64//:ispc) --target=avx2 --arch=x86-64 $(locations %s) --header-outfile=$(location %s) -o $(location %s.o)" % (ispc_source_file, generted_header_filename, name),
+                "@platforms//os:windows": "$(location @ispc_windows_x86_64//:ispc) --target=avx2 --target-os=windows --arch=x86-64 $(locations %s) --header-outfile=$(location %s) -o $(location %s.o)" % (ispc_source_file, generted_header_filename, name),
             }),
             tools = select({
                 "@platforms//os:linux": ["@ispc_linux_x86_64//:ispc"],
diff --git a/tests/example/main.cpp b/tests/example/main.cpp
index 44f7feb..1883757 100644
--- a/tests/example/main.cpp
+++ b/tests/example/main.cpp
@@ -1,4 +1,4 @@
-#include "square.h"
+#include "example/square.h"
 
 #include <stdio.h>
 
Другие вопросы по тегам