From 2255208ef59fceb2a1efdfa077a15bb291677b66 Mon Sep 17 00:00:00 2001 From: Daniel Manja <daniel.manja@tu-dresden.de> Date: Mon, 29 Aug 2022 16:45:03 +0200 Subject: [PATCH] Add slurm job generator Closes #268 --- .../docs/jobs_and_resources/misc/info.png | Bin 0 -> 6508 bytes .../docs/jobs_and_resources/misc/style.css | 123 ++ .../jobs_and_resources/slurm_generator.md | 1308 +++++++++++++++++ doc.zih.tu-dresden.de/mkdocs.yml | 1 + .../tud_theme/stylesheets/extra.css | 125 ++ 5 files changed, 1557 insertions(+) create mode 100644 doc.zih.tu-dresden.de/docs/jobs_and_resources/misc/info.png create mode 100644 doc.zih.tu-dresden.de/docs/jobs_and_resources/misc/style.css create mode 100644 doc.zih.tu-dresden.de/docs/jobs_and_resources/slurm_generator.md diff --git a/doc.zih.tu-dresden.de/docs/jobs_and_resources/misc/info.png b/doc.zih.tu-dresden.de/docs/jobs_and_resources/misc/info.png new file mode 100644 index 0000000000000000000000000000000000000000..2687f73d78d3ae697fda138e8ba69837f34e55ee GIT binary patch literal 6508 zcmV-y8I$ITP)<h;3K|Lk000e1NJLTq003G5003DC1^@s6zC1Im00004b3#c}2nYxW zd<bNS0000PbVXQnQ*UN;cVTj60B3G*ZDlQUV{&C>ZgXgFbngSdJ^%m!E_6j$bVG7w zVRUJ4ZXi@?ZDjyWZ*CwlH6THCXCN{#GBO}BF*-6iIy5jKK}{e-MN?ErH}mHJ02stc zL_t(|ob6p{d)r8kev4JSDcO=^Cp**6&hG#JVZGh94vY6u#r*(Okvft%mh9=-9Xze3 zlISSD0s$280u*&!kNCHIxOo5U1^j=Je*^tVqCVqG#&JA)Zj8Y=j`W<5;G=uci}~pO zcR>V%pd<eWA;fnc9z1XQv-^bE^N*4b1$qK*dam_=ei$(HJs$@QdVtp2J%&MJ91V=I z@2BTyA^=Z#5JJH7rlXV+N=is6A(e!Z3d&dTm4fnp_)0-ac?9@JgZ<$eO&UCb)pb3Z zwn5vpXxau%)1vD-^nH)6@6dNWy1s|j8paqHZJ>>Y(T3FZNCc$x2wYFXlLT_$`v`&n zzV9RO0|bGOD2fn9A)+t>qVP!5J&!EtM}qxH8f~DpfiW6g*P*U!RAq&-Dp8gd>ZU={ zG-#U!P1~Yr8Vmz#w;rGejX~?9&n9ajSbG&~u7pwwQ55lmfQ{n_X__J(5?}-*{~(@6 zKhijk|5r4cK-OBL>pRqSgS;qk$a5SH2b5)rs;W>`H6JVV*0c-*`ku^<gF@JYV3XiO zDFxqG@cjU3k|0T9J|;-h6vHq8<477G`0#z-tx*W^;b7kk=(&?4U=4%Rqw9J$4LypY zz~OMf;c&n!KdQ1sc?oC+*nSRhdU*>1cV>Hi-$$A<zzlR&RcKo>QC-)e>pNskL+`N< z<wGgy9HzDTw*voWKpSHmm^}mAG!3e{CR0(-u`EjzWr?CF=y_2%)6q0!Hky`A$1q@+ zIY<CFK5v0xkmzRS!&i#GyG2!1h{6bmIL0B*v44F<mZiwD3~8DoiDSg>5g`gAzA6ZO zrF=;F7X+H@Z-ct2(bNrTZ=NI1a~uu@@;pabRjBJ4bwj|{b<LV)f28in8BRw7;2db_ zdE^9V&ai1(1VII#9bp&*h?5veoDisNR+fte7Rv>e3woq!iYO-g4ggY0+-j?FTcG<M zbzP$<3gktB{r(lZ-45H`j*i<M>bgPKwP^V=Zo3Y{z~SAXU8pyYRIE7y&Vi<=VTzGG z;Xx`nIY}v@e1$Lw5rzT6Fhm#xNYVuB)f(&d3iWD*zVF@DgAq_tA_#(8!E<BN(Gk#j zUSR*a$IHtG&(AOT^Z6NnK0o96`PoGj1Dl0m7%-0JDAu+QV7}S8v|+I^@cjAtM#b|y zD5c0@@-aygJU!*8>Kc95^Y_qaNGTD9!R6Tfo$@ZAY2%??$fmVMQI^>6_t>)LZg)Fu zUN(4sdBMxe2Aj<m+wBf*+d{Lmw5H*sWxkQIVO`xcQ-~*MOKFTjKaklP0SMti>tTAG zl#uKse^uTEwALDJ+oEY(v`ve)ZE-jpu-Wdg-EOhnZn4?!u;1^o-|vwZIhv-%Fbou# z%(md4DRUDv3_Ys4!r^d$=Xvg&>bgejHc=h2Y%w!AWPZqY|C+oDXk!f8wnbS`)KHWK zcKcUsH(PABTWt7fW8|_dQ8x|Qz!}J&1+>enFv#OLqVEUPRSoHR(ArEOw=Fs4zQ-^O zXxk2Hnj%Y62o5Jd4QQ<mnzltz6xi+e*zNY%Znt>ZY_ZvFu-R<zve}}lO0+FGysm90 zjpiiMXNvt%jWG~HpznKBbq#Ganx;ij<S2@Q*2+L@_94SCKnMZf_Yo)YyT1RO8cmm3 zQI^>4_jrDOCR@DO;N@k5m(2#7mkpY>ficqt#%k33#6L?;ovU3>+cXfo6;F}_y1vIS z^w0z6T1Erf82O0f7~||5enox?^n9mhA7xolWU(hrwjl4eJG{QWx_G(kx_2!Km>if8 z0-g{M-aMWi?SDsR;b-RPQo8o|-wmQLLg4!@y9Zu}@B4_N5D9Cv&6B)!2l*zThhcEr z=)Ui;e?7Rkc(d8!WwXI{yF;FHxYYM&C-JK?56P62kV?UYcq3fCnquF<C84f~VvHHl zb{)#Hf>Me?PK;0tbP)Im!w^QBlO3eG9%y4m+S0ZSnz}*VG*cM2+p+W8V84H*?RGVf zOW!Zj^WZCmAPC%JbecRJDXrQ8=v~<PUa`B|vZ?@#PGNlIBjCs*j%n8zg%P5N?EPDu z;~O;EpzjBA7-fmFD6!j34sf&C;^k$7L!P@_a^GJMv?o0%Um*xX#F5<=pHyGQ5slY! z3_L;)!&TpDfd)nl>?{YZ5d;CEC`265*4^_YJ5@ljGW<;5XgYedO@p#5@p?F5zu#lG z-C^TQ#}-9V9EEMSFde?~5rzTcI6{)9$K@`79g~0=4TeFZ^RCNFjN|Bv5VcoB2oHTf zAPPeyaYPxxEM-#xD5(&J;hU7|BGB_U4uhspt}OBT`s!@*Zoem+Tvce>#-%aeBd6PC zAq0{*!D6|<-ExV$<r2%gB}Iheh|y}c8S#2J;Bd$xrQ`yGKHJK__3E0x)>@#373^@x zvD@tsMG-vCU(;4SM4FnT@3>^I&w!rS`2cc+P2Hf#3+#4#&RM)*zu%)MO0;czbxy!z zJ2!tU78%y76}~(?;Njr`4-e}zFpM!2vqxJ<>A`3+bA~rYX0}0kuNXs$mKO!0-Jb06 zI08Z-2m&NY;(lD<`$dEw06n^hqiLujvfJ(O{QQFF=V!bga+GC>w(G7o6T<U2m+W&g zUSY9VV7*@9>FEjIzJ0~FZ(q+Gp)m$g6hcbrV*9$TsTwm37yy_neTCs&V^I`PQciJo z5Fm*YESF0R9CQDu(0c^*JgB#6%3&B#Hx2SU$Cfqv<>iH{A$5hWZLhb-LO@Cimx3@r z7z9qEzdk+Ux4-`lzy0=`U8UPpYONtX38M`;>zt}L!V`QR23lX2xYx#@ZCVtv#K_^F zfIyPOxLYpKHVw2M&aRqY(r9Bwve8Ex{fw8F4ad|}*Sm>EO9|ii5e6ZmD4aC<>l6O| z_rKx4|LY&loH-D<DA2ak`ob`z^DrZf))3<QNTh9BjN^#5BVQ$iz}?*v#lr)dwsq_H zQ8oQUqv7`VmUB^7C6%G7nyM!?RjM^7>&?tQT_cVIBj#yM${z=QaM8PKtr57AlZ0S$ z41ThC_!Sw)5t_?%<2b@-<4SW?UAdyN@_ko@Kjn-7XBtgAt+wsZwk_JWLy;GpeXG%S zE#+&6ft(F9jc#&6IPnkWa^!HjjXr&kBi&&9F1P8I*2ST!76RZrb=UXo4;o5G6a}QB zicH9xE4PJbIkVAv7$)vTT_Z1Y;$GAZW#D?MjEoHQZIVNr%^T<bVa9U8cm}XNx=`=z zN5aiAgl8$%u1CX;x2!4@MFHPe<Pd?2JH<1ghe4xdpo^kFo);*ql5({i%wLLCuRD=R zqwSApj<kAO-+Zm7{)FB;rD1QCA3UW}bbaSEx~fX#MZvp60qIHjL2!o2Ina7Q*S4tY z8bv`LV%bD(+fJpPTc<fMYUMEj(yq}SoyK1>9izQUu2q8RyDdAa@7Q!SHOi7SIt)Wd z=@I>Gh<*;V9yHk?=0#LxiKc1Lbsfixx37#?hcjpmuOA>phq5ZMe|^RC%L|euhVT2V zp;H{KwZZSd{|{a^8ypU=sOrj9Mzq$X;kR5TE!L5Px~?PcN>w3=6QVW5J+wJbY@GwG zHD~Jx=(4KOG!6Q$yBIIt<OKM82c~_E<A^*ju-R@A1OZn>223$D0cecD@4x?!KmPaw z+ua^zS#jc?{K%~$qEj(!V!O@~b!t>ejW~{uOzT`OhIf6(EF-39HBCb&@Ieb7XIf&l zyC@25w_8_sD$CNn)}653f^W9i?RF^35?$B1t@pLt?;ovK>tl_kdSl8d0CQ%sj)BI= zL`1SdHco7qx2A^=(h%#>nSS7T9`d4q5O5&x_IrDl&V-n8M4so!^8z`i1iG%9ImnL! zn#|n%%C9Rb>{^XJ<)NsPPhiv0@dr#A{k==#HVbE-2>)3K0gNMqTw%A{BZ}q@W^_>s z#rxCan)2D3*K639IgO@Jcn<VWO^2}o`Y>P^h|#GBCd-T;qan6TM5J+ggi(kniV%m) zbB>~;n0f?78F`*Nejm{WJ^^R|hB@DwnXbcNDP@;2I@=kNb{R+4q7N8gjK+9Fiqu?u z-$#~a$g&JsmST}*h?5v`G%-EnIG#+xIJ&Fg<z<6l^8x_GH7P%2iAOSpl59ellHj@& zehxI*A4}C5W*<Nr{V{xuAn=i8Dc0*19v;?sSg(;Vw>e=_c@ifKvY9fAT5}R<MB5Ns z>a)a*)bcUmq#e-Xg|PC(8N&TiT5I$J{aWq=jJauCYK6$-8P@AHzJ2?KzkU109A;wc zr_9>7JPV>djOd3RU^{&{<OuxRu|Iz#PNTJ%2%B@9E-2)gGjuk3rqM*@(tJsLfJXZP zvMj~JdWHY^_7(s5$A4n6SP*GE%^Z2$aL8uEx1KjvheM9%=jWT!Y=12F$|9=6(I&|l zjN^IQ_=nX@t`|`69v?5XMqMq2Ykd?}b`uA#v;JXLj{_!BjSy36^aIxQeG${crbB=7 z^(R0J_j>#0Pv~{z0t0D=El0VKa?o5patk{t<a%%^=+DI3F6Z=_IR0BJmo@sd{mHeY z-e`3vVyo9KSyMMICMJ!xY=1Fz#xk$jY4%J>K0}W1oUQA7a!xl8$4}pKSzIf|P{E;_ zYjm5i?bAoZLVGeEz}n0Z{}Z&CS9ApW_m*)%qggv<B_V60Kk95o-XQf|M@bqs9Ub?# zoYo{K(=n~{BiDCP1S2Id{n+*&F36EayLugWH`%^DsT4fPEeIbVgXT(mQ9yB{rIZp; z6d}tp^jA{7ZY^}Bb2pe|BBrmP)T~wG1n@J{;msS@{TZ9n^JX6Ywlc4@Q}5t_Fbc6) zWT@{~82Y~!(BP{{dJ;-W_>7a3)PhGi9lzxSXbP94=Rqmy+J2>y@T7z%K4!d!CFuwT zxoK)-X^PeTJ?f^Wjmcj~1W#4)BoTiUw@6E=xS8l2rwgWoyN}p(kVdNy)o9H?JF<>a zxVyW<WB!P`uK#)(?G%!F8Eu=i?cRD5_s(+~ZHd;wbXk0mMr&iBTk4(_q6Q#vI2>FL z%;{u<Q?Y*gluPjunMV3PHm_=q6ZMi4*ykG%b@~C4J4U03X{u?0x~_?<pyY=*M7MD6 z<?}qx&D&6R;j`Dy0klLL<rBp>3PYE8vaKMu23!aMC5abpM^q$9f+&h8c#!fe_P7YN z@B4_tkdiuOf-))*1U{7fc?-dN7cQCQLl2_ED%VT$oqd(<isd!iJhq+hLG8vP^o@b` zJVAsRpA^!Lt%$;K0{VyCJ0Z9S+CS3hD2@>Lq|w5=J<y)x-Vy!F=SF#7`E(UsAeg(2 zi)ErR&`}to_XdcbGJD4JfGfFy=ilu)rhgPgNO){T7)1yIp9wTSG93W3I%lRMNf1X7 zf*^pp@Jroh;d~`2*2*wM5C#-B$;n*JxySZM8coi~cDRE7T^j@O0WHwNDP({+nwbu( z(VqNqcsJQ-YV}H!1a+Dc&|v`O`|vz@bBE*E#vt29k;F*in9PUr;mPkgVVbGr`wCGQ zB93FEY3i;3Z48DhIuVY(X?D)^own^`nsh@p`kZ$MTmV`r$wZJC#uzkB<A#VtVd%!> z%=`MTrG+V_5XTYC&EQswhldB;Etf=|QU2L`D8c}IpIG<H<q{9;2Q+nqL!LwBIq~HB z9=NjK(Ox;W-!TlShMB|(k~E<rMUo(j2p_3_!o3qhK(g(Lje&r0z0h$SBVrTcE9E8> z+@dnBltL88SS%KJSg&0<Yq?w?j$`=#w9I+bA%sBS`$*y#%ey5Wsx|t)hf?(VzVA_2 z^;K&FCLbbshfEyq$Z2zyrbyF-Ox~L{T1o^#=p19$bx2d1+(H^nCd9Tb%$b(&6{RHN zD8h0{<nymjPk4A(W4T-+iDQ@ln6J~?XzI^SaJO8dYdd$Pb$ySjsxE5RugK9XJ!O3X zYjhGLO{n^lB*_#{zs+<gXF_xkpznKU?87KT=#xeR6Ue8r?XL=%j+j~gYkd9sg!}t@ zESF2fKQJBR2>5~TOouTegz(UH1oGi<fRxwGemM#um4Y7xWSgx<rwOu*>Y8?E_*2^M zy#0*Y$wtJpYIK^UNYj+aB3+BtdiN_m`%(13VVa#s*Yo%w??PBPjw9;2acq1kB}Xfi zd-&dV_*d7aW}CP$43VW=I8Jy*Q$%KU-YoRf9+tBgaJq7_$gp0okQYx7o`<q5P!uH! zz*WlMD}C3aC`xR%TjyvK=5<7IH0zu_mT?5?x^k`26;C1i<Bva?i&tG8bx3#q3oI5H z7TE$%U!SmAt&n9Iq9}r#MMdBHVZVD_**CZ^%E*2;O$*Nx*zM?YwsSA8k*@Dilm#|h z1v8Fl+6G||POPQSzgXcON4OS{wrkO~9rdd3_SnDfQC8)<bJ_0vJ#VIHYpho*JUu;P zy;@<h$Pk913weL7l!eonQE``4hIO-s)`oY7({PbXJGWnvz9)?y&4`AHFsG9ZY$S0k zBZk=!LR;XS4=a36NALXnJt?Oyu@(7`$Hy;|Ml%6@{+>5w@9c}LSC?wKbhOqGZ1;Nh z>aRSL=o;y`DYR)CyfVmc#2QlyzLz<4%q2&z8E1r+!3`#Sk62$7^7*gVD+2n<7u?+~ zvB)w+QFykAyCgq19iE3Upn0Fh7<kfyG1@iB91aK9raNWJrg?R55j$t2ZQEaf;r22Q z<!m-FO%p7$1@7*au4Q_?ULj2=67z%LqN6^QpT<6J6B7oAHBDb>+YYPy`-!C9b%>*g zA`xpdxe4-LNj%R(6om-G2vJClrK{BnkB?vQuwLWt{tk;p#@p@iyD{@6c@xk|DTF}) zI}&&ph9i*mpb>@vMIl8Apt#8tn$H&Lc?iP@i!8%pLG0Ft^%{?lk9b(GaesG*MYcei zB<!d!r$jHw+klo5;MmrNUk+sMYoS7}&kc_qJW<`^+&@jI`Y#cM<oH*s71nDq6;F>} zuwJimKhtQX$VuN8Xr<tBa(x^}K!A90+;buXmA?QuCn>IUke?~@+;$j-$THjT|KzmU zY4jpP6vapP3b+~2LI`5o@YXWc8d;X2?>pBm3IN(@3_Uf`v`mDVhIAj7l`gd$f25p_ zc(4%#jjpF-nx<H-?n#rsJmB&15swcKxWB){a=Ac~CI~}H?*FR1D-qy%9%s!G7e3jZ z5<BfS2m&`arD=&v*EX%||9i{$v|GwNz2GsOA_}Lu|29^BdVIvw)1%YmyZbwemtz{! z_Ld0alDr>ip2-a0D6b%G(K3qgdN`oSX~eOexzzWxT^B-p$^clvf_yv(HV6V_i;NxL z0*fre-TmDxP5a<7h;bAlj;N{hy}6Tj1MLR^5^yfrhB|5jIY|;^JhIKskn6f0Y~pD; z%ndSsZxtb?R3~Y3h($*E8#_mOwOZl+{tm1Ad)(jO<Np2*X_8X<lM5d2-JD%zI((%N z@g~I<1#DG#vB)TwtQ5c?mu2a+*o-4QA@DgmZEdp06fPfOL{4wDqTQa$f%BB~1y4z* ztlaV3|M$qdfVPh0^zY0#LWpUaxYgFVEw-aH?ZeJwnqFt9;T~^yn3gvUKH4;a<xYD% zc-s|z18U`XdV0ju<0Bp)zu=KWINL8n#g61%j_;D(Y$CcXu!dns8x^*}<2XXj68p9j zx8Z3CP18`C)%MEp`1#|}^V6M$PW8#=LG01e50q5Q93slr(Y;x?a!qDqh4p%kySqCA zm#<7I)w><vCAk^UZU-5Lbbl0HDB18B%f$lg)rux2*gIM9v2DBQu0pKot|{mTcNP+W zn^JB=H0$VsAaHjT3d4|ZroerROruyVCP!#DBKCcBtB}7S&~|9+oP^^Cz5}`8y9Sk2 z#lyR+qaohS>`^xjX*L%WhVK*>gaGrCNpoqYk$+Syh-M`xYZ4|3*A&`CQG}33^hi$6 z-V$hWs~bn2joX>E(aj%aMI({zoh|a5MhVf#ipt&mrthZ~>Ej#T94()@$-cYkP2l?u zNLy}7)6|7>8EbDG$7e$g?fm{<+3~$qZfZJC7j_AJ8wNVA91rTN>I!L9p-NLq*xNh9 z4b!ch+;>f1dUPiWr6>fmT)3&$Ni#*$G^Ijnnz|aFd*H{-KG({J-z)2M@z#dMF_{9p z`H6VQs&$a_dC>C&{;5VQzLg$nrE+mSnS{wKSW_}5Av%CBtn=3Lp+KLKT>wyS+ozN( zWdkW9umcONQ`CHmJ!7;Z>l}SHALqC2n8=cWV^jscPZWWfgOs+$M+^H%2%LP%9XjXQ zLMd0`)A_!_5JhKpe12!4(TqPF`({gBQ`zg}#*zGR4pT{2<C~kHkCsn09djO=@9Z{U z$5$NxnT`OCo?rNe8BY9M*cQII?>PSRN1KXM`4o+w%Rl2J{|fT2lb!z;m;VLVb}?ul SkPzPh0000<MNUMnLSTZL?S7^J literal 0 HcmV?d00001 diff --git a/doc.zih.tu-dresden.de/docs/jobs_and_resources/misc/style.css b/doc.zih.tu-dresden.de/docs/jobs_and_resources/misc/style.css new file mode 100644 index 000000000..61b585e79 --- /dev/null +++ b/doc.zih.tu-dresden.de/docs/jobs_and_resources/misc/style.css @@ -0,0 +1,123 @@ +/* universal style */ +body { + margin: auto; + width: 90%; +} +img { + display: block; +} +pre { + background-color: lightgrey; + border-color: black; + border-width: 1pt; +} +.header { + background-color: #002557; +} +label.header { + color: white; + font-size: 40px; + margin: 15px; +} +.hidden { + display: none !important; +} +.info-img { + height: 20px; + width: 20px; +} +.info-pre { + display: flex; + padding: 5px; +} +.limits { + color: red; + display: none; + margin-left: 10px; +} +button.output { + padding: 8px; + background-color: rgba(231, 231, 231, 0.726); + border-color: rgba(124, 119, 119, 0.541); + border-radius: .25rem; +} +button.output:hover, button.output:focus { + background-color: #ddd; +} +div.output { + margin: 15px 0px; +} + +/* tablelike layout */ +.input { + display: block; + width: 70%; +} +.row { + align-items: center; + display: flex; + width: 100%; +} +.cell-name { + display: flex; + height: 25px; + justify-content: center; + align-items: center; + width: 125px; +} +.cell-tooltip { + align-items: center; + display: flex; + height: 25px; + justify-content: center; + width: 25px; +} +.cell-input { + display: flexbox; + vertical-align: middle; +} +.partition-input { + float: left; + width: 650px; +} +.partition-info { + display: flex; + float: left; + width: calc(30%); +} + +/* collapsible */ +.active { + background-color: #5a7094 !important; +} +.active:after { + content: "-" !important; +} +.collapsible { + background-color: #274275; + border: none; + color: #fff; + cursor: pointer; + font-size: 20px; + outline: none; + padding: 18px; + text-align: left; + width: 100%; +} +.collapsible:hover, .collapsible:focus { + text-decoration: underline; +} +.collapsible:after { + color: #fff; + content: '+'; + float: right; + font-size: 20px; + font-weight:900; + margin-left: 5px; +} +.content { + background-color: #f1f1f1; + display: block; + overflow: hidden; + padding: 0 18px; +} \ No newline at end of file diff --git a/doc.zih.tu-dresden.de/docs/jobs_and_resources/slurm_generator.md b/doc.zih.tu-dresden.de/docs/jobs_and_resources/slurm_generator.md new file mode 100644 index 000000000..dd03478d4 --- /dev/null +++ b/doc.zih.tu-dresden.de/docs/jobs_and_resources/slurm_generator.md @@ -0,0 +1,1308 @@ +# Slurm Job Generator + +<!DOCTYPE html> +<html lang="en-us"> + <head> + <meta charset="utf-8"> + <!-- <meta name="viewport" content="width=device-width, initial-scale=1.0"> --> + <title>Slurm-Job-Generator</title> + <!-- <link type="text/css" href="../misc/style.css" rel="stylesheet"> --> + <!-- <script src="jquery-3.6.0.min.js"> </script> --> + </head> + + <body> + <div class="header"> + <label class="header">TU Dresden Slurm Job Generator</label> + </div> + <button type="button" class="collapsible">General</button> + <div class="content"> + <div class="input"> + <div class="row"> + <label class="cell-name">Job name</label> + <div class="cell-tooltip"> + <img class="info-img" src="../misc/info.png" title="help"> + </div> + <input id="job-name" class="cell-input" type="text"> + </div> + <div class="row"> + <label class="cell-name">Account</label> + <div class="cell-tooltip"> + <img class="info-img" src="../misc/info.png" title="help"> + </div> + <input id="account" class="cell-input" type="text"> + </div> + <div class="row"> + <label class="cell-name">Email</label> + <div class="cell-tooltip"> + <img class="info-img" src="../misc/info.png" title="help"> + </div> + <div class="cell-input"> + <input id="mail" type="mail"> + + <input id="begin" type="checkbox"> + <lable for="begin">Begin</lable> + <input id="end" type="checkbox"> + <lable for="end">End</lable> + <input id="fail" type="checkbox"> + <lable for="fail">Fail</lable> + </div> + </div> + </div> + </div> + + <button type="button" class="collapsible">Resources</button> + <div class="content"> + <div class="partition-input"> + <div class="row"> + <label class="cell-name">Time limit</label> + <div class="cell-tooltip"> + <img class="info-img" src="../misc/info.png" title="days-hours:minutes:seconds"> + </div> + <input id="time" class="cell-input" type="text" placeholder="00-00:00:00"> + <label id="time-text" class="limits cell-input"></label> + </div> + <div class="row"> + <label class="cell-name">Partition</label> + <div class="cell-tooltip"> + <img class="info-img" src="../misc/info.png" title="help"> + </div> + <select id="partition" class="cell-input"></select> + </div> + <div class="row"> + <label class="cell-name">Nodes</label> + <div class="cell-tooltip"> + <img class="info-img" src="../misc/info.png" title="help"> + </div> + <input id="nodes" class="cell-input" type="number" min="1"> + <label id="nodes-text" class="limits cell-input"></label> + </div> + <div class="row"> + <label class="cell-name">Tasks</label> + <div class="cell-tooltip"> + <img class="info-img" src="../misc/info.png" title="help"> + </div> + <input id="tasks" class="cell-input" type="number" min="1"> + <label id="tasks-text" class="limits cell-input"></label> + </div> + <div class="row"> + <label class="cell-name">Tasks/node</label> + <div class="cell-tooltip"> + <img class="info-img" src="../misc/info.png" title="help"> + </div> + <input id="tasks/node" class="cell-input" type="number" min="1"> + <label id="tasks/node-text" class="limits cell-input"></label> + </div> + <div class="row"> + <label class="cell-name">CPUs/task</label> + <div class="cell-tooltip"> + <img class="info-img" src="../misc/info.png" title="help"> + </div> + <input id="cpus" class="cell-input" type="number" min="1"> + <label id="cpus-text" class="limits cell-input"></label> + </div> + <div id="div-thread" class="row"> + <span class="cell-name"></span> + <div class="cell-tooltip"> + <img class="info-img" src="../misc/info.png" title="help"> + </div> + <div class="cell-input"> + <input id="nomultithread" class="cell" type="checkbox"> + <lable for="nomultithread">No Multithreading</lable> + </div> + </div> + <div id="div-gpu" class="row"> + <label class="cell-name">GPUs/node</label> + <div class="cell-tooltip"> + <img class="info-img" src="../misc/info.png" title="help"> + </div> + <input id="gpus" class="cell-input" type="number" min="1"> + <label id="gpus-text" class="limits cell-input"></label> + </div> + <div id="div-gpu/task" class="row"> + <label class="cell-name">GPUs/task</label> + <div class="cell-tooltip"> + <img class="info-img" src="../misc/info.png" title="help"> + </div> + <input id="gpus/task" class="cell-input" type="number" min="1"> + <label id="gpus/task-text" class="limits cell-input"></label> + </div> + <div class="row"> + <label class="cell-name">RAM/CPU</label> + <div class="cell-tooltip"> + <img class="info-img" src="../misc/info.png" title="help"> + </div> + <div class="cell-input"> + <input id="mem" type="number" min="1"> + <select id="byte"> + <option value="M" title="placeholder" selected="selected">MiB</option> + <option value="G" title="placeholder">GiB</option> + </select> + <label id="mem-text" class="limits"></label> + </div> + </div> + <div class="row"> + <span class="cell-name"></span> + <div class="cell-tooltip"> + <img class="info-img" src="../misc/info.png" title="help"> + </div> + <div class="cell-input"> + <input id="exclusive" type="checkbox"> + <lable for="exclusive">Exclusive</lable> + </div> + </div> + </div> + <div class="partition-info"> + <pre id="info-panel" class="info-pre"></pre> + </div> + </div> + + <button type="button" class="collapsible">Files</button> + <div class="content"> + <div class="input"> + <div class="row"> + <label class="cell-name">Executable</label> + <div class="cell-tooltip"> + <img class="info-img" src="../misc/info.png" title="help"> + </div> + <input id="executable" class="cell-input" type="text"> + </div> + <div class="row"> + <span class="cell-name"></span> + <div class="cell-tooltip"> + <img class="info-img" src="../misc/info.png" title="help"> + </div> + <div class="cell-input"> + <input id="one-output" type="checkbox"> + <lable for="one-output">just one output file</lable> + </div> + </div> + <div class="row"> + <label class="cell-name">Output file</label> + <div class="cell-tooltip"> + <img class="info-img" src="../misc/info.png" title="help"> + </div> + <input id="output-file" class="cell-input" type="text"> + </div> + <div id="err-div" class="row"> + <label class="cell-name">Error file</label> + <div class="cell-tooltip"> + <img class="info-img" src="../misc/info.png" title="help"> + </div> + <input id="error-file" class="cell-input" type="text"> + </div> + </div> + </div> + + <button type="button" class="collapsible">Advanced</button> + <div class="content"> + <div class="input"> + <div class="row"> + <label class="cell-name">Array</label> + <div class="cell-tooltip"> + <img class="info-img" src="../misc/info.png" title="help"> + </div> + <input id="array" class="cell-input" type="text" placeholder="1-5"> + </div> + <div class="row"> + <label class="cell-name">Dependency</label> + <div class="cell-tooltip"> + <img class="info-img" src="../misc/info.png" title="help"> + </div> + <div class="cell-input"> + <select id="type-depend"> + <option value="none" title="placeholder" selected="selected"></option> + <option value="after" title="placeholder">after</option> + <option value="afterany" title="placeholder">afterany</option> + <option value="afterburstbuffer" title="placeholder">afterburstbuffer</option> + <option value="aftercorr" title="placeholder">aftercorr</option> + <option value="afternotok" title="placeholder">afternotok</option> + <option value="afterok" title="placeholder">afterok</option> + <option value="singleton" title="placeholder">singleton</option> + </select> + <input id="jobid" class="hidden" type="text" placeholder="jobid"> + </div> + </div> + </div> + </div> + + <button type="button" class="collapsible">Workspace</button> + <div class="content"> + <div class="input"> + <div class="row"> + <span class="cell-name"></span> + <div class="cell-tooltip"> + <img class="info-img" src="../misc/info.png" title="help"> + </div> + <div class="cell-input"> + <input id="check-workspace" type="checkbox"> + <label for="check-workspace">Allocate a workspace</label> + </div> + </div> + <div class="row hidden"> + <label class="cell-name">Filesystem</label> + <div class="cell-tooltip"> + <img class="info-img" src="../misc/info.png" title="help"> + </div> + <select id="workspace-filesystem" class="cell-input"></select> + </div> + <div class="row hidden"> + <label class="cell-name">Name</label> + <div class="cell-tooltip"> + <img class="info-img" src="../misc/info.png" title="help"> + </div> + <input id="name" class="cell-input" type="text"> + </div> + <div class="row hidden"> + <label class="cell-name">Duration</label> + <div class="cell-tooltip"> + <img class="info-img" src="../misc/info.png" title="help"> + </div> + <div class="cell-input"> + <input id="duration" type="number" min="1"> + <label id="duration-text" class="limits"></label> + </div> + </div> + <div class="row hidden"> + <span class="cell-name"></span> + <div class="cell-tooltip"> + <img class="info-img" src="../misc/info.png" title="help"> + </div> + <div class="cell-input"> + <input id="check-delete" type="checkbox"> + <label for="check-delete">Delete after job</label> + </div> + </div> + </div> + </div> + + <div class="output"> + <button id="generate-button" class="output" type="button">Generate</button> + <div class="code"> + <label id="output-text" class="limits">Output requieres update</label> + <pre id="output"></pre> + </div> + <button id="copy-button" class="output" type="button">Copy to Clipboard</button> + <button id="save-button" class="output" type="button">Save as File</button> + </div> + + <script> + // dictionary containing the limits for the different partitions + const limits = { + 'gpu2' : gpu2 = { + 'MaxTime' : 'INFINITE', + 'DefaultTime' : 480, + 'info' : 'help', + 'Sockets' : 2, + 'cpu/socket' : 12, + 'threads' : 1, + 'nodes' : 59, + 'cores/node' : 24, + 'ht_cores/node' : 24, + 'mem/core' : 2583, + 'mem/node' : 62000, + 'gpu/node' : 4 + }, + 'gpu2-interactive' : gpu2_interactive = { + 'MaxTime' : 480, + 'DefaultTime' : 10, + 'info' : 'help', + 'Sockets' : 2, + 'cpu/socket' : 12, + 'threads' : 1, + 'nodes' : 59, + 'cores/node' : 24, + 'ht_cores/node' : 24, + 'mem/core' : 2583, + 'mem/node' : 62000, + 'gpu/node' : 4 + }, + 'haswell' : haswell = { + 'MaxTime' : 'INFINITE', + 'DefaultTime' : 480, + 'info' : 'help', + 'Sockets' : 2, + 'cpu/socket' : 12, + 'threads' : 1, + 'nodes' : 1435, + 'cores/node' : 24, + 'ht_cores/node' : 24, + 'mem/core' : 2541, + 'mem/node' : 61000, + 'gpu/node' : 0 + }, + 'haswell64' : haswell64 = { + 'MaxTime' : 'INFINITE', + 'DefaultTime' : 480, + 'info' : 'help', + 'Sockets' : 2, + 'cpu/socket' : 12, + 'threads' : 1, + 'nodes' : 1284, + 'cores/node' : 24, + 'ht_cores/node' : 24, + 'mem/core' : 2541, + 'mem/node' : 61000, + 'gpu/node' : 0 + }, + 'haswell128' : haswell128 = { + 'MaxTime' : 'INFINITE', + 'DefaultTime' : 480, + 'info' : 'help', + 'Sockets' : 2, + 'cpu/socket' : 12, + 'threads' : 1, + 'nodes' : 84, + 'cores/node' : 24, + 'ht_cores/node' : 24, + 'mem/core' : 5250, + 'mem/node' : 126000, + 'gpu/node' : 0 + }, + 'haswell256' : haswell256 = { + 'MaxTime' : 'INFINITE', + 'DefaultTime' : 480, + 'info' : 'help', + 'Sockets' : 2, + 'cpu/socket' : 12, + 'threads' : 1, + 'nodes' : 44, + 'cores/node' : 24, + 'ht_cores/node' : 24, + 'mem/core' : 10583, + 'mem/node' : 254000, + 'gpu/node' : 0 + }, + 'haswell64long' : haswell64long = { + 'MaxTime' : 'INFINITE', + 'DefaultTime' : 480, + 'info' : 'help', + 'Sockets' : 2, + 'cpu/socket' : 12, + 'threads' : 1, + 'nodes' : 878, + 'cores/node' : 24, + 'ht_cores/node' : 24, + 'mem/core' : 2541, + 'mem/node' : 61000, + 'gpu/node' : 0 + }, + 'haswell64extralong' : haswell64extralong = { + 'MaxTime' : 'INFINITE', + 'DefaultTime' : 480, + 'info' : 'help', + 'Sockets' : 2, + 'cpu/socket' : 12, + 'threads' : 1, + 'nodes' : 698, + 'cores/node' : 24, + 'ht_cores/node' : 24, + 'mem/core' : 2541, + 'mem/node' : 61000, + 'gpu/node' : 0 + }, + 'haswell64ht' : haswell64ht = { + 'MaxTime' : 'INFINITE', + 'DefaultTime' : 480, + 'info' : 'help', + 'Sockets' : 2, + 'cpu/socket' : 12, + 'threads' : 2, + 'nodes' : 18, + 'cores/node' : 24, + 'ht_cores/node' : 48, + 'mem/core' : 1270, + 'mem/node' : 61000, + 'gpu/node' : 0 + }, + 'interactive' : interactive = { + 'MaxTime' : 480, + 'DefaultTime' : 30, + 'info' : 'help', + 'Sockets' : 2, + 'cpu/socket' : 12, + 'threads' : 1, + 'nodes' : 8, + 'cores/node' : 24, + 'ht_cores/node' : 24, + 'mem/core' : 2541, + 'mem/node' : 61000, + 'gpu/node' : 0 + }, + 'smp2' : smp2 = { + 'MaxTime' : 'INFINITE', + 'DefaultTime' : 480, + 'info' : 'help', + 'Sockets' : 4, + 'cpu/socket' : 14, + 'threads' : 1, + 'nodes' : 5, + 'cores/node' : 56, + 'ht_cores/node' : 56, + 'mem/core' : 36500, + 'mem/node' : 2044000, + 'gpu/node' : 0 + }, + 'broadwell' : broadwell = { + 'MaxTime' : 'INFINITE', + 'DefaultTime' : 480, + 'info' : 'help', + 'Sockets' : 2, + 'cpu/socket' : 14, + 'threads' : 1, + 'nodes' : 32, + 'cores/node' : 28, + 'ht_cores/node' : 28, + 'mem/core' : 2214, + 'mem/node' : 62000, + 'gpu/node' : 0 + }, + 'ifm' : ifm = { + 'MaxTime' : 'INFINITE', + 'DefaultTime' : 60, + 'info' : 'help', + 'Sockets' : 2, + 'cpu/socket' : 8, + 'threads' : 2, + 'nodes' : 1, + 'cores/node' : 16, + 'ht_cores/node' : 32, + 'mem/core' : 12000, + 'mem/node' : 384000, + 'gpu/node' : 1 + }, + 'hpdlf' : hpdlf = { + 'MaxTime' : 'INFINITE', + 'DefaultTime' : 60, + 'info' : 'help', + 'Sockets' : 2, + 'cpu/socket' : 6, + 'threads' : 1, + 'nodes' : 14, + 'cores/node' : 12, + 'ht_cores/node' : 12, + 'mem/core' : 7916, + 'mem/node' : 95000, + 'gpu/node' : 3 + }, + 'ml-all' : ml_all = { + 'MaxTime' : 'INFINITE', + 'DefaultTime' : 60, + 'info' : 'help', + 'Sockets' : 2, + 'cpu/socket' : 22, + 'threads' : 4, + 'nodes' : 32, + 'cores/node' : 44, + 'ht_cores/node' : 176, + 'mem/core' : 1443, + 'mem/node' : 254000, + 'gpu/node' : 6 + }, + 'ml' : ml = { + 'MaxTime' : 'INFINITE', + 'DefaultTime' : 60, + 'info' : 'help', + 'Sockets' : 2, + 'cpu/socket' : 22, + 'threads' : 4, + 'nodes' : 30, + 'cores/node' : 44, + 'ht_cores/node' : 176, + 'mem/core' : 1443, + 'mem/node' : 254000, + 'gpu/node' : 6 + }, + 'ml-interactive' : ml_interactive = { + 'MaxTime' : 480, + 'DefaultTime' : 10, + 'info' : 'help', + 'Sockets' : 2, + 'cpu/socket' : 22, + 'threads' : 4, + 'nodes' : 2, + 'cores/node' : 44, + 'ht_cores/node' : 176, + 'mem/core' : 1443, + 'mem/node' : 254000, + 'gpu/node' : 6 + }, + 'nvme' : nvme = { + 'MaxTime' : 'INFINITE', + 'DefaultTime' : 60, + 'info' : 'help', + 'Sockets' : 2, + 'cpu/socket' : 8, + 'threads' : 2, + 'nodes' : 90, + 'cores/node' : 16, + 'ht_cores/node' : 32, + 'mem/core' : 1875, + 'mem/node' : 60000, + 'gpu/node' : 0 + }, + 'datamover' : datamover = { + 'info' : 'help', + 'Sockets' : 2, + 'cpu/socket' : 8, + 'threads' : 1, + 'nodes' : 2, + 'cores/node' : 16, + 'ht_cores/node' : 16, + 'mem/core' : 3875, + 'mem/node' : 62000, + 'gpu/node' : 0 + }, + 'romeo' : romeo = { + 'MaxTime' : 'INFINITE', + 'DefaultTime' : 480, + 'info' : 'help', + 'Sockets' : 2, + 'cpu/socket' : 64, + 'threads' : 2, + 'nodes' : 190, + 'cores/node' : 128, + 'ht_cores/node' : 256, + 'mem/core' : 1972, + 'mem/node' : 505000, + 'gpu/node' : 0 + }, + 'romeo-interactive' : romeo_interactive = { + 'MaxTime' : 480, + 'DefaultTime' : 10, + 'info' : 'help', + 'Sockets' : 2, + 'cpu/socket' : 64, + 'threads' : 2, + 'nodes' : 2, + 'cores/node' : 128, + 'ht_cores/node' : 256, + 'mem/core' : 1972, + 'mem/node' : 505000, + 'gpu/node' : 0 + }, + 'julia' : julia = { + 'MaxTime' : 'INFINITE', + 'DefaultTime' : 480, + 'info' : 'help', + 'Sockets' : 32, + 'cpu/socket' : 28, + 'threads' : 1, + 'nodes' : 1, + 'cores/node' : 896, + 'ht_cores/node' : 896, + 'mem/core' : 54006, + 'mem/node' : 48390000, + 'gpu/node' : 0 + }, + 'alpha' : alpha = { + 'MaxTime' : 'INFINITE', + 'DefaultTime' : 480, + 'info' : 'help', + 'Sockets' : 2, + 'cpu/socket' : 24, + 'threads' : 2, + 'nodes' : 32, + 'cores/node' : 48, + 'ht_cores/node' : 96, + 'mem/core' : 10312, + 'mem/node' : 990000, + 'gpu/node' : 8 + }, + 'alpha-interactive' : alpha_interactive = { + 'MaxTime' : 'INFINITE', + 'DefaultTime' : 480, + 'info' : 'help', + 'Sockets' : 2, + 'cpu/socket' : 24, + 'threads' : 2, + 'nodes' : 2, + 'cores/node' : 48, + 'ht_cores/node' : 96, + 'mem/core' : 10312, + 'mem/node' : 990000, + 'gpu/node' : 8 + }, + 'htw-gpu' : htw_gpu = { + 'MaxTime' : 'INFINITE', + 'DefaultTime' : 480, + 'info' : 'help', + 'Sockets' : 2, + 'cpu/socket' : 24, + 'threads' : 2, + 'nodes' : 5, + 'cores/node' : 48, + 'ht_cores/node' : 96, + 'mem/core' : 10312, + 'mem/node' : 990000, + 'gpu/node' : 8 + }, + 'beaker-interactive' : beaker_interactive = { + 'MaxTime' : 480, + 'DefaultTime' : 10, + 'info' : 'help', + 'Sockets' : 2, + 'cpu/socket' : 16, + 'threads' : 2, + 'nodes' : 2, + 'cores/node' : 32, + 'ht_cores/node' : 64, + 'mem/core' : 7890, + 'mem/node' : 505000, + 'gpu/node' : 0 + }, + 'beaker' : beaker = { + 'MaxTime' : 'INFINITE', + 'DefaultTime' : 480, + 'info' : 'help', + 'Sockets' : 2, + 'cpu/socket' : 16, + 'threads' : 2, + 'nodes' : 114, + 'cores/node' : 32, + 'ht_cores/node' : 64, + 'mem/core' : 7890, + 'mem/node' : 505000, + 'gpu/node' : 0 + } + }; + + // dictionary containing the limits for the different workspaces + const limitsWorkspace = { + 'scratch' : scratch = { + 'info' : 'help', + 'duration' : 100, + 'extensions' : 10 + }, + 'warm_archive' : warm_archive = { + 'info' : 'help', + 'duration' : 365, + 'extensions' : 2 + }, + 'ssd' : ssd = { + 'info' : 'help', + 'duration' : 30, + 'extensions' : 2 + }, + 'beegfs_global0' : beegfs_global0 = { + 'info' : 'help', + 'duration' : 30, + 'extensions' : 2 + }, + 'beegfs' : beegfs = { + 'info' : 'help', + 'duration' : 30, + 'extensions' : 2 + } + }; + + // dictionary for the min and max values + var maxValues = { + 'nodes' : 0, + 'tasks' : 0, + 'tasks/node' : 0, + 'cpus' : 0, + 'gpus' : 0, + 'gpus/task' : 0, + 'mem' : 0, + 'duration': 0 + } + + /** + * Function to generate the output text + */ + var generateOutput = function() { + let outputText = document.getElementById('output') + outputText.innerText = '#!/bin/bash\n'; + if (document.getElementById('job-name').value !== '') { + outputText.innerText += '\n#SBATCH --job-name=\"' + + document.getElementById('job-name').value + '\"'; + } + if (document.getElementById('array').value !== '') { + outputText.innerText += '\n#SBATCH --array=' + + document.getElementById('array').value; + } + outputText.innerText += '\n#SBATCH --time=' + + document.getElementById('time').value; + + limits[document.getElementById('partition').value]['DefaultTime'] + outputText.innerText += '\n#SBATCH --partition=' + + document.getElementById('partition').value; + if (document.getElementById('nodes').value !== '') { + outputText.innerText += '\n#SBATCH --nodes=' + document.getElementById('nodes').value; + } + if (document.getElementById('tasks').value !== '') { + outputText.innerText += '\n#SBATCH --ntasks=' + + document.getElementById('tasks').value; + } + if (document.getElementById('tasks/node').value !== '' && document.getElementById('gpus').value !== '') { + outputText.innerText += '\n#SBATCH --ntasks-per-node=' + + document.getElementById('tasks/node').value; + } else if (document.getElementById('tasks/node').value !== '') { + outputText.innerText += '\n#SBATCH --mincpus=' + + document.getElementById('tasks/node').value; + } + if (document.getElementById('cpus').value !== '') { + outputText.innerText += '\n#SBATCH --cpus-per-task=' + + document.getElementById('cpus').value; + } + if (document.getElementById('gpus').value !== '') { + outputText.innerText += '\n#SBATCH --gres=gpu:' + + document.getElementById('gpus').value; + } + if (document.getElementById('gpus/task').value !== '') { + outputText.innerText += '\n#SBATCH --gpus-per-task=' + + document.getElementById('gpus/task').value; + } + if (document.getElementById('mem').value !== '') { + outputText.innerText += '\n#SBATCH --mem-per-cpu=' + + document.getElementById('mem').value + + document.getElementById('byte').value; + } + if (document.getElementById('account').value !== '') { + outputText.innerText += '\n#SBATCH --account=\"' + + document.getElementById('account').value + '\"'; + } + if (document.getElementById('mail').value !== '') { + outputText.innerText += '\n#SBATCH --mail-user=' + + document.getElementById('mail').value; + if (document.getElementById('begin').checked === true) { + outputText.innerText += '\n#SBATCH --mail-type=BEGIN'; + } + if (document.getElementById('end').checked === true) { + outputText.innerText += '\n#SBATCH --mail-type=END'; + } + if (document.getElementById('fail').checked === true) { + outputText.innerText += '\n#SBATCH --mail-type=FAIL'; + } + } + if (document.getElementById('output-file').value !== '') { + outputText.innerText += '\n#SBATCH --output=' + + document.getElementById('output-file').value; + } + if (document.getElementById('error-file').value !== '') { + outputText.innerText += '\n#SBATCH --error=' + + document.getElementById('error-file').value; + } + if (document.getElementById('exclusive').checked === true) { + outputText.innerText += '\n#SBATCH --exclusive'; + } + if (document.getElementById('nomultithread').checked === true) { + outputText.innerText += '\n#SBATCH --hint=nomultithread'; + } + if (document.getElementById('type-depend').value !== 'none') { + outputText.innerText += '\n#SBATCH --dependency=' + + document.getElementById('type-depend').value + if (document.getElementById('type-depend').value !== 'singleton') { + outputText.innerText += ':' + document.getElementById('jobid').value + } + } + + outputText.innerText += '\n\n# Setup computational environment, i.e, load desired modules'; + outputText.innerText += '\n# module purge'; + outputText.innerText += '\n# module load <module name>'; + outputText.innerText += '\n\n'; + + if (document.getElementById('check-workspace').checked) { + outputText.innerText += '\n# Allocate workspace as working directory'; + outputText.innerText += '\nWSNAME=' + + document.getElementById('name').value + '_$SLURM_JOB_ID'; + outputText.innerText += '\nexport WSDIR=$(ws_allocate -F ' + + document.getElementById('workspace-filesystem').value + + ' -n $WSNAME -d ' + + document.getElementById('duration').value + + ')'; + outputText.innerText += '\necho "Workspace: $WSDIR"'; + + outputText.innerText += '\n# Check allocation'; + outputText.innerText += '\n[ -z "$WSDIR" ] && echo "Error: Cannot allocate workspace $WSNAME" && exit 1'; + + outputText.innerText += '\n\n# Change to workspace'; + outputText.innerText += '\ncd $WSDIR'; + } + + if (document.getElementById('executable').value !== '') { + outputText.innerText += '\n\n# Execute parallel application ' + outputText.innerText += '\nsrun ' + + document.getElementById('executable').value; + } + + if (document.getElementById('check-workspace').checked && document.getElementById('check-delete').checked) { + outputText.innerText += '\n\n# Save your results!' + outputText.innerText += '\n# cp <results> <dest>' + outputText.innerText += '\n\n# Clean up workspace' + outputText.innerText += '\nif [ -d $WORK_SCRDIR ] && rm -rf $WSDIR/*'; + outputText.innerText += '\nws_release -F ' + + document.getElementById('workspace-filesystem').value + + ' $WSDIR'; + } + } + + /** + * Proof if all values are correct, if yes it prints the output, else it highlights incorrect values + */ + var proofValues = function() { + let boolValues = true; + // proof values and set/unset warnings + // walltime + let reArray = /^(([0-9]{1,3})-)?([0-9]{2}):[0-9]{2}:[0-9]{2}$/; + if (!reArray.test(document.getElementById('time').value) && document.getElementById('time').value) { + document.getElementById('time').style.backgroundColor = 'red'; + boolValues = false; + } else { + document.getElementById('time').style.backgroundColor = ''; + } + // proof multiple fields + const fields = ['nodes', 'tasks', 'tasks/node', 'cpus', 'gpus', 'gpus/task', 'mem']; + if (document.getElementById('check-workspace').checked === true) { + fields.push('duration'); + } + [].forEach.call(fields, function(field) { + let element = document.getElementById(field); + let elementText = document.getElementById(field + '-text'); + let value = Number(document.getElementById(field).value); + let min = Number(document.getElementById(field).min); + let max = Number(maxValues[field]); + if (value >= min && value <= max || document.getElementById(field).value === '') { + element.style.backgroundColor = ''; + elementText.style.display = 'none'; + } else { + boolValues = false; + element.style.backgroundColor = 'rgb(255, 121, 121)'; + elementText.style.display = 'inline'; + } + }) + + if (boolValues === true) { + document.getElementById('output-text').style.display = 'none'; + generateOutput(); + } else { + document.getElementById('output-text').style.display = 'block'; + } + } + + // copy to clipboard + document.getElementById('copy-button').addEventListener('click', function () { + let code = document.getElementById('output'); + + // select the text + let range = document.createRange(); + range.selectNodeContents(code); + let selection = window.getSelection(); + selection.removeAllRanges(); + selection.addRange(range); + + // copy to clipboard + navigator.clipboard.writeText(code.innerText); + + // remove selection + selection.removeAllRanges(); + }); + + // save as file + document.getElementById('save-button').addEventListener('click', function () { + // create file informations + var file = new Blob([document.getElementById('output').innerText], {type: 'text/plain'}); + // create url and link + var url = URL.createObjectURL(file); + var a = document.createElement('a'); + a.href = url; + a.download = 'sbatchfile.sh'; + document.body.appendChild(a); + // activate the link + a.click(); + // remove link after some time + setTimeout(function() { + document.body.removeChild(a); + window.URL.revokeObjectURL(url); + }, 0); + }); + + // remove the error field, if checkbox is active + document.getElementById('one-output').addEventListener('change', function () { + if (document.getElementById('one-output').checked) { + document.getElementById('err-div').style.display = 'none'; + document.getElementById('err-div').value = ''; + } else { + document.getElementById('err-div').style.display = ''; + } + }); + + // show workspace div, if checkbox is active + document.getElementById('check-workspace').addEventListener('change', function () { + let hidden = document.getElementsByClassName('row hidden'); + [].forEach.call(hidden, function (row) { + if (document.getElementById('check-workspace').checked === true) { + row.style.cssText = 'display:flex !important'; + } else { + row.style.cssText = 'display:none !important'; + } + }) + }); + + // input mask for array + document.getElementById('array').addEventListener('change', function () { + let reArray = /^[0-9]+(-[0-9]+)?(,[0-9]+(-[0-9]+)?)*(:[0-9]+)?(%[0-9]+)?$/; + if (!reArray.test(document.getElementById('array').value) && document.getElementById('array').value) { + document.getElementById('array').style.backgroundColor = 'red'; + } else { + document.getElementById('array').style.backgroundColor = ''; + } + }); + // input mask for walltime + document.getElementById('time').addEventListener('change', function () { + let reArray = /^([0-9]{1,3}-)?[0-9]{2}:[0-9]{2}:[0-9]{2}$/; + if (!reArray.test(document.getElementById('time').value) && document.getElementById('time').value) { + document.getElementById('time').style.backgroundColor = 'red'; + } else { + document.getElementById('time').style.backgroundColor = ''; + setMinDuration() + } + }); + + /** + * Function to fill the information panel about the currently selected partition + */ + var fillInfo = function() { + let panelText = document.getElementById('info-panel'); + let partitionLimits = limits[document.getElementById('partition').value]; + + panelText.innerText = partitionLimits['info']; + panelText.innerText += '\nNodes: ' + partitionLimits['nodes']; + panelText.innerText += '\nCores per node: ' + partitionLimits['cores/node']; + panelText.innerText += '\nHyper threading: ' + partitionLimits['ht_cores/node']; + panelText.innerText += '\nRAM per core: ' + partitionLimits['mem/core'] + 'MB'; + panelText.innerText += '\nRAM per node: ' + partitionLimits['mem/node'] + 'MB'; + panelText.innerText += '\nGPUs per node: ' + partitionLimits['gpu/node']; + } + + /** + * Function to fill the tooltip about the partitions + */ + var fillTooltips = function() { + for (const [key, value] of Object.entries(limits)) { + let panelText = document.getElementById(key); + let partitionLimits = limits[key]; + + panelText.title = partitionLimits['info']; + panelText.title += '\nNodes: ' + partitionLimits['nodes']; + panelText.title += '\nCores per node: ' + partitionLimits['cores/node']; + panelText.title += '\nHyper threading: ' + partitionLimits['ht_cores/node']; + panelText.title += '\nRAM per core: ' + partitionLimits['mem/core'] + 'MB'; + panelText.title += '\nRAM per node: ' + partitionLimits['mem/node'] + 'MB'; + panelText.title += '\nGPUs per node: ' + partitionLimits['gpu/node']; + } + } + + /** + * Function to fill the tooltip about the workspaces + */ + var fillTooltipsWorkspace = function() { + for (const [key, value] of Object.entries(limitsWorkspace)) { + let panelText = document.getElementById(key); + let partitionLimits = limitsWorkspace[key]; + + panelText.title = partitionLimits['info']; + panelText.title += '\nDuration: ' + partitionLimits['duration']; + panelText.title += '\nExtensions: ' + partitionLimits['extensions']; + } + } + + /** + * Function to fill the tooltip about limits of the field + * + * @param {string} field The id for the field to set the tooltip + */ + var setTooltips = function(field) { + let panelText = document.getElementById(field); + + panelText.title = 'Limits by current setting:'; + panelText.title += '\nmin: ' + panelText.min; + panelText.title += '\nmax: ' + maxValues[field]; + panelText.title += '\nEmpty the field if unneeded' + + // set limit labels + let limitText = document.getElementById(field + '-text'); + limitText.innerText = 'min: ' + panelText.min; + limitText.innerText += ' max: ' + maxValues[field]; + } + + /** + * Set the max for the tasks field + */ + var setMaxTasks = function() { + // get partition limits from dictionary + let partitionLimits = limits[document.getElementById('partition').value]; + + let nodes = 0; + // set number of nodes + if (document.getElementById('nodes').value !== '') { + nodes = Number(document.getElementById('nodes').value); + } else { + nodes = maxValues['nodes']; + } + + // set max for tasks + if (document.getElementById('nomultithread').checked === true) { + maxValues['tasks'] = nodes * partitionLimits['cores/node']; + } else { + maxValues['tasks'] = nodes * partitionLimits['ht_cores/node']; + } + if (document.getElementById('tasks/node').value !== '' && document.getElementById('nodes').value !== '') { + maxValues['tasks'] = Number(document.getElementById('tasks/node').value) + * Number(document.getElementById('nodes').value); + } + + // tasks per node + if (document.getElementById('nomultithread').checked === true) { + maxValues['tasks/node'] = partitionLimits['cores/node']; + } else { + maxValues['tasks/node'] = partitionLimits['ht_cores/node']; + } + if (document.getElementById('gpus').value !== '' && document.getElementById('nodes').value !== '' && document.getElementById('tasks').value !== '') { + document.getElementById('tasks/node').min = Number(document.getElementById('tasks').value) + / Number(document.getElementById('nodes').value); + maxValues['tasks/node'] = Number(document.getElementById('tasks').value) + / Number(document.getElementById('nodes').value); + } else { + document.getElementById('tasks/node').min = 1; + } + setTooltips('tasks'); + setTooltips('tasks/node'); + } + + /** + * Set the max for the cpus or gpus field + * + * @param {string} field The id for the field, for which the max has to be updated + */ + var setMaxCpuGpu = function(field) { + // get partition limits from dictionary + let partitionLimits = limits[document.getElementById('partition').value]; + + // get the partition limit and base for the respective field + if (field === 'cpus') { + if (document.getElementById('nomultithread').checked === true) { + limit = 'cores/node'; + } else { + limit = 'ht_cores/node'; + } + } else if (field === 'gpus/task') { + limit = 'gpu/node'; + } + + // get value from base + let tasks = document.getElementById('tasks').value; + let tasksNode = document.getElementById('tasks/node').value; + // set number of nodes + let nodes = 0; + if (document.getElementById('nodes').value !== '') { + nodes = Number(document.getElementById('nodes').value); + } else { + nodes = maxValues['nodes']; + } + + // set new max + let maxValue = [partitionLimits[limit]]; + if (tasks !== '') { + maxValue.push(Math.floor(partitionLimits[limit] / Math.ceil(Number(tasks) / Number(nodes)))); + } + if (tasksNode !== '') { + maxValue.push(Math.floor(partitionLimits[limit] / Number(document.getElementById('tasks/node').value))); + } + maxValues[field] = Math.min.apply(null, maxValue); + + // set max for cpus if gpus are set + if (document.getElementById('gpus').value !== '' && document.getElementById('gpus').value !== '0' && field === 'cpus' && document.getElementById('exclusive').checked !== true) { + maxValues[field] = Math.floor(Number(document.getElementById('gpus').value) / partitionLimits['gpu/node'] * partitionLimits[limit]); + } + // set tooltips for new limits + setTooltips(field); + } + + /** + * Set the max for the duration field + */ + var setMaxDuration = function() { + // get partition limits from dictionary + let workspaceLimits = limitsWorkspace[document.getElementById('workspace-filesystem').value]; + // set new max + maxValues['duration'] = workspaceLimits['duration']; + // set tooltips for new limits + setTooltips('duration'); + } + + /** + * Set the min for the duration field + */ + var setMinDuration = function() { + // get days and hours from walltime + let reArray = /^(([0-9]{1,3})-)?([0-9]{2}):([0-9]{2}):([0-9]{2})$/; + let match = reArray.exec(document.getElementById('time').value); + // if days are defined or not + if (match[2]) { + document.getElementById('duration').min = Number(match[2]) + Math.ceil(Number(match[3]) / 24); + } else { + document.getElementById('duration').min = Math.ceil(Number(match[3]) / 24); + } + if ((Number(match[4]) !== 0 || Number(match[5]) !== 0) && Number(match[3]) % 24 === 0) { + document.getElementById('duration').min = Number(document.getElementById('duration').min) + 1; + } + // set tooltips for new limits + setTooltips('duration'); + } + + /** + * Update the value und max for CPU values + */ + var memUpdate = function() { + // 0 limit if no cpus are selected + if (document.getElementById('cpus').value === '0' || document.getElementById('cpus').value === '') { + maxValues['mem'] = '0'; + } else { + // get partition limits from dictionary + let partitionLimits = limits[document.getElementById('partition').value]; + maxValues['mem'] = partitionLimits['mem/core']; + } + if (document.getElementById('nomultithread').checked === true) { + maxValues['mem'] *= 2; + } + if (document.getElementById('byte').value === 'G') { + maxValues['mem'] = Math.floor(maxValues['mem'] / 1024); + } + setTooltips('mem'); + } + + /** + * Update the value und max for CPU and GPU values + */ + var cpugpuLimitChange = function() { + setMaxCpuGpu('cpus'); + if (document.getElementById('div-gpu').style.display !== 'none') { + setMaxCpuGpu('gpus/task'); + } + } + + /** + * Function to trigger updates, if parttion was changed + */ + var partitionLimitChange = function() { + // get partition limits from dictionary + let partitionLimits = limits[document.getElementById('partition').value]; + // hide the GPU field, if partition do not have GPUs + if (partitionLimits['gpu/node'] === 0) { + document.getElementById('div-gpu').style.display = 'none'; + document.getElementById('div-gpu/task').style.display = 'none'; + document.getElementById('gpus').value = ''; + document.getElementById('gpus/task').value = ''; + } else { + document.getElementById('div-gpu').style.display = ''; + document.getElementById('div-gpu/task').style.display = ''; + } + // hide the multithreading field if it isnt supported + if (partitionLimits['cores/node'] === partitionLimits['ht_cores/node']) { + document.getElementById('div-thread').style.display = 'none'; + document.getElementById('nomultithread').checked = false; + } else { + document.getElementById('div-thread').style.display = ''; + } + // set new max for nodes + maxValues['nodes'] = partitionLimits['nodes']; + setTooltips('nodes'); + // set max for gpus + maxValues['gpus'] = partitionLimits['gpu/node']; + setTooltips('gpus'); + // update other values + setMaxTasks(); + cpugpuLimitChange(); + memUpdate(); + } + + // set up event listeners, if field change + document.getElementById('partition').addEventListener('change', partitionLimitChange); + document.getElementById('partition').addEventListener('change', fillInfo); + document.getElementById('tasks').addEventListener('change', cpugpuLimitChange); + document.getElementById('byte').addEventListener('change', memUpdate); + document.getElementById('nodes').addEventListener('change', cpugpuLimitChange); + document.getElementById('nodes').addEventListener('change', setMaxTasks); + document.getElementById('tasks').addEventListener('change', memUpdate); + document.getElementById('tasks').addEventListener('change', setMaxTasks); + document.getElementById('gpus').addEventListener('change', setMaxTasks); + document.getElementById('gpus').addEventListener('change', cpugpuLimitChange); + document.getElementById('tasks/node').addEventListener('change', setMaxTasks); + document.getElementById('tasks/node').addEventListener('change', cpugpuLimitChange); + document.getElementById('cpus').addEventListener('change', memUpdate); + document.getElementById('exclusive').addEventListener('change', memUpdate); + document.getElementById('exclusive').addEventListener('change', cpugpuLimitChange); + document.getElementById('nomultithread').addEventListener('change', partitionLimitChange); + document.getElementById('workspace-filesystem').addEventListener('change', setMaxDuration); + + // hide jobid field if unneeded + document.getElementById('type-depend').addEventListener('change', function() { + if (document.getElementById('type-depend').value === 'none' || + document.getElementById('type-depend').value === 'singleton') { + document.getElementById('jobid').style.cssText = 'display:none !important'; + } else { + document.getElementById('jobid').style.cssText = 'display:inline !important'; + } + }); + + document.getElementById('generate-button').addEventListener('click', proofValues); + + // initialize webpage + + // set up the collapsible fields + let colls = document.getElementsByClassName('collapsible'); + [].forEach.call(colls, function (coll) { + // add event listeners + coll.addEventListener('click', function() { + this.classList.toggle('active'); + let content = this.nextElementSibling; + if (content.style.display === 'block') { + content.style.display = 'none'; + } else { + content.style.display = 'block'; + } + }); + + // extended at beginning + let content = coll.nextElementSibling; + content.style.display = 'block'; + coll.classList.toggle('active'); + }) + + // set up of partition options + let select = document.getElementById('partition'); + + for (const [key, value] of Object.entries(limits)) { + let option = document.createElement('option'); + option.id = key; + option.value = key; + option.innerText = key; + if (key === 'haswell64') { + option.selected = 'selected'; + } + select.appendChild(option); + } + + // set up of workspace options + select = document.getElementById('workspace-filesystem'); + + for (const [key, value] of Object.entries(limitsWorkspace)) { + let option = document.createElement('option'); + option.id = key; + option.value = key; + option.innerText = key; + if (key === 'scratch') { + option.selected = 'selected'; + } + select.appendChild(option); + } + + // initialize UI + partitionLimitChange(); + fillInfo(); + fillTooltips(); + fillTooltipsWorkspace(); + setMaxDuration(); + </script> + </body> +</html> diff --git a/doc.zih.tu-dresden.de/mkdocs.yml b/doc.zih.tu-dresden.de/mkdocs.yml index 34e6df334..4b5e8ce98 100644 --- a/doc.zih.tu-dresden.de/mkdocs.yml +++ b/doc.zih.tu-dresden.de/mkdocs.yml @@ -103,6 +103,7 @@ nav: - Batch System Slurm: jobs_and_resources/slurm.md - Job Examples: jobs_and_resources/slurm_examples.md - Partitions and Limits : jobs_and_resources/partitions_and_limits.md + - Slurm Job Generator : jobs_and_resources/slurm_generator.md - Checkpoint/Restart: jobs_and_resources/checkpoint_restart.md - Job Profiling: jobs_and_resources/slurm_profiling.md - Binding And Distribution Of Tasks: jobs_and_resources/binding_and_distribution_of_tasks.md diff --git a/doc.zih.tu-dresden.de/tud_theme/stylesheets/extra.css b/doc.zih.tu-dresden.de/tud_theme/stylesheets/extra.css index f5664bf72..a925a9eca 100644 --- a/doc.zih.tu-dresden.de/tud_theme/stylesheets/extra.css +++ b/doc.zih.tu-dresden.de/tud_theme/stylesheets/extra.css @@ -252,3 +252,128 @@ p { color: var(--tud-red-90); } +/* style for the slurm job generator */ +/* universal style */ +body { + margin: auto; + width: 90%; + } + img { + display: block; + } + pre { + background-color: lightgrey; + border-color: black; + border-width: 1pt; + } + .header { + background-color: #002557; + } + label.header { + color: white; + font-size: 40px; + margin: 15px; + } + .hidden { + display: none !important; + } + .info-img { + height: 20px; + width: 20px; + } + .info-pre { + display: flex; + padding: 5px; + } + .limits { + color: red; + display: none; + margin-left: 10px; + } + button.output { + padding: 8px; + background-color: rgba(231, 231, 231, 0.726); + border-color: rgba(124, 119, 119, 0.541); + border-radius: .25rem; + } + button.output:hover, button.output:focus { + background-color: #ddd; + } + div.output { + margin: 15px 0px; + } + + /* tablelike layout */ + .input { + display: block; + width: 70%; + } + .row { + align-items: center; + display: flex; + width: 100%; + } + .cell-name { + display: flex; + height: 25px; + justify-content: center; + align-items: center; + width: 125px; + } + .cell-tooltip { + align-items: center; + display: flex; + height: 25px; + justify-content: center; + width: 25px; + } + .cell-input { + display: flexbox; + vertical-align: middle; + } + .partition-input { + float: left; + width: 650px; + } + .partition-info { + display: flex; + float: left; + width: calc(30%); + } + + /* collapsible */ + .active { + background-color: #5a7094 !important; + } + .active:after { + content: "-" !important; + } + .collapsible { + background-color: #274275; + border: none; + color: #fff; + cursor: pointer; + font-size: 20px; + outline: none; + padding: 18px; + text-align: left; + width: 100%; + } + .collapsible:hover, .collapsible:focus { + text-decoration: underline; + } + .collapsible:after { + color: #fff; + content: '+'; + float: right; + font-size: 20px; + font-weight:900; + margin-left: 5px; + } + .content { + background-color: #f1f1f1; + display: block; + overflow: hidden; + padding: 0 18px; + } + -- GitLab