Функция сборки отсутствует в файле .o - PullRequest
1 голос
/ 01 октября 2019

Мне нужно собрать OpenBLAS статическую библиотеку, которая содержит функции сборки - https://github.com/xianyi/OpenBLAS/releases. Лично я пытаюсь собрать 0.3.6 версию.

Хотя процесс компиляции проходит успешно, в файлах .o отсутствуют реальные реализации, когда речь идет о функциях сборки.

У меня проблемы со всеми функциями сборки, но я приведу в качестве примера один из них - _sdot_k.

Как определить, что реализация отсутствует? Я могу определить это по тому факту, что когда я выполняю nm [library_name].a, вывод для этой функции следующий:

libopenblas_armv8p-r0.3.6.a(sdot_k.o):
0000000000000050 t .Ldot_kernel_F1
0000000000000058 t .Ldot_kernel_F10
0000000000000028 t .Ldot_kernel_F4
000000000000001c t .Ldot_kernel_F_BEGIN
00000000000000d8 t .Ldot_kernel_L999
00000000000000bc t .Ldot_kernel_S1
00000000000000c4 t .Ldot_kernel_S10
0000000000000084 t .Ldot_kernel_S4
0000000000000070 t .Ldot_kernel_S_BEGIN
0000000000000000 t ltmp0

Нет идентификатора T, который сообщает, что реализация функции находится здесь, в файле .o,И, конечно, если я добавлю эту библиотеку в свой проект iOS, у меня будет такая ошибка:

Undefined symbols for architecture arm64:
  "_sdot_k", referenced from:
      _strmv_TLN in libopenblas.a(strmv_TLN.o)
      _strmv_TLU in libopenblas.a(strmv_TLU.o)
      _strmv_TUN in libopenblas.a(strmv_TUN.o)
      _strmv_TUU in libopenblas.a(strmv_TUU.o)
      _trmv_kernel in libopenblas.a(strmv_thread_TLN.o)
      _trmv_kernel in libopenblas.a(strmv_thread_TLU.o)
      _trmv_kernel in libopenblas.a(strmv_thread_TUN.o)
      ...

Вот фактический файл dot.S:

#define ASSEMBLER
#include "common.h"

#define N   x0  /* vector length */
#define X   x1  /* X vector address */
#define INC_X   x2  /* X stride */
#define Y   x3  /* Y vector address */
#define INC_Y   x4  /* Y stride */
#define I   x5  /* loop variable */

/*******************************************************************************
* Macro definitions
*******************************************************************************/

#if !defined(DOUBLE)
#if !defined(DSDOT)
#define REG0    wzr
#define DOTF    s0
#else // DSDOT
#define REG0    xzr
#define DOTF    d0
#endif
#define DOTI    s1
#define TMPX    s2
#define LD1VX   {v2.s}[0]
#define TMPY    s3
#define LD1VY   {v3.s}[0]
#define TMPVY   v3.s[0]
#define SZ  4
#else
#define REG0    xzr
#define DOTF    d0
#define DOTI    d1
#define TMPX    d2
#define LD1VX   {v2.d}[0]
#define TMPY    d3
#define LD1VY   {v3.d}[0]
#define TMPVY   v3.d[0]
#define SZ  8
#endif

/******************************************************************************/

.macro KERNEL_F1
    ldr TMPX, [X], #SZ
    ldr TMPY, [Y], #SZ
#if !defined(DSDOT)
    fmadd   DOTF, TMPX, TMPY, DOTF
#else // DSDOT
    fcvt    d3, TMPY
    fcvt    d2, TMPX
    fmul    d2, d2, d3
    fadd    DOTF, DOTF, d2
#endif
.endm

.macro KERNEL_F4
#if !defined(DOUBLE)
    ld1 {v2.4s}, [X], #16
    ld1 {v3.4s}, [Y], #16
#if !defined(DSDOT)
    fmla    v0.4s, v2.4s, v3.4s
#else
    fcvtl2  v5.2d, v3.4s
    fcvtl2  v4.2d, v2.4s
    fcvtl   v3.2d, v3.2s
    fcvtl   v2.2d, v2.2s
    fmul    v4.2d, v4.2d, v5.2d
    fmul    v2.2d, v2.2d, v3.2d
    fadd    v2.2d, v2.2d, v4.2d
    fadd    v0.2d, v0.2d, v2.2d
#endif
#else //DOUBLE
    ld1 {v2.2d, v3.2d}, [X], #32
    ld1 {v4.2d, v5.2d}, [Y], #32
    fmul    v2.2d, v2.2d, v4.2d
    fmul    v3.2d, v3.2d, v5.2d
    fadd    v0.2d, v0.2d, v2.2d
    fadd    v0.2d, v0.2d, v3.2d
#endif
    PRFM    PLDL1KEEP, [X, #1024]
    PRFM    PLDL1KEEP, [Y, #1024]
.endm

.macro KERNEL_F4_FINALIZE
#if !defined(DOUBLE)
#if !defined(DSDOT)
    ext v1.16b, v0.16b, v0.16b, #8
    fadd    v0.2s, v0.2s, v1.2s
    faddp   DOTF, v0.2s
#else
    faddp   DOTF, v0.2d
#endif
#else //DOUBLE
    faddp   DOTF, v0.2d
#endif
.endm

.macro INIT_S
#if !defined(DOUBLE)
    lsl INC_X, INC_X, #2
    lsl INC_Y, INC_Y, #2
#else
    lsl INC_X, INC_X, #3
    lsl INC_Y, INC_Y, #3
#endif
.endm

.macro KERNEL_S1
    ld1 LD1VX, [X], INC_X
    ld1 LD1VY, [Y], INC_Y
#if !defined(DSDOT)
    fmadd   DOTF, TMPX, TMPY, DOTF
#else // DSDOT
    fcvt    d3, TMPY
    fcvt    d2, TMPX
    fmul    d2, d2, d3
    fadd    DOTF, DOTF, d2
#endif
.endm

/*******************************************************************************
* End of macro definitions
*******************************************************************************/

    PROLOGUE

    fmov    DOTF, REG0
#if defined(DOUBLE)
    fmov    d6, DOTF
#endif

    cmp N, xzr
    ble .Ldot_kernel_L999

    cmp INC_X, #1
    bne .Ldot_kernel_S_BEGIN
    cmp INC_Y, #1
    bne .Ldot_kernel_S_BEGIN

.Ldot_kernel_F_BEGIN:

    asr I, N, #2
    cmp I, xzr
    beq .Ldot_kernel_F1

.Ldot_kernel_F4:

    KERNEL_F4

    subs    I, I, #1
    bne .Ldot_kernel_F4

    KERNEL_F4_FINALIZE

.Ldot_kernel_F1:

    ands    I, N, #3
    ble .Ldot_kernel_L999

.Ldot_kernel_F10:

    KERNEL_F1

    subs    I, I, #1
        bne     .Ldot_kernel_F10

    ret

.Ldot_kernel_S_BEGIN:

    INIT_S

    asr I, N, #2
    cmp I, xzr
    ble .Ldot_kernel_S1

.Ldot_kernel_S4:

    KERNEL_S1
    KERNEL_S1
    KERNEL_S1
    KERNEL_S1

    subs    I, I, #1
    bne .Ldot_kernel_S4

.Ldot_kernel_S1:

    ands    I, N, #3
    ble .Ldot_kernel_L999

.Ldot_kernel_S10:

    KERNEL_S1

    subs    I, I, #1
        bne     .Ldot_kernel_S10

.Ldot_kernel_L999:

    ret

    EPILOGUE

Как видите, естьPROLOGUE и EPILOGUE, которые являются макросами, определенными в заголовке C:

#ifndef F_INTERFACE
#define REALNAME ASMNAME
#else
#define REALNAME ASMFNAME
#endif

#if defined(ASSEMBLER) && !defined(NEEDPARAM)

#define PROLOGUE \
    .text ;\
    .align  2 ;\
    .globl  REALNAME ;\
REALNAME:

#define EPILOGUE

#define PROFCODE

#endif

Мои внутренности говорят мне, что проблема лежит где-то в EPILOGUE и PROLOGUE, но у меня нетПриличные знания ассемблера, чтобы самостоятельно разобраться в проблеме.

Также я нашел эту статью - https://developer.apple.com/library/archive/documentation/DeveloperTools/Reference/Assembler/040-Assembler_Directives/asm_directives.html,, но она мне не сильно помогла. Возможно, из-за отсутствия у меня навыка сборки.

ПРИМЕЧАНИЕ: Если кто-то борется с той же библиотекой, пытаясь заставить ее работать на iOS, вот моя ветка о Github - https://github.com/xianyi/OpenBLAS/issues/2275#issuecomment-536982253is. Содержит описания всех проблем, которые я преодолел.

ПРИМЕЧАНИЕ 2: Мне действительно нужна библиотека OpenBLAS, и использование Accelerate.framework в моем случае, к сожалению, не вариант.

1 Ответ

0 голосов
/ 01 октября 2019

Я счастлив сказать, что преодолел эту проблему. Проблема действительно была в моих PROLOGUE макросах. Макросы

PROLOGUE, которые я использовал, конвертировали в код сборки следующим образом:

.text; .align 2; .globl REALNAME; REALNAME:

И это было проблемой. Чтобы заставить метку сборки работать, она должна выглядеть следующим образом:

   .text; 
   .align 2; 
   .globl REALNAME; 
REALNAME:
   //assembly code

Поэтому, чтобы добиться этого результата, я изменил макрос C на макрос GAS как таковой:

.macro PROLOGUE
    .text
    .align 2
    .globl REALNAME
REALNAME:
.endm

После того, как проблема исчезла!

ПРИМЕЧАНИЕ: Чтобы устранить любые недоразумения, ; на самом деле здесь не играет роли. Это новая строка после каждой запятой, что имеет значение.

...