From 0ced7ec41fcefdfb1a626d3e6dfb857020233ddb Mon Sep 17 00:00:00 2001 From: IgorErin <47027759+IgorErin@users.noreply.github.com> Date: Wed, 7 Feb 2024 14:29:15 +0300 Subject: [PATCH] Julia RISCV (#18) * refactor (julia): riscv asm gen, compute_root * add (julia): gen asm, header * refactor: halide runtime * add: rutime object --- .github/workflows/test.yaml | 2 +- CMakeLists.txt | 1 + aot/halide_julia_rv.h | 56 +++++ aot/halide_julia_rv.s | 394 ++++++++++++++++++++++++++++++++++++ aot/halide_runtime.o | Bin 0 -> 172792 bytes src/julia.cpp | 28 ++- 6 files changed, 475 insertions(+), 6 deletions(-) create mode 100644 aot/halide_julia_rv.h create mode 100644 aot/halide_julia_rv.s create mode 100644 aot/halide_runtime.o diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 1b76df9..e1fd539 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -45,7 +45,7 @@ jobs: cd build rm ${{ github.workspace }}/aot/* ./perf_algo --gtest_filter=*halide* - mv *.h *.s ${{ github.workspace }}/aot + mv *.h *.s halide_runtime.o ${{ github.workspace }}/aot - name: Build for RISC-V run: | diff --git a/CMakeLists.txt b/CMakeLists.txt index 39356b5..a20e3f2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,6 +67,7 @@ file(GLOB SOURCES src/*.cpp) if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "riscv64") file(GLOB ASM aot/*.s) list(APPEND SOURCES ${ASM}) + list(APPEND SOURCES aot/halide_runtime.o) endif() add_library(algos SHARED ${SOURCES}) diff --git a/aot/halide_julia_rv.h b/aot/halide_julia_rv.h new file mode 100644 index 0000000..7013d13 --- /dev/null +++ b/aot/halide_julia_rv.h @@ -0,0 +1,56 @@ +#ifndef HALIDE__halide_julia_rv_h +#define HALIDE__halide_julia_rv_h +#include + +// Forward declarations of the types used in the interface +// to the Halide pipeline. +// +// For the definitions of these structs, include HalideRuntime.h + +// Halide's representation of a multi-dimensional array. +// Halide::Runtime::Buffer is a more user-friendly wrapper +// around this. Its declaration is in HalideBuffer.h +struct halide_buffer_t; + +// Metadata describing the arguments to the generated function. +// Used to construct calls to the _argv version of the function. +struct halide_filter_metadata_t; + +#ifndef HALIDE_MUST_USE_RESULT +#ifdef __has_attribute +#if __has_attribute(nodiscard) +#define HALIDE_MUST_USE_RESULT [[nodiscard]] +#elif __has_attribute(warn_unused_result) +#define HALIDE_MUST_USE_RESULT __attribute__((warn_unused_result)) +#else +#define HALIDE_MUST_USE_RESULT +#endif +#else +#define HALIDE_MUST_USE_RESULT +#endif +#endif + +#ifndef HALIDE_FUNCTION_ATTRS +#define HALIDE_FUNCTION_ATTRS +#endif + + + +#ifdef __cplusplus +extern "C" { +#endif + +HALIDE_FUNCTION_ATTRS +int halide_julia_rv(struct halide_buffer_t *_f0_buffer); + +HALIDE_FUNCTION_ATTRS +int halide_julia_rv_argv(void **args); + +HALIDE_FUNCTION_ATTRS +const struct halide_filter_metadata_t *halide_julia_rv_metadata(); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/aot/halide_julia_rv.s b/aot/halide_julia_rv.s new file mode 100644 index 0000000..b9128da --- /dev/null +++ b/aot/halide_julia_rv.s @@ -0,0 +1,394 @@ + .text + .attribute 4, 16 + .attribute 5, "rv64gcv0p7" + .file "halide_buffer_t.cpp" + .section .sdata,"aw",@progbits + .p2align 2 # -- Begin function halide_julia_rv +.LCPI0_0: + .word 0xc0000000 # float -2 +.LCPI0_1: + .word 0x3ca3d70a # float 0.0199999996 +.LCPI0_2: + .word 0xbf400000 # float -0.75 +.LCPI0_3: + .word 0x40800000 # float 4 + .section .text.halide_julia_rv,"ax",@progbits + .globl halide_julia_rv + .p2align 1 + .type halide_julia_rv,@function +halide_julia_rv: # @halide_julia_rv +# %bb.0: # %entry + addi sp, sp, -96 + sd ra, 88(sp) # 8-byte Folded Spill + sd s0, 80(sp) # 8-byte Folded Spill + sd s1, 72(sp) # 8-byte Folded Spill + sd s2, 64(sp) # 8-byte Folded Spill + sd s3, 56(sp) # 8-byte Folded Spill + sd s4, 48(sp) # 8-byte Folded Spill + sd s5, 40(sp) # 8-byte Folded Spill + sd s6, 32(sp) # 8-byte Folded Spill + sd s7, 24(sp) # 8-byte Folded Spill + sd s8, 16(sp) # 8-byte Folded Spill + sd s9, 8(sp) # 8-byte Folded Spill + sd s10, 0(sp) # 8-byte Folded Spill + ld a1, 40(a0) + ld s6, 16(a0) + lw s7, 0(a1) + lw s9, 4(a1) + lw s8, 16(a1) + lwu s4, 20(a1) + lw s5, 24(a1) + bnez s6, .LBB0_3 +# %bb.1: # %_halide_buffer_is_bounds_query.exit + ld a2, 0(a0) + bnez a2, .LBB0_3 +# %bb.2: # %_halide_buffer_is_bounds_query.exit31 + sd zero, 16(a0) + sd zero, 8(a0) + sd zero, 0(a0) + lui a2, 512 + addiw a2, a2, 17 + slli a2, a2, 12 + addi a2, a2, -2047 + sd a2, 32(a0) + li a2, 1 + sw a2, 8(a1) + sw zero, 12(a1) + sw s9, 24(a1) + sw zero, 28(a1) + ld a1, 0(a0) + sd zero, 24(a0) + beqz a1, .LBB0_30 +.LBB0_3: # %then_bb2 + sext.w s10, s4 + slti s0, s9, 1 + sgtz a0, s9 + neg a0, a0 + and a0, a0, s9 + slti s1, s10, 1 + sgtz a1, s10 + neg a1, a1 + and a1, a1, s10 + mul s3, a0, a1 + slli s3, s3, 10 + li a0, 0 + mv a1, s3 + call halide_malloc@plt + mv s2, a0 + li a0, 0 + mv a1, s3 + call halide_malloc@plt + or s0, s0, s1 + mv s3, a0 + bnez s0, .LBB0_26 +# %bb.4: # %"for julia.s0.v2.us.us.preheader" + li a7, 0 + mulw a0, s10, s9 +.Lpcrel_hi0: + auipc a1, %pcrel_hi(.LCPI0_0) + flw ft0, %pcrel_lo(.Lpcrel_hi0)(a1) +.Lpcrel_hi1: + auipc a1, %pcrel_hi(.LCPI0_1) + flw ft1, %pcrel_lo(.Lpcrel_hi1)(a1) + slli a0, a0, 2 + slli t3, s9, 2 + li a6, 256 + mv t0, s2 + mv t1, s3 +.LBB0_5: # %"for julia.s0.v2.us.us" + # =>This Loop Header: Depth=1 + # Child Loop BB0_6 Depth 2 + # Child Loop BB0_7 Depth 3 + li a3, 0 + mv s0, t0 + mv a2, t1 +.LBB0_6: # %"for julia.s0.v1.rebased.us.us.us" + # Parent Loop BB0_5 Depth=1 + # => This Loop Header: Depth=2 + # Child Loop BB0_7 Depth 3 + add a1, s8, a3 + fcvt.s.w ft2, a1 + fmadd.s ft2, ft2, ft1, ft0 + mv a1, s7 + mv a4, s0 + mv a5, a2 + mv s1, s9 +.LBB0_7: # %"for julia.s0.v0.rebased.us.us.us" + # Parent Loop BB0_5 Depth=1 + # Parent Loop BB0_6 Depth=2 + # => This Inner Loop Header: Depth=3 + fcvt.s.w ft3, a1 + fmadd.s ft3, ft3, ft1, ft0 + fsw ft3, 0(a4) + fsw ft2, 0(a5) + addi s1, s1, -1 + addi a5, a5, 4 + addi a4, a4, 4 + addiw a1, a1, 1 + bnez s1, .LBB0_7 +# %bb.8: # %"end for julia.s0.v0.rebased.loopexit.us.us.us" + # in Loop: Header=BB0_6 Depth=2 + addi a3, a3, 1 + add a2, a2, t3 + add s0, s0, t3 + bne a3, s10, .LBB0_6 +# %bb.9: # %"end for julia.s0.v1.rebased.split.us.us.us" + # in Loop: Header=BB0_5 Depth=1 + addi a7, a7, 1 + add t1, t1, a0 + add t0, t0, a0 + bne a7, a6, .LBB0_5 +# %bb.10: # %"for julia.s1.v1.rebased.preheader" + blez s9, .LBB0_27 +# %bb.11: # %"for julia.s1.v1.rebased.us.preheader" +.Lpcrel_hi2: + auipc a1, %pcrel_hi(.LCPI0_2) + flw ft0, %pcrel_lo(.Lpcrel_hi2)(a1) + li a6, 0 + add a7, s3, a0 + add t0, s2, a0 + mv t1, s2 + mv t2, s3 +.LBB0_12: # %"for julia.s1.v1.rebased.us" + # =>This Loop Header: Depth=1 + # Child Loop BB0_13 Depth 2 + # Child Loop BB0_14 Depth 3 + li t4, 0 + mv t5, t1 + mv t6, t2 + mv s0, t0 + mv a2, a7 +.LBB0_13: # %"for julia.s1.v0.rebased.us" + # Parent Loop BB0_12 Depth=1 + # => This Loop Header: Depth=2 + # Child Loop BB0_14 Depth 3 + li a1, 255 + mv a5, t5 + mv s1, t6 + mv a3, s0 + mv a4, a2 +.LBB0_14: # %"for julia.s1.r7$x.rebased.us" + # Parent Loop BB0_12 Depth=1 + # Parent Loop BB0_13 Depth=2 + # => This Inner Loop Header: Depth=3 + flw ft1, 0(s1) + flw ft2, 0(a5) + fmul.s ft3, ft1, ft1 + fmsub.s ft2, ft2, ft2, ft3 + fsw ft2, 0(a3) + flw ft2, 0(a5) + fadd.s ft1, ft1, ft1 + fmadd.s ft1, ft1, ft2, ft0 + fsw ft1, 0(a4) + addi a1, a1, -1 + add a4, a4, a0 + add a3, a3, a0 + add s1, s1, a0 + add a5, a5, a0 + bnez a1, .LBB0_14 +# %bb.15: # %"end for julia.s1.r7$x.rebased.us" + # in Loop: Header=BB0_13 Depth=2 + addi t4, t4, 1 + addi a2, a2, 4 + addi s0, s0, 4 + addi t6, t6, 4 + addi t5, t5, 4 + bne t4, s9, .LBB0_13 +# %bb.16: # %"end for julia.s1.v0.rebased.loopexit.us" + # in Loop: Header=BB0_12 Depth=1 + addi a6, a6, 1 + add a7, a7, t3 + add t0, t0, t3 + add t2, t2, t3 + add t1, t1, t3 + bne a6, s4, .LBB0_12 +# %bb.17: # %"for f0.s0.v1.rebased.preheader" + blez s9, .LBB0_27 +# %bb.18: # %"for f0.s0.v1.rebased.us.preheader" +.Lpcrel_hi3: + auipc a1, %pcrel_hi(.LCPI0_3) + flw ft0, %pcrel_lo(.Lpcrel_hi3)(a1) + li t0, 0 + add a6, s3, a0 + add a7, s2, a0 + j .LBB0_20 +.LBB0_19: # %"end for f0.s0.v0.rebased.loopexit.us" + # in Loop: Header=BB0_20 Depth=1 + addi t0, t0, 1 + add a6, a6, t3 + add a7, a7, t3 + beq t0, s4, .LBB0_27 +.LBB0_20: # %"for f0.s0.v1.rebased.us" + # =>This Loop Header: Depth=1 + # Child Loop BB0_22 Depth 2 + # Child Loop BB0_24 Depth 3 + li t5, 0 + mulw t1, s5, t0 + mv t2, a7 + mv t4, a6 + j .LBB0_22 +.LBB0_21: # %"consume argmin.us" + # in Loop: Header=BB0_22 Depth=2 + add a2, t5, t1 + add a2, a2, s6 + sb a1, 0(a2) + addi t5, t5, 1 + addi t4, t4, 4 + addi t2, t2, 4 + beq t5, s9, .LBB0_19 +.LBB0_22: # %"for f0.s0.v0.rebased.us" + # Parent Loop BB0_20 Depth=1 + # => This Loop Header: Depth=2 + # Child Loop BB0_24 Depth 3 + li a1, 0 + li a2, 1 + li s0, 255 + mv a4, t2 + mv a3, t4 + li s1, 1 + j .LBB0_24 +.LBB0_23: # %"for argmin.s1.r7$x.rebased.us" + # in Loop: Header=BB0_24 Depth=3 + addi s0, s0, -1 + addiw a2, a2, 1 + add a3, a3, a0 + add a4, a4, a0 + beqz s0, .LBB0_21 +.LBB0_24: # %"for argmin.s1.r7$x.rebased.us" + # Parent Loop BB0_20 Depth=1 + # Parent Loop BB0_22 Depth=2 + # => This Inner Loop Header: Depth=3 + flw ft1, 0(a4) + flw ft2, 0(a3) + fmul.s ft1, ft1, ft1 + fmadd.s ft1, ft2, ft2, ft1 + fle.s a5, ft0, ft1 + and a5, a5, s1 + beqz a5, .LBB0_23 +# %bb.25: # in Loop: Header=BB0_24 Depth=3 + flt.s s1, ft1, ft0 + mv a1, a2 + j .LBB0_23 +.LBB0_26: # %"end for f0.s0.v1.rebased" + beqz s2, .LBB0_28 +.LBB0_27: # %if.then.i + li a0, 0 + mv a1, s2 + call halide_free@plt +.LBB0_28: # %call_destructor.exit + beqz s3, .LBB0_30 +# %bb.29: # %if.then.i38 + li a0, 0 + mv a1, s3 + call halide_free@plt +.LBB0_30: # %destructor_block + li a0, 0 + ld ra, 88(sp) # 8-byte Folded Reload + ld s0, 80(sp) # 8-byte Folded Reload + ld s1, 72(sp) # 8-byte Folded Reload + ld s2, 64(sp) # 8-byte Folded Reload + ld s3, 56(sp) # 8-byte Folded Reload + ld s4, 48(sp) # 8-byte Folded Reload + ld s5, 40(sp) # 8-byte Folded Reload + ld s6, 32(sp) # 8-byte Folded Reload + ld s7, 24(sp) # 8-byte Folded Reload + ld s8, 16(sp) # 8-byte Folded Reload + ld s9, 8(sp) # 8-byte Folded Reload + ld s10, 0(sp) # 8-byte Folded Reload + addi sp, sp, 96 + ret +.Lfunc_end0: + .size halide_julia_rv, .Lfunc_end0-halide_julia_rv + # -- End function + .section .text.halide_julia_rv_argv,"ax",@progbits + .globl halide_julia_rv_argv # -- Begin function halide_julia_rv_argv + .p2align 1 + .type halide_julia_rv_argv,@function +halide_julia_rv_argv: # @halide_julia_rv_argv +# %bb.0: # %entry + addi sp, sp, -16 + sd ra, 8(sp) # 8-byte Folded Spill + ld a0, 0(a0) + call halide_julia_rv@plt + li a0, 0 + ld ra, 8(sp) # 8-byte Folded Reload + addi sp, sp, 16 + ret +.Lfunc_end1: + .size halide_julia_rv_argv, .Lfunc_end1-halide_julia_rv_argv + # -- End function + .section .text.halide_julia_rv_metadata,"ax",@progbits + .globl halide_julia_rv_metadata # -- Begin function halide_julia_rv_metadata + .p2align 1 + .type halide_julia_rv_metadata,@function +halide_julia_rv_metadata: # @halide_julia_rv_metadata +# %bb.0: # %entry +.Lpcrel_hi4: + auipc a0, %pcrel_hi(.Lhalide_julia_rv_metadata_storage) + addi a0, a0, %pcrel_lo(.Lpcrel_hi4) + ret +.Lfunc_end2: + .size halide_julia_rv_metadata, .Lfunc_end2-halide_julia_rv_metadata + # -- End function + .type .L__unnamed_1,@object # @0 + .section .rodata,"a",@progbits + .p2align 4, 0x0 +.L__unnamed_1: + .zero 32 + .size .L__unnamed_1, 32 + + .type .Lstr,@object # @str + .p2align 5, 0x0 +.Lstr: + .asciz "f0" + .size .Lstr, 3 + + .type .L__unnamed_2,@object # @1 + .section .data.rel.ro,"aw",@progbits + .p2align 4, 0x0 +.L__unnamed_2: + .quad .Lstr + .word 2 # 0x2 + .word 2 # 0x2 + .byte 1 # 0x1 + .byte 8 # 0x8 + .half 1 # 0x1 + .zero 4 + .quad 0 + .quad 0 + .quad 0 + .quad 0 + .quad .L__unnamed_1 + .size .L__unnamed_2, 64 + + .type .Lstr.4,@object # @str.4 + .section .rodata,"a",@progbits + .p2align 5, 0x0 +.Lstr.4: + .asciz "riscv-64-linux-no_asserts-no_runtime" + .size .Lstr.4, 37 + + .type .Lstr.5,@object # @str.5 + .p2align 5, 0x0 +.Lstr.5: + .asciz "halide_julia_rv" + .size .Lstr.5, 16 + + .type .Lhalide_julia_rv_metadata_storage,@object # @halide_julia_rv_metadata_storage + .section .data.rel.ro,"aw",@progbits + .p2align 4, 0x0 +.Lhalide_julia_rv_metadata_storage: + .word 1 # 0x1 + .word 1 # 0x1 + .quad .L__unnamed_2 + .quad .Lstr.4 + .quad .Lstr.5 + .size .Lhalide_julia_rv_metadata_storage, 32 + + .ident "clang version 16.0.0 (https://github.com/dkurt/llvm-rvv-071 b027aa1b59c9f53240bdc836f39656723fdf9df0)" + .ident "clang version 16.0.0 (https://github.com/dkurt/llvm-rvv-071 b027aa1b59c9f53240bdc836f39656723fdf9df0)" + .ident "clang version 16.0.0 (https://github.com/dkurt/llvm-rvv-071 b027aa1b59c9f53240bdc836f39656723fdf9df0)" + .ident "clang version 16.0.0 (https://github.com/dkurt/llvm-rvv-071 b027aa1b59c9f53240bdc836f39656723fdf9df0)" + .ident "clang version 16.0.0 (https://github.com/dkurt/llvm-rvv-071 b027aa1b59c9f53240bdc836f39656723fdf9df0)" + .ident "clang version 16.0.0 (https://github.com/dkurt/llvm-rvv-071 b027aa1b59c9f53240bdc836f39656723fdf9df0)" + .section ".note.GNU-stack","",@progbits diff --git a/aot/halide_runtime.o b/aot/halide_runtime.o new file mode 100644 index 0000000000000000000000000000000000000000..4880b54f145613f54fdbd45a065a4f63ec7b2a00 GIT binary patch literal 172792 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%0D{+SX7 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 P_>8(HxX}6U=CA()d>SAx literal 0 HcmV?d00001 diff --git a/src/julia.cpp b/src/julia.cpp index 07f8db7..d09da17 100644 --- a/src/julia.cpp +++ b/src/julia.cpp @@ -2,8 +2,7 @@ #ifdef __riscv #include -#include "bgr2gray_interleaved.h" -#include "bgr2gray_planar.h" +#include "halide_julia_rv.h" using namespace Halide::Runtime; @@ -65,7 +64,7 @@ struct HComplex { void halide_julia(uint8_t* dst, int height, int width) { Buffer output(dst, {width, height}); #ifdef __riscv - // add later + halide_julia_rv(output); #else static Func julia("julia"); @@ -80,7 +79,6 @@ void halide_julia(uint8_t* dst, int height, int width) { Expr y_ranged; y_ranged = halide_julia_norm(y, width); - Func julia; Var t; julia(x, y, t) = HComplex(x_ranged, y_ranged); @@ -96,7 +94,27 @@ void halide_julia(uint8_t* dst, int height, int width) { Func result; result(x, y) = cast(first_escape[0]); - result.realize(output); + julia.compute_at(result, y); + + // result.realize(output); + Target target; + target.os = Target::OS::Linux; + target.arch = Target::Arch::RISCV; + target.bits = 64; + + Halide::compile_standalone_runtime("halide_runtime.o", target); + + std::vector features; + // features.push_back(Target::RVV); TODO + features.push_back(Target::NoAsserts); + features.push_back(Target::NoRuntime); + target.set_features(features); + + std::cout << target << std::endl; + result.print_loop_nest(); + + result.compile_to_header("halide_julia_rv.h", {}, "halide_julia_rv", target); + result.compile_to_assembly("halide_julia_rv.s", {}, "halide_julia_rv", target); } #endif }