From 0e90f805a4df8c2186aac2c1c66b03f015705281 Mon Sep 17 00:00:00 2001 From: Surma Date: Wed, 5 Aug 2020 17:20:33 +0100 Subject: [PATCH] Add Node 14 for SIMD tests --- codecs/cpp.Dockerfile | 2 ++ codecs/mozjpeg_enc/.emscripten | 13 ++++++++ codecs/mozjpeg_enc/Makefile | 10 +++++++ codecs/mozjpeg_enc/example.html | 44 +++++++++++++++------------- codecs/mozjpeg_enc/mozjpeg_enc.cpp | 2 ++ codecs/mozjpeg_enc/mozjpeg_enc.wasm | Bin 217799 -> 221976 bytes 6 files changed, 51 insertions(+), 20 deletions(-) create mode 100644 codecs/mozjpeg_enc/.emscripten diff --git a/codecs/cpp.Dockerfile b/codecs/cpp.Dockerfile index 88e489db..ea1507ae 100644 --- a/codecs/cpp.Dockerfile +++ b/codecs/cpp.Dockerfile @@ -5,5 +5,7 @@ ENV CXXFLAGS "${CFLAGS} -std=c++17" ENV LDFLAGS "${CFLAGS}" # Build and cache standard libraries with these flags RUN emcc ${CXXFLAGS} --bind -xc++ /dev/null -o /dev/null +RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash +RUN /bin/bash -ic 'nvm install 14.7.0' WORKDIR /src CMD ["sh", "-c", "emmake make -j`nproc`"] diff --git a/codecs/mozjpeg_enc/.emscripten b/codecs/mozjpeg_enc/.emscripten new file mode 100644 index 00000000..5da1fd50 --- /dev/null +++ b/codecs/mozjpeg_enc/.emscripten @@ -0,0 +1,13 @@ +import os +emsdk_path = "/emsdk/" +#NODE_JS = emsdk_path + '/node/12.18.1_64bit/bin/node' +# We need a newer version of Node that supports the most recent iteration of Wasm SIMD +# and need to enable that experimental support via flag so that autoconf can successfully +# detect SIMD support. +NODE_JS=["/root/.nvm/versions/node/v14.7.0/bin/node", "--experimental-wasm-simd"] +LLVM_ROOT = emsdk_path + '/upstream/bin' +BINARYEN_ROOT = emsdk_path + '/upstream' +EMSCRIPTEN_ROOT = emsdk_path + '/upstream/emscripten' +TEMP_DIR = emsdk_path + '/tmp' +COMPILER_ENGINE = NODE_JS +JS_ENGINES = [NODE_JS] diff --git a/codecs/mozjpeg_enc/Makefile b/codecs/mozjpeg_enc/Makefile index 30b5ca0e..542e0b78 100644 --- a/codecs/mozjpeg_enc/Makefile +++ b/codecs/mozjpeg_enc/Makefile @@ -5,11 +5,21 @@ CODEC_OUT := $(addprefix $(CODEC_DIR)/, $(CODEC_OUT_RELATIVE)) OUT_JS := mozjpeg_enc.js OUT_WASM := $(OUT_JS:.js=.wasm) +CFLAGS += -msimd128 -msse --em-config /src/.emscripten +CXXFLAGS += -msimd128 -msse --em-config /src/.emscripten + +#override CFLAGS += "-msimd128 -msse" +#override CXXFLAGS += "-msimd128 -msse" + .PHONY: all clean all: $(OUT_JS) %.js: %.cpp $(CODEC_OUT) + # We just to disable the overridden NODE_JS binary because + # `--closure 1` can’t handle arrays in `.emscripten` it seems. + # https://github.com/emscripten-core/emsdk/issues/583 + export EM_NODE_JS='/root/.nvm/versions/node/v14.7.0/bin/node' && \ $(CXX) \ -I $(CODEC_DIR) \ ${CXXFLAGS} \ diff --git a/codecs/mozjpeg_enc/example.html b/codecs/mozjpeg_enc/example.html index 2cff900f..76b54ef1 100644 --- a/codecs/mozjpeg_enc/example.html +++ b/codecs/mozjpeg_enc/example.html @@ -1,26 +1,14 @@ diff --git a/codecs/mozjpeg_enc/mozjpeg_enc.cpp b/codecs/mozjpeg_enc/mozjpeg_enc.cpp index 27388587..3673db5c 100644 --- a/codecs/mozjpeg_enc/mozjpeg_enc.cpp +++ b/codecs/mozjpeg_enc/mozjpeg_enc.cpp @@ -1,5 +1,7 @@ #include #include +#include +#include #include #include #include diff --git a/codecs/mozjpeg_enc/mozjpeg_enc.wasm b/codecs/mozjpeg_enc/mozjpeg_enc.wasm index bf5df72946251fc63b1db3fba73410e5e20fe107..e6e508c22c6321cf93ad221e08a87eb74c8aa572 100644 GIT binary patch delta 12188 zcmb_i378etm9BHE>g`Lt*RP?QZs5KGwFMe+VVQ0SUF;yXEJnXf)L^!WuXPN5=rDs) zZQMg-u>ysf1(VDdOcadI&>;Awzr^Jmx6yniaWqi^Xc9GwYcN{${O4A^M?=ubd^62Q z-Ku-eJ@?#m&OPVcbKj%?p56RN_TG{ZdXqOqbc$5oTPj8;P2DhtmJ4~)>lK$YTjIoG zakx3!Fp@FT7P_trvq9jmYU*1k`7N`8#Nh_7oq~%s z1+9V~dXN?gZ*J#=an3Kb5R9gufQI&xW3g=m`1g{xuJe>n)yYNpARB>slo~7<{d|0i zW2ek}zv-MZ&H2TVIln2wIX`*s>wu-Gf{B?^Coirs0Xm8R=2Zm#Ze|qAb*hQHw|(lR z%~G)?jw7klr;W|kR;AiR_33FN^kfEtmDH|j)pxt%BL1E!;;z2x)|vhgDjRy2G^HVv z6~Jx1;#?!Ty=TmD5spfd7%c+%}!7D&;u7 z-AYg>XFxJ-XPLoZ8v#!^M#UD=oSW6sGArXs-UYy03Brf2b=LJFJ1a9X9b`2Uy5{mD z`fq1~sX@2ov6l6052G(ylO)H$HE6Q=8=~z|tE#q^HE_}wYVzHtk1=}VRQUNWN z0?6wj(aJao)tG~cSPCTL-bJ%o^KnLvbH@sdFuZTfY9Z6xI%`VGa1xV53EDEeS7%Kl zv)VTMauNR;wjJ-4@6Ii|0WT%3VF#2A)^PL`9MCSs;_*uA6#~G!2;ZTaphXYgp(2dhNzMRM4R(+nmkAl4DpNsc z(Cv&2eoT1WO~DeTt9KGKtw?nec7mFqlSKHYbrSn6!`n1}LSZvOt5#*SmVPkO*{|lG zM7kHuKf%@8;00#0w48^?8Vd!g%~UqAOcS(V4p1O(Q>+1vQXpETK(sXln!x1!6e&={ zVEjA23L_A!(1qsef8k~TjfRRfn$67`?ogS)i6%+v>s!zhJHIt?PcD+Pxdj-i2q^qVLlN@4%u-cyC#J zJ>KtJ?1-Q3^bRb(gw}hDm$Ztf_js2rSW%sIGCbFO`bS`C(z&mD-QA97pZ8_@cJ=1-;s(9% zZTM_QS~=r{idfYbKYJg=cNy@pw5q!Cf*ciLtR*{vXtPJi1njA-SD(DlBsd>jens`YT};)vZ^0F?!9Ldi9eQ{85J%hloW5 z>xoyq{OY^B*Kd5Fy7GoD!hl^jjvdynG(t)husTP}r&%Y~Euz}D`eLK%U-xsOzH0f} zlL+(aa4Lp(-gRB+v{D#$>>A-Mzj;V?_e~GRXtVdP>s}r)3ZNNZ>+S8eCS&(uA5Ibp z^k_j5Yb#ZI*PmdIN2BW5LN-_hPM6)xz3_DS=qI~Hy-2&2dx!I5MDP)V6rDOorH29Pnja=idEHj{UmwUZa!%w{Lc!6 zm8aV);|V?riO4CWUE=g6Do*-JXTaOF`BZPkZ4GXcy(+;ViNgwlk--rNAt^aYOvNta zNLdz8wBhJ0ob~OMAf+RJK_{UziJ@#kYyz`1^>=W3P=diJX92s2pH8rGiADq?$WG0` z7T~|lzhKi}Sh2UBG#pf_FeX zC~G@{21KGV?Fe8%!!_P)NR-$WD?v%&BskTG@|c9zdi#|4V@T)O;e6)yGpIEvs?3o$ z5GT1)({~OtPH^K_i>vfi-u650FUw4uXq_z^9h!GJ3(w?K#8TU!jQqQt@oxCmEpAY< zJF($19DxIaG`mA~K&$pt*%@VNSYItYfCwHZJf0xC15EFN1kuv2z*g((h}MNxtxI-F zMTRptmU%6U8$_o4|ZJs*Zf%nsjz0 z>Fy}av3hKCwC4Tb;mK#193Jv;YX*{cCttC;I41HALe7F@z6aR`@(l!oo6&EogvARU zem=XrPD%%<7anPzV}v7x^?A+(Ol!JrSo7FnS{LCdth13$OY9$OZkYud&5N)E@nBvw zoDEe^c=SdixgTdpm##)4`>X$$;O&3>oLFe5Ue^<|kd+2$eXF%Nf&mt=iNV5L*fAudCPjYDLPA4W0IyMTrbpt4)?A(a+jh#` zPxVzBSoOdB?y?g61q+b<0(My_K<};JwZ@P&^KvpT4%7Y56=_{xca}a&)d~Cmi~QGe z^td><$KRQ!i>cz<7M+LY-z-{y=3$Gv`>rM0K`mWY&U2pg z`}eBJmmNVHt7rbHXzTo5j|h-iBB2z*lwrYYuU{{PmLs`Q9CGTtGe558g-$ z>hbiq9-&Ru$KD!EG`{-g+usp1-dp?Lxvd+?&eeQVZ?C%~OEa``R^n-mzwiCm2y|Zm z%L5?r!$YUhChz$}+jCoYnicp^bx8TvPS5|~W^w;c&;IN6;=!HXU4N}27rNlXDYVYp z^x>nJ?81+}M41gcOwJn}YkpSuti!`F`>Qy6Y}nx?4%%HnA0c(HQ8BNP4C*cn8xTB;&%|uw+_|S zS>{anZg0-MrSzP4`@XTF|9)xH$o$NoM)0flZfulPo%z?>z&s^W;f61VEL)&L(;q;OG zJEIXBu~!WgP^`87Lk68n?f&})ok;C{!%dntv^;c*7^}wu{zy|EU=L zNNf=Ph$Ic^TOTKEt6Tk+Bu&X;sDWe`Nk`H8hQBOHd&u*Lr|29sm#1hud3|=8zDMGA z;g^auHFt+l`+PlN8%V9Mqk*nB==#3?q4b-0{6i83Vvzrxk@Q$IQlKUrHsNRR)&?(a z;XQ`7?>0%jS$ftVHl9YAoI4tQbH-CwoL=d>aU!jx6#O7NWca(j*ktp!%JP8_FW_v56%XLqoRTv;HYfMp*d8;8>-JISG- zO?;(niZ1_yB{ZrSQztaozKx`lbI^oeI6x&g#;3O|VFd+VkzoasZI$+OVd8HOU+6=! z6jdo|AySL}*vq$QASU2W*h$Bb3UfB1iYvlF$boxLfeBS-0rP1WaTxv#2gC&S7(J#>)is2K7=)RSEX%^8v z{)4|CgyIkUp1wF07&!N`jYE7W+8iR02>p!2sggZhn|NJt6jW0u;b+*taI5+E?4x1I ziy+RxnUvVKgj+f^ROLt{`G49+@+4HE;Aa+Es~}z8Rah;wz$1`VL3}mj3HwPRATQoe zqe%2!v7c@vy2?L%fJWw>(|9-5j@#qfHp3zr+kjf< zD>PH1-Z?=-aDakCI4bp`$i_Y(7L~YgdPcR3OI+%WxWuL2REZ1Tn9FeenmVg(;ZTTK z{TKg8x4Uo0%%n@J#np6`ffXVV zZl)kDL32hq$;||mXwZx+=P^+V+ue}4f{CaG`UZAzvOtidA@eS(jWTX@v65yGj%ei} zuue_y604&F)?OUwYOg=T$po`8dnZHvMI5U~YP->imUiQ~B8SX~BP?|TfSTfw6C)5% zOboxrqF@ppY#M{ItL+HK<7g8R7{FhiiJ-RqB%j>>K1$jSoZcHS5h$VhAfYn+L1lAr zhR>>cIKFG~q;^(vpFpKj7MX_zo*!pT%vi=@{kGboXMO=fE8UB5I4BcLmr*R02`7#k zwx*1S#A=>g`yWT*I9%Yfa3hX*(@?9IsAu5RH;pt%PhjCsK?y8m9JFdSgZQuJg6cES zKo+`$ny{TBZzaG2?*}W;NV6NAfp}n{U~#I=1&nS~3x))zJJ+m4XA|E6fc{W)HU+1+ zxDaRznz01b{GDZH1P(!P zPc={?1Q~7(2EST^r9zll17X|OK$#E}tAV&88L^lPL2(5VIOd~78|^r_3!M5*h!7%5 z$e7xO>1UH7=DPV+*dgq=%@te>g9{0g0yd7YAdxcYV}t=)Qs4a=It>)o~GXfN)L2NT|_|5ebFlsuzWY4jol`Mkp~tDWZZ_!O`l- z+dw7957b_OiQqT}J29LOt-?gB+c<*(-pcUS2#!|4(dsZ25Gf$t23Cf#G7%P9g@smE z<-8=yj(}Sc9Ib+*)v?h)rNoa$e#GGqrZ7_|^p7NdGx$yL8{Z;~)cK7Ic*)>pMt2#X z)7uc=s^fF82=Te*SwJlf_(@cpvNDHPOg8f!W8(Cn!OjM+L?Qt`s6o0BwM3m-qE3zL zp-DwTG3!oYl|}eXb^N9}J{N-W(h6r!;1Z45hD%NJO9E_2HNWc5;y6%5VNbDVCuTmo zCItq;9{Q7*0|H6_IJ5E1UwlgS+bNejl~P0Iq4|gz_O$4O=t^~FxFVYkrw-AfxCouy zLWrKJqjT9d36?QMQYL0zG3|#DJE@Qr^t&OQ@M?xN#t|%}W7O$znF0jV(v^r|RnfGq zb@bLcdMkDlXPjZlO>M8iMPk$zVRRaog%g1b9&m2O=Q11YqV2^lVfGY{$j8wo?VM`+ z$<8wf7J=TbsJy&|%eLr^OcBD5s>G;6qCZSh;H*=Mf4o>V6~TgBWkM-7A=W66`{4qB z6bQ`eGZ9WZVU=GJqe;fu69@**#sXtslD+m*B;fd4A!tk|B zaiN5Ov4eESlPWqu+8gr9r12%;=OFi5P54z)$6fW+`YJve*;#eB%w7w@8`9Gt(`>Nq zd_vxkkvZou7q&Zb@yd<9Va``cq0r#}&>7F4z9FFd5#!e9AkYW)m3{nKH! zd;xvjOXp7{(j&#CxOE^Y=Cz>MQz^$d?!l%+nf%LMp_X|<-*?T%J znc@6#Dx6-9%5bXUOa9?MQ%eE)6)us1i&Sd?@^;-H^9JFr(U*Uq5&l=-AhW~7WVkND zZ3*rd7qr0LgBJe>8)5|#Kvm>nS#koe10Dz5aHh@km%Txa?lI$mAzEy+$4)R^zOsZ= zv^gy(JR(i$1!caYLQ;9z_@ARFstQw2GsA zJWHoH8oJ>ctCL~O1iLC}<}(|TW?T>PPgi;cq8xr05E&VpNgliDZ!)kMQJ#l=*NsE4 z=0c8{;~}E28`0`ld<`?4&&!x2hWt$>;Kh#}(EwySev`_!hU1ckYNVYl*h$k{_G@A2}A@fo-)N#hO6f>R-xF?)I6*OI}QbH z5X7aq3TZ!aIXgIxoOpJ`AIxs?>}o}LLrhVNQDctB4SW^Gq}EjrcUZP2O4FCV1uxqnV0mpX1LWnpWGFqOht1{b#KJ4~fi$KX^- zb<|QR#I`mhB^ZG_DYQsBRI9`L!KlJa36TibF>Zv_8eySDs)Q(^5+v-<2#!`!L8~K+ zVh_fTFe^jo#ZffEM5{2-)>0|t6>S0+)rudq3eFeT$fB4EM zEiTz2I9dfq%c&HIgm@aO%n4G9I=^$cZBZp9j?OLNuV(m7XD2`|Oo(qd2M-F9 zDjpOjRXiw6s(275RT+dtRNCUWjI{WLW#K$yV`Jeuvo`_rOfgIN)sb^}g6d_2G+(EN ze1(}7rf`vT)ffv?EuMo@EqHzBrJJL>o1;gEc^5Mn=3UHSn0N7D&bv70Pz>g<3GkBO z`KxmjE8rcx<-pt8hQL)Ad?8QK$awDfjOLg*6a-zj`<gC?ziDiC<0(FKwREJ-%3^pCtVsJiWZZ9Wgk;SHAkLt$>>}+a# zD>TLeLcrji5smKW(FK^$pe+}HklUzZ1SkbBL>8y)I^n`X2AdpsA8c~UN+Tj$m_B~Q zag;?3W`7yr@C-+p%U}Y>WSP6-xL**7RsMJ1p-CN3ID9CIPh7Y{1q)54jFTuFXW2s5 z#y<>5$UK*#QpjsKUrwn~RKm}{OHD2=B7ud3R~1%JfIx!5zd3>CqpY zHx--In~F_Q6<=kr8I%k)zUUlGW{A3iw&7*Caw7PL5`nI}8oV%4U=)LJ|NUbsqi~|) zbaOBbzgOsNQUgUz8TMfl&Vfq&x`>J=F*pOm>E>1dp=Dy1W=Ixg#?f;>+{ z6{{Flu^LdtYJ?zo?uJ?wtE8$}sP-wjoq{4(v0lU~04*wFp)*np@@rMZ0w^qE0TfAv zL0rTF$PKGlfJIti7+0|X3#(WFMO7>YaTN<7L)DxBii%ha;vyD6VG#?UsEEZNE@A-` z7O?<|idX=Rakz>FSXjlv&qDdvrpk)dO}wgNCAo@~^qb$Kf29Asam9Pox8gm~)1Xh8 zFtKl6LjS0N*7m*Bs$1h*oM)?Mnl93u57C;OZx5iNc)ywMHT>t!(x3LSQ+HS*`X&2+8^aIwfw{3SK#9duF}$h-YF&(w#d u?%5MgzH5))uuva2FWp!=p84Ro6WBtl1>A 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