sonson
April 20, 2020
1.2k

# LLVMでHalideみたいな計算グラフ+JITを作りたい

April 20, 2020

## Transcript

1. ### HalideͬΆ͍Կ͔Λ࡞ͬͯΈΔςετ Programming Yuichi Yoshida Chief engineer, DENSO IT Laboratory, Inc.

#Θ͍Θ͍swift @sonson_twit © 2014 DENSO IT Laboratory, Inc., All rights reserved. Redistribution or public display not permitted without written permission from DENSO IT Laboratory, Inc. LLVMͰܭࢉάϥϑΛJITίϯύΠϧ
2. ### αϯϓϧίʔυ • https://github.com/sonsongithub/llvm_jit_compile • https://github.com/sonsongithub/llvm-tutorial • Ϗϧυʹ͸llvm͕ඞཁ • macOSͷ৔߹ brew

install llvm • ubuntuͷ৔߹ apt install llvm

4. ### Computational Graph • ܭࢉΛάϥϑͱͯ͠อ࣋͢Δ • ී௨ͷίʔυͰ͸ɼ݁Ռ͔͠ಘΒΕͳ͍ • ͳͥɼͦΕ͕ඞཁʁ • ඍ෼͍͔ͨ͠Β

• ͳͥɼඍ෼͍ͨ͠ͷ͔ʁ
5. ### χϡʔϥϧωοτϫʔΫ f1 y W1 W2 W3 W4 f2 f3 x

ֶशɿ ͷ஋Λௐ੔͍ͯ͘͠ ͜ͷͨΊʹ Ͱඍ෼͢Δඞཁ͕͋Δ ·ͨ ΋ඍ෼͢Δඞཁ͕͋Δ Back propagationͰݕࡧʂ y Wi f
6. ### ඍ෼ • χϡʔϥϧωοτϫʔΫΛ࣮૷͢Δ৔߹ • ϑΥϫʔυ • ग़ྗΛܭࢉ͢Δ࣮૷ • όοΫϫʔυ •

ௐ੔͢Δͱ͖ʹܭࢉ͢Δ࣮૷ • ࣮͸ɼϑΥϫʔυͷܭࢉͷඍ෼ • ैདྷ͸ɼ͜ΕΒΛผʑʹ࣮૷͍ͯͨ͠ • ࣮૷͕ඇৗʹ໘౗ɾɾɾɾඍ෼͸खܭࢉ • όάͷԹচ

8. ### ී௨ʹ࣮૷͢Δͱ // x=10ͷͱ͖ͷdy/dwͷ஋͕ཉ͍͠ double w = 1; double x =

10; // ͜͜Ͱଈ࣌ʹܭࢉ͞ΕΔɽ double y = sin(w * x); double temp_x = 10; // खͰ୅਺తʹܭࢉͨࣜ͠Λ // ιʔείʔυ্Ͱ࣮૷͢Δඞཁ͕͋Δ double dy_dw = cos(w * temp_x) * temp_x; std::cout << dy_dw << std::endl;
9. ### ܭࢉάϥϑ͕ར༻Ͱ͖Ε͹ // ܭࢉάϥϑͷ৔߹ Param w; Var x,y; // ͜͜Ͱ͸ܭࢉ͞Εͳ͍ɽܭࢉάϥϑ͕ߏங͞ΕΔɽ //

“define by run”ͱݺ͹ΕΔ y = math.sin(w * x); double temp_x = 10; // ඍ෼͸ɼܭࢉάϥϑʹج͖ͮɼࣗಈతʹܭࢉ͞ΕΔɽ double dy_dw = y.diff(temp_x); std::cout << dy_dw << std::endl;

sin(a)

ͳͲͳͲɾɾɾ

18. ### Halideͷ࣮ࡍ \$ DPEF )BMJEF'VOD )BMJEF%4- #JOBSZ "45 ී௨ʹ ίϯύΠϧ Ϗϧυʹ͸

LLVMͱ Halide͕ඞཁ ੩తʹίϯύΠϧ΋Մೳ
19. ### Halideͷ࣮ࡍ \$ DPEF )BMJEF'VOD )BMJEF%4- #JOBSZ )BMJEF*3 --7.*3 #JOBSZ Halide::Func಺ͷ

AST͔ΒIRΛੜ੒ Halide IR͔Β LLVM IRΛੜ੒ LLVMͰ όΠφϦΛੜ੒ "45 ࣮ߦ؀ڥΛηοτ
20. ### \$ DPEF )BMJEF'VOD )BMJEF%4- Halideͷ࣮ࡍ #JOBSZ )BMJEF*3 --7.*3 #JOBSZ ࣮ߦ

Halide::Func಺ͷ AST͔ΒIRΛੜ੒ Halide IR͔Β LLVM IRΛੜ੒ LLVMͰ όΠφϦΛੜ੒ "45 ࣮ߦ؀ڥΛηοτ ࠷ۙ͸͜ͷลͰ QPMZIFESBMPQUJNJ[BUJPOͷͨΊʹ ΋͏Ұஈ֊*3Λు͍ͯ࠷దԽ͢ΔΒ͍͠
21. ### \$ DPEF )BMJEF'VOD )BMJEF%4- Halideͷ࣮ࡍ "45 #JOBSZ )BMJEF*3 --7.*3 #JOBSZ

࣮ߦ Halide::Func಺ͷ AST͔ΒIRΛੜ੒ Halide IR͔Β LLVM IRΛੜ੒ LLVMͰ όΠφϦΛੜ੒ "45 ࣮ߦ؀ڥΛηοτ Ϗϧυʹ͸ LLVMͱ Halide͕ඞཁ Polyhederal IR
22. ### ܭࢉάϥϑ·ͱΊ • ࣗಈඍ෼ • TensoFlow, PyTorchɾɾɾɾɾ • χϡʔϥϧωοτϫʔΫͷֶशʹඞਢͷٕज़ • ฒྻԽͳͲʹ΋

• Halide • ͭ·Γ • ܭࢉΛఆ͓͍ٛͯͯ͠ɼϥϯλΠϜͰͳΜͧ͢Δ • ࣗಈతʹͳΜͧ͢Δͷָ͕ʹͳΔ

24. ### llvm::JIT • Ͳ͏΍ΒJITʹ͸͍͔ͭ͘API/࣮૷͕͋ΔͬΆ͍ • MCJIT • depracatedΒ͍͠ɾɾɾ • Ͱ΋γϯϓϧͰݟ௨͕͍͍͠ •

ORC JIT • KaleidoscopeJIT.hʹ࣮૷͞Ε͍ͯΔ΋ͷ • ·ͩ͜ͷลɾɾɾશવௐࠪͰ͖ͯͳ͍ • http://llvm.1065342.n5.nabble.com/llvm-dev- Questions-about-moving-from-MCJIT-to-Orc-JIT- td129151.html
25. ### ࠓ೔ͷྲྀΕ • LLVM API for C++ͰίʔυΛॻ͘ • IRBuilder • ίʔυΛ֬ೝɼLLVM

IRΛు͘ɼ • MCJIT API • ExecutionEngine • ίϯύΠϧ • C++ͷؔ਺ͷϙΠϯλΛήοτ͢Δ

29. ### LLVM IRΛίʔυ͔Β࡞Δ LLVMͷAPIͰLLVM IRΛ૊ΈཱͯΔ --7.͕؅ཧ͢Δ\$POUFYU .PEVMF 'VODUJPO #MPDL FOUSZ 'VODUJPO

#MPDL UIFO SFUVSO

31. ### ؔ਺ݺͼग़͠ • call.cpp • ͷcosΛݺͼग़͢ • ࣗ෼ͰϩʔΧϧͰ࣮૷ͨؔ͠਺Λݺͼग़͢ • Cͷ໊લ •

C++ͷmangled name • खॱ • ؔ਺ΛϞδϡʔϧʹ௥Ճ • module͔Βؔ਺Λऔಘ • ݺͼग़͢

33. ### ؔ਺Λ࣮ߦ͢Δ // Get pointer to a function which is built

by EngineBuilder. // ؔ਺ͷϙΠϯλͰड͚Δ auto f = reinterpret_cast<double(*)(double*)>( engineBuilder->getFunctionAddress(name); if (f == NULL) { cout << "error" << endl; return 1; } // Execution // a + b double a = 10; cout << f(&a) << endl;
34. ### ܭࢉάϥϑ • graph.cpp • ೋม਺ݻఆͷγϯϓϧͳྫ • ΫϥεͱԋࢉࢠͰߏจ໦Λ࡞Δ • VarΫϥεͱVarΫϥεΛ଍ͯ͠ɼExpressionΛɾɾɾ •

LLVM Tutorial KaleidoscopeϕʔεͰ։ൃ
35. ### ܭࢉάϥϑ • graph.cpp • ೋม਺ݻఆͷγϯϓϧͳྫ • ΫϥεͱԋࢉࢠͰߏจ໦Λ࡞Δ • VarΫϥεͱVarΫϥεΛ଍ͯ͠ɼExpressionΛɾɾɾ •

LLVM Tutorial KaleidoscopeϕʔεͰ։ൃ • ՝୊ • C++ͷϙΠϯλͰड͚ΔgetFunctionAddress • Ҿ਺ͱ໭Γ஋Λࣗ༝ʹઃܭͰ͖ͳ͍
36. ### ࢀߟจݙ • ͖ͭͶ͞ΜͰ΋Θ͔ΔLLVM • llvm.org • LLVM Tutorial, C++൛Λಡ΋͏ •

swift.org • SwiftݴޠαΠτ • https://halide-lang.org • ݁ہɾɾɾίʔυಡΉͷ͕खͬऔΓૣ͠ɾɾɾɾɾ • Halideͷͬ͟ͱͨ͠આ໌ɾɾɾFixStars͕೤৺ʹ׆ಈ͍ͯ͠Δɼ͢͹Β͍͠ • https://www.slideshare.net/ﬁxstars/halide-82788728 • https://qiita.com/fukushima1981/items/fa3537234e19baffc761 • Polyhedral Model • εέδϡʔϧ໰୊Λઢܗ୅਺ʹؼண͠ɼ੔਺ܭը໰୊Ͱղ͘Έ͍ͨͳ • ·ͩɼΑʔ͔ΘΒ͔Μ • Darkroomͱ͍͏ٕज़ͷத਎ͬΆ͍ • https://www.slideshare.net/ﬁxstars/prelude-to-halidepublic-108059122