Laurent Deniau, CERN BE/ABP, 1211 Geneva 23, [email protected] BE Methodical Accelerator Design Next Generation Technologies Laurent Deniau CERN-BE/ABP 29th January 2016 Beams Department Who am i? (as a computer scientist) BE Beams Department ๏ 1990-1992 consultant for C and C++ development (for money…) ๏ 1992 Engineer in computer science + DEA in sensors physics and signal processing ๏ 1994-1996 teach C and C++ as well as scientific computing at university ๏ 1994,1996 C++ revolution: ARM, Barton and Nackman, Inside C++ Object Model (Lippman), D&E. Laurent Deniau, CERN BE/ABP, 1211 Geneva 23, [email protected] ๏ 1997 PhD in signal & image processing + CERN staff (LHC-MTA, magnetic fields) 1998 develop SL++ (presented at LHC++98) ➡ advanced linear algebra C++98 library (ancestor of Eigen and Armadillo) ➡ intensive use of template expressions, SFINAE, and __restrict__ keyword ➡ complementary to Blitz++ (from T. Veldhuizen), but too advanced for ROOT… ๏ 1999-2007 develop & support Superconducting Magnet Analysis tools (5 servers) ➡ interactive multi users + multi sessions load balanced web application (pre-AJAX) ➡ online db access, devices calibrations, data filtering+analysis, plots, reports generator 2004 attempts to develop a better object model for C++ (after Sidwell’s paper) ➡ technical paper on the C++ object model with complex examples in C (never published) 2006-2007 develop the « C Object System » (papers & code on github & arXiv.org) ➡ use C99 preprocessor for parsing DSL and generate classes and objects on-the-fly ➡ static+dynamic typing, fast multi-methods, fast delegation, self-consistent object model, exceptions, contracts, closures, … (very powerful object oriented framework) 2 What is MAD? BE Beams Department ๏ MAD: Methodical Accelerator Design ➡ design, studies and optimization of beam physics for particle accelerators ➡ family of applications from the 70’s and 80’s ➡ MAD8 1984-2002 (F77) developed for LEP Laurent Deniau, CERN BE/ABP, 1211 Geneva 23, [email protected] ➡ MAD9 + Classic 1994-2004 (C++) developed for LHC ➡ MAD-X 2000- (F77, F90, C, C++) crash program for LHC, +PTC/FPP from E. Forest. ➡ MAD-NG 2014- (C, Lua) ๏ MAD code specificities (developed by physicists) ➡ user input scripts: highly dynamic, injected deeply inside physics calculations ➡ complex scientific code: ~80% of the code is for scientific computations (~160 KSLOC) ➡ prototypical language without delegation: clone+update objects ➠ dictionary ➡ deferred expressions: lazy evaluation everywhere (!) for sharing and links ➡ « abstractions » make string lookup, expr. evaluation and memory management critical ➡ global workspace: everything is global, no scope (deferred expr. ➠ lambda without parameters) ➡ context dependent syntax and semantic: command specific « parser » and behavior… ➡ weak macro system: unexpected behavior… 3 Objectives of MAD-NG BE Beams Department ๏ Long term design and easy to use ➡ Safe, correct and accurate ➠ closed to changes, open to extensions and compositions ➡ Flexible ➠ easy scripting language to implement new features (avoid backdoor) ➡ Extensible ➠ good architecture to extend existing features (avoid special cases) Laurent Deniau, CERN BE/ABP, 1211 Geneva 23, [email protected] ➡ Efficient ➠ performance of MAD-X or better ๏ Robust, consistent and easy to support ➡ Expressive ➠ smaller code, easier to read, understand and document ➡ Partitioned ➠ less coupling, less dependencies easier to maintain ➡ Functional ➠ less globals, options, attributes and side effects (avoid headaches) ➡ License GPLv3 ➠ all modifications (improvements) must be submitted to the authors ๏ Portable and easy to maintain ➡ Simple technologies ➠ simple to build, test, install and run ➡ Portable technologies ➠ same code gives same results everywhere ➡ Flexible technologies ➠ reduce updates and releases, self-contained 4 Constraints of MAD-NG BE Beams Department ๏ Resources ➡ MAD8 (F77) ~ 4-7 years x2 staffs (from scratch + TRANSPORT) ➡ MAD9 (C++) ~ 4-7 years x1 staff + Classic collaboration (from scratch + MAD8) ➡ MAD-X (C, F77, F90) ~ 3-5 years x1 staff (from MAD8 + PTC/FPP) Laurent Deniau, CERN BE/ABP, 1211 Geneva 23, [email protected] ➡ MAD-NG (C, Lua) ~ 2-3 years x0.4 staff (from scratch + PTC) ๏ Schedule ➡ 2013-2014 R&D ➡ 2014-2015 GTPSA ➡ 2015 Prototypes (elements, sequences, tables, survey, tracking, plot, algebra ℝ&ℂ) ➡ 2016 Development (integration, modules completion, twiss, match) ➡ 2017 Consolidation + check, check, check… + high order normal forms Productivity must be about x5 higher than for previous MADs ➠ importance to use simple and flexible technologies 5 BE Layout Beams Department ๏ Red area should be entirely written in the scripting language ➡ Implement >80% of the features with full “monitored” access to physics and algebra! ➡ Importance of the scripting language!! ➠ clear, simple, expressive and efficient Laurent Deniau, CERN BE/ABP, 1211 Geneva 23, [email protected] efficient + expressive ➠ simple ➠ clear User scripts Classes, Lattices, Studies Toolbox help, tests I/O, env, ... Components Objects, Elements, Sequences, Tables, Maps Survey, Tracking, Matching, Normal Forms Math (ℝ & ℂ) Linear Algebra (ℝ & ℂ) Differential Algebra (ℝ & ℂ) Plotting Numerics FFT, OPT (ℝ & ℂ) 6 Technologies overview (static) BE Beams Department ๏ Simple for user, simple for developper, simple for support, efficient enough for physics. ๏ Candidates: C, C++, Fortran, Java. ➡ C (99) is the baseline: simple, stable, fast, well supported, well known, portable. Laurent Deniau, CERN BE/ABP, 1211 Geneva 23, [email protected] ‣ ± low level, − operator overloading, ± poor standard library (pros & cons!), ± GC. ➡ C++ (14) is (too?) complex for BE-ABP expertise (who will takeover after me?). ‣ what about portability, productivity, dependencies and performance (i.e. low expertise) ‣ rely on SFINAE, CRTP, template expressions, type erasure, visitors, observers, alloc. ‣ support & technology: GCC (good asm), LLVM (good inlining), Intel (best, but?). ‣ BE-ABP attempts switched to Python, Matlab, Mathematica… MAD9 experience… ➡ Fortran (95) is simple, fast, moderately expressive, not so supported, not so portable. ‣ not so appealing, + operator overloading, not dead (std 2003, 2008, 2015)… ➡ Java (1.8) is simple, moderately fast, GC, not so expressive, well supported, portable. ‣ − heavy runtime, − operator overloading, + interface (dyn.), ± rich SDK (pros & cons!) none of them are good in all aspects 7 Technologies overview (dynamic) BE Beams Department ๏ Simple for user, simple for developper, simple for support, efficient enough for physics. ๏ Candidates: Python, Lua, Javascript, (Ruby, Perl, Tcl, R). ➡ Python: simple, too slow for physics, well supported & known, moderately portable. Laurent Deniau, CERN BE/ABP, 1211 Geneva 23, [email protected] ‣ large community, many libraries, easy connection to C & C++, not easy to embed. ‣ powerful « glue » language, very dynamic, most used & known in BE-ABP. ‣ JIT: PyPy(CFFI) is running after LuaJIT(FFI)… integration? portability? ➡ Lua: the simplest, faster than Python, well supported, very portable, mature. ‣ « smaller » community, many libraries, easy connection to C, easy to embed. ‣ JIT: one of the best ever, compete with C and C++ and beat Java in most cases. ‣ JIT: provide the best FFI interface ever, tracing JIT, include a profiler and a tracer. ➡ Javascript: simple, faster than Python (V8), well supported & known, very portable, not suitable for scientific computing. none of them are good in all aspects 8 Technologies overview (exotic) BE Beams Department ๏ Simple for user, simple for developper, simple for support, efficient enough for physics. ๏ Candidates: Julia, D, Scala, Haskell, COS, (Go, Swift). ➡ Julia (0.4) is the rising scripting language (dynamic) in scientific computing, not yet mature, rely on LLVM technologies (JIT), support multi-methods (!), heavy FFI, future? Laurent Deniau, CERN BE/ABP, 1211 Geneva 23, [email protected] ➡ D (2) is between C++ and Java, not well known, not well supported, future? ➡ Scala (2) is a much better Java (same VM), more expressive, more complex, operator overloading, functional & object oriented, traits, rich type system (parametric+variance +constraint+existential) ➠ not so known (EPFL!) and probably as complex as C++. ➡ Haskell (2010): good in most points (one of my favorite), powerful, rather exotic and complex for common users and developers, low performance if low expertise. ➡ C Object System: good in most points (one of my favorite), simple and powerful pure C solution but single person technology, no operator overloading, no community. Potential candidate for an « all in C » simple and efficient solution. exotic technologies should be envisaged in last resort 9 Technologies overview (combinations) BE Beams Department ๏ Python + C (motivation: widely known/used at CERN and BE-ABP, huge community) ➡ Python is too slow for the physics ➠ 80% of the code in C / C++ ➠ resources… ➡ Python is a high level user « glue » language ➠ callback ➠ sandboxing… Laurent Deniau, CERN BE/ABP, 1211 Geneva 23, [email protected] ➡ Python relies on many libraries ➠ problem of portability and integration ➠ packaging… ➡ Python relies on many libraries ➠ maintenance of dependencies… ➡ JIT: is PyPy(CFFI) good enough? How to integrate everything? Libraries compatibility? ๏ LuaJIT + C (motivation: simplicity, performance, integration, portability) ➡ Lua: simple, dynamic, can be generative, prototypical, functional, object oriented, … ➡ LuaJIT is fast enough for everything ➠ 20% in C, no callback, easy sandboxing… ➡ LuaJIT is less known/used (small community) ➠ fallback: PyPy(CFFI) + C ➡ integration of LuaJIT and C is trivial with FFI (see demo) ➡ C is good for low level, vectorized and parallel computations (SSE, OMP, MPI, GPU). LuaJIT + C considered as the best compromise ➠ selected solution 10 BE Performances (containers) library « class » « native » type C++ GCC 4.8 : 21 sec LuaJIT 2.1 : 7.2 sec Laurent Deniau, CERN BE/ABP, 1211 Geneva 23, [email protected] template <typename T> T find_duplicates(const T& inp) { std::unordered_map<typename T::value_type, int> map; T result; for (auto &item : inp) map[item] += 1; for (auto &item : inp) { auto &count = map[item]; if (count > 1) result.push_back(item), count=0; } return result; } Beams Department local function find_duplicates(inp) local out = {} for _,v in ipairs(inp) do out[v] = out[v] and out[v]+1 or 1 end for _,v in ipairs(inp) do if out[v] > 1 then out[#out+1], out[v] = v, 0 end end return out end local inp, out inp = {'b','a','c','c','e','a','c','d','c','d'} int main() { std::vector<std::string> inp, out; inp = {"b","a","c","c","e","a","c","d","c","d"}; for (int i=1; i<10000000; i++) out = find_duplicates(inp); std::cout << "{ "; for (auto &a : out) std::cout << "\"" << a << "\","; std::cout << "}" << std::endl; } C++ Intel 16 : 26.4 sec C++ LLVM 3.7 : 26.7 sec for i=1,1e7 do out = find_duplicates(inp) end io.write('{ ') for _,v in ipairs(out) do io.write('"', v, '",') end io.write('}\n') output: { "a","c","d",} C++ GCC 4.8 + OMP (4 cores 100%) : 10.7 sec 11 BE Performances (abstraction and small size types) library « class » « interpreted » function f(z) return z*z + (1+1i)*z - 1 end local z = 0.1 for i=1,1e9 do z = f(z) end print(z) « native » type Python 2.7 : 459 sec or 2hr def f(z): return z*z + (1+1j)*z - 1 z = 0.1 for i in range(1,100000000): z = f(z) print(z) Julia 0.4 : 35 sec function f(z) return z*z + (1+1im)*z - 1 end local z = 0.1 for i=1:1000000000 z = f(z) end println(z) PyPy 4.0 : 7.6 or 10.2 sec C++ GCC 4.8 : 6.8 sec compiled Laurent Deniau, CERN BE/ABP, 1211 Geneva 23, [email protected] MAD (LJ2.1) : 5.3 sec Beams Department C GCC 4.8 : 5.7 sec inline std::complex<double> f(const std::complex<double> &z) { return z*z + (1.0+I)*z - 1.0; } int main() { std::complex<double> z = 0.1; for (int i=1; i<1000000000; i++) z = f(z); std::cout << z << std::endl; return 0; } C++ Intel 16 : 5.7 sec C++ LLVM 3.7 : 20.4 sec static inline complex double f(complex double z) { return z*z + (1+I)*z - 1; } OK 2 x n i with int main(void) { complex double z = 0.1; for (int i=1; i<1000000000; i++) z = f(z); printf("%+g%+gi\n", creal(z),cimag(z)); return 0; } C Intel 16 : 5.3 sec 12 Performances (abstraction and medium size types) I = matrix.eye(n) def f(z): return z*z + (1+1j)*z - I PyPy 4.0 + NumPy : [4x4] 162 sec [6x6] 188 sec [8x8] 220 sec BE Beams Department framework z = I*0.1 for i in range(1,10000000): z = f(z) Laurent Deniau, CERN BE/ABP, 1211 Geneva 23, [email protected] print(z) local I = matrix(n):eye() function f(z) return z*z + (1+1i)*z - I end local z = I*0.1 for i=1,1e7 do z = f(z) end print(z) library « class » C++ GCC 4.8 + Eigen 3.3 : [4x4] 6.0 sec [6x6] 9.4 sec [8x8] 15.1 sec static CMatrix I; MAD (LJ2.1) : [4x4] 9.2 sec [6x6] 16.5 sec [8x8] 29.7 sec local I, r = matrix(n):eye(), cmatrix(n) function f(z) z:mul(z, r) return z:mul(1+1i,z):sub(I,z):add(r,z) end inline CMatrix f(const CMatrix &z) { return z*z + Cpx(1,1)*z - I; } MAD (LJ2.1) : [4x4] 2.3 sec no allocation [6x6] 6.5 sec [8x8] 16.4 sec int main() { I = CMatrix::Identity(nr, nc); CMatrix z = I*0.1; for (int i=0; i < 10000000; i++) z = f(z); std::cout << z << std::endl; } local z = cmatrix(n):eye(0.1) for i=1,1e7 do z = f(z) end print(z) C++ GCC 4.8 + Eigen 3.3 : [4x4] 1.5 sec no allocation [6x6] 3.9 sec [8x8] 13.9 sec 13 BE Performances (abstraction and algorithms) m = np.matrix([[…],…,[…]]) a = m[:nr,:nc].T b = m[:nc,:nr] # [8x8] # *1j for i in range(1,1000000): c = solve(b,a) # lstsq(b,a)[0] Laurent Deniau, CERN BE/ABP, 1211 Geneva 23, [email protected] print(c.T) PyPy 4.0 + NumPy : [4x4] 29 sec real [6x6] 31 sec [8x8] 32 sec Beams Department framework PyPy 4.0 + NumPy : [4x4] 39 sec complex [6x6] 43 sec [8x8] 47 sec PyPy 4.0 + NumPy : [3x4] 95 sec real [5x6] 101 sec [7x8] 120 sec library « class » local local local local m = matrix {{…},…,{…}} -- [8x8] a = m:get_sub{1,1,nr,nc} -- *1i b = m:get_sub{1,1,nc,nr}:t() c for i=1,1e6 do c = a/b end print(c) int main() { CMatrix m(8,8); m << … ; // [8x8] // *I; CMatrix a = m.block(0,0,nr,nc).transpose(); CMatrix b = m.block(0,0,nc,nr); CMatrix c; for (int i=0; i < 1000000; i++) c = b.fullPivHouseholderQr().solve(a); std::cout << c.transpose() << std::endl; } PyPy 4.0 + NumPy : [3x4] 251 sec complex [5x6] 269 sec [7x8] 291 sec MAD (LJ2.1) : [4x4] 1.1 sec real [6x6] 2.1 sec [8x8] 3.6 sec C++ 4.8 + Eigen 3.3 : [4x4] 3.5 sec real [6x6] 6.7 sec [8x8] 8.0 sec MAD (LJ2.1) : [4x4] 1.5 sec complex [6x6] 3.1 sec [8x8] 5.4 sec C++ 4.8 + Eigen 3.3 : [4x4] 4.4 sec complex [6x6] 7.7 sec [8x8] 12.3 sec MAD (LJ2.1) : [3x4] 2.5 sec real [5x6] 4.5 sec [7x8] 7.4 sec C++ 4.8 + Eigen 3.3 : [3x4] 3.3 sec real [5x6] 5.2 sec [7x8] 7.3 sec MAD (LJ2.1) : [3x4] 4.0 sec complex [5x6] 7.6 sec [7x8] 12.6 sec C++ 4.8 + Eigen 3.3 : [3x4] 3.8 sec complex [5x6] 6.8 sec [7x8] 11.1sec 14 Technology details BE Beams Department Laurent Deniau, CERN BE/ABP, 1211 Geneva 23, [email protected] LuaJIT has been successfully used as a scripting middleware in games, appliances, network and graphics apps, numerical simulations, trading platforms and many other specialty applications. It scales from embedded devices, smartphones, desktops up to server farms. It combines high flexibility with high performance and an unmatched low memory footprint. LuaJIT has been in continuous development since 2005. It's widely considered to be one of the fastest dynamic language implementations. It has outperformed other dynamic languages on many crosslanguage benchmarks since its first release — often by a substantial margin. For LuaJIT 2.0, the whole VM has been rewritten from the ground up and relentlessly optimized for performance. It combines a high-speed interpreter, written in assembler, with a state-of-theart JIT compiler. An innovative trace compiler is integrated with advanced, SSA-based optimizations and highly tuned code generation backends. A substantial reduction of the overhead associated with dynamic languages allows it to break into the performance range traditionally reserved for offline, static language compilers. compagnies secret weapon… 15 Technology choice BE Beams Department ๏ The current choice (LuaJIT + C) is the « easy » way ➡ choice of maximum flexibility & good speed ➡ good ratio development vs. resources Laurent Deniau, CERN BE/ABP, 1211 Geneva 23, [email protected] ➡ allow quick design exploration and postpone decisions ➡ proof of concepts quickly become final version ➡ fast integration demo ๏ The alternate choice (PyPy + C) could be a good alternative in the future (few years) ➡ need many more benchmarks to validate the JIT ➡ check libraries compatibility and portability (GC, delay, patches) ➡ PyPy CFFI is a clone of LuaJIT FFI ➠ easy binding ➡ integration, portability, stability, distribution, community? ➡ embedding PyPy? interactive? dependencies? ➡ Python 2.7 or 3 (delay)? 16 BE R&D achievements Beams Department ๏ Domain Specific Language in Lua (DSL) ➡ use the expressive power of the language to embed a domain-friendly syntax ➡ Pros: entirely written in Lua, adapted to the domain ➠ simple and intuitive to specialists ➡ Cons: heavy machinery behind the scene, make debugging more difficult Laurent Deniau, CERN BE/ABP, 1211 Geneva 23, [email protected] Is the syntax so important? ๏ On-the-fly Parser Generator in Lua (advanced topic) ➡ Allow to read and extend other languages (e.g. MAD-X, Lua), eval. 100 KLOC/sec ➡ Already able to parse LHC files, MAD-X dict, deferred. expr. (lambda), macros, ... ➡ Pros: read new inputs, compatibility with other codes (as soon as grammars exist) ➡ Cons: heavy machinery, difficulty to report errors location, interactive mode .madx .mad .lua select grammar generate parser user script parser code parse (build AST) context transform (AST ➠ AST’) lua script generate (AST’ ➠ Lua) execute (LuaJIT) Abstract Syntax Tree = program representation 17 BE R&D achievements (cont.) Beams Department ๏ New interpreter (fallback, aka MAD-X 6 ➠ 100% in C) ➡ highly portable and extensible interpreter written in C (x10 faster than Python ➠ callback) ➡ rely on tagged pointers, NaN mangling and CPS dynamic dispatch techniques (advanced) ➡ slower, less expressive, much bigger code ➠ physics not in the scripting language! Laurent Deniau, CERN BE/ABP, 1211 Geneva 23, [email protected] ➡ Pros: standalone, main stream tech., “full” control, lang. syntax, optimized data structures ➡ Cons: heavy & complex code (experts!), less flexibility, less efficiency (x5-x10 slower), potential conflicts of API with garbage collectors and scripting languages (e.g. Python), only one language supported… ๏ Generalized Truncated Power Series Algebra (GTPSA Library) ➡ improve and extend Berz TPSA ➡ automatic differentiation (differential algebra) ➡ real and complex (for high order normal forms) ➡ support hundreds of Knobs R&D Proof of concepts Helped a lot to take decisions to make the design, and to have fallbacks. ➡ fast, parallel, 100% in C + Lua API ๏ Linear Algebra (ℝ & ℂ Matrix libraries) ➡ fast, Lua + 20% in C + Lapack F77 Not mandatory for MAD-NG Can be included later (except Matrix & GTPSA) 18 BE Prototypical Language Beams Department ๏ Prototypical = Prototype + Delegation ➠ more general than Class + Inheritance Laurent Deniau, CERN BE/ABP, 1211 Geneva 23, [email protected] U$ina Prototynical Obiects to Imolement Shared Behavior in Obiect Oriented Systems HenryLieberman A traditional philosophical controversy between representing ArtO~cial Intelligence Laboratory general concepts as abstract sets or classes and representing concepts as concrete Massachusetts lnatimte ofprototypes Technology is reflected in a controversy 02139 USA between two mechanisms for Combrid&e, sharing Mass. behavior between objects in object oriented programming languages. Inheritance splits the object world into classes, which encode Electronic mall ( A ~ t ) : behavior shared among a group of instances, which individual members of these sets. Henry@AI .AI .MIT. Edu, represent Henry@MIT-AI The class/instance distinction is not needed if the alternative of using prototypes is adopted. A 1. Setsand vs. prototypes: a philosophical dilemma prototype represents the default behavior for a concept, new objects can re-use part of the consequences knowledge stored in the prototype by saying how the with new practical object differs from the prototype. The prototype approach seems to hold some advantages for representing default knowledge, and How doDelegation people represent is knowledge about generalizations incrementally andAbstract dynamically modifying concepts. the mechanism for they make from its experience with concrete situations? implementing this in object oriented languages. After checking idiosyncratic behavior, an Philosophers concerned with the theory of knowledge have can forward a message to prototypes Aobject traditional philosophical controversy between representing to invoke more general knowledge. Because class debated thisand question, but ascan we shall issue is not objects mustasbe created before instances can be used, behavior onlysee, be the associated general concepts abstract sets or classestheir and representing without practical consequences for the task of creation representing with classes, inheritance fixes the communication patterns between objects at instance concepts as concrete prowrypes is reflected in a controversy knowledge in object oriented systems. Because muchatof time. Because any object can be used between as a prototype, and any messages can be forwarded between two mechanisms for sharing behavior object of oriented progrmuming involves constructing any time, delegation is the more flexible and general the two techniques. objects in object oriented progrJmmtng languages. l,~,~rance ,pUts the object world into c/asses, which encode behavior shared among a group of ins~,,ces, which represem individual membe~ of these sets. The class/instanee representations of objects in the real world, our mechanisms OOPLSA’86 for storing and using real world knowledge get reflected in 19 mechanisms for dealing with objects in computm" languages. We'll examine how the traditional contmvorsy between BE Object model (user, details) elements Laurent Deniau, CERN BE/ABP, 1211 Geneva 23, [email protected] qf1 qd1 qf2 qd2 ๏ MAD-X definition: ➡ share attributes statically (clone) ➡ no delegation (no lookup) ➡ global workspace! ๏ MAD-NG definition: ➡ inherit attributes dynamically (lookup) circuits Beams Department Read: lookup for parent attributes if needed Write: set/override element attributes qf type mq class kind quad strait element qd mq.l = 2.10 ; qf.k1 = 0.05 ; qd.k1 = -0.06 ; mq: quadrupole, qf: mq , qd: mq , cell: sequence, qf1:qf,at=0 ; endsequence; qf->k1 = 0.06 ; qf.k1 = 0.06; value qf1->k1; ! type ! circuit 3 variables + 3 ! circuit l := mq.l; k1 := qf.k1; k1 := qd.k1; l = 40, refer = entry; qd1:qd,at=10 ; qf2:qf,at=20 ; qd2:qd,at=30 ; elements ! BAD! no update of children ! update qf circuit ! print 0.06 only 3 elements mq = quad { l = 2.10 } -- type qf = mq { k1 = 0.05 } -- circuit qd = mq { k1 = -0.06 } -- circuit cell = sequence ‘cell’ { l = 40, refer = ‘entry’, qf{‘qf1’,at=0}, qd{‘qd1’,at=10}, qf{‘qf2’,at=20}, qd{‘qd2’,at=30} } qf.k1 = 0.06 -- update qf circuit (same as qf->k1 but OK!) print(qf1.k1) -- print 0.06 ➡ delegation should avoid the need of >90% of the deferred expressions and save extra variables 20 Laurent Deniau, CERN BE/ABP, 1211 Geneva 23, [email protected] BE Beams Department Extra slides 21 BE Deferred expressions (user, details) Laurent Deniau, CERN BE/ABP, 1211 Geneva 23, [email protected] ๏ MAD-X definition: ๏ MAD-NG definition: ๏ MAD-X behavior: ➡ common misunderstanding ➡ abuse of deferred expressions like in mq.l := 2.10; mq.l = 2.10 ; qf.k1 = 0.05 ; mq: quadrupole, qf: mq , qd: mq , cell: sequence, qf1:qf,at=0 ; endsequence; qf.k1 = 0.06; value qd->k1; Beams Department ! type ! circuit l := mq.l; k1 := qf.k1; k1 := -qf.k1*0.95; ! deferred expression l = 40, refer = entry; qd1:qd,at=10 ; qf2:qf,at=20 ; qd2:qd,at=30 ; ! update qf circuit ! print -0.057 deferred expressions are implemented as lambda functions without argument, controlled context and implicit function call mq = quad { l = 2.10 } -- type qf = mq { k1 = 0.05 } -- circuit qd = mq { k1 = D”-qf.k1*0.95” } -- deferred expression cell = sequ ‘cell’ { l = 40, refer = ‘entry’, qf{‘qf1’,at=0}, qd{‘qd1’,at=10}, qf{‘qf2’,at=20}, qd{‘qd2’,at=30} } qf.k1 = 0.06 -- update qf circuit print(qd.k1) -- print -0.057 X:> mq: quadrupole, l := mq.l; X:> value mq->l; mq->l = 0 ; X:> mq.l = 2.1; X:> qf: mq ; X:> value qf->l; qf->l = 2.1 ; X:> mq.l = 2.2; X:> value qf->l; qf->l = 2.2 ; X:> mq->l = 2.3; X:> value qf->l; qf->l = 2.2 ; ! mq.l not yet defined ! not an error, default is zero!! ! define mq.l ! cloning is not inheritance ! update variable, OK! ! update attribute, BAD! 22 Sequence examples (user) BE Beams Department ๏ Simple construction of lattice using operator overloading ➡ can mix sequences, subsequence, lines and elements arbitrarily ➡ names can be anonymous or non-unique function make_als() -- PTC-like definition (thick) Laurent Deniau, CERN BE/ABP, 1211 Geneva 23, [email protected] ... BEND = rbend 'BEND' { length=l_bend, angle=alpha, k1=-0.778741 } BEND1 = rbend 'BEND1' { length=l_bend, angle=alpha, k1=-0.778741 } CAV = rfcav 'CAV' { length=0.0, volt=-1.0, freq=500e6 } SUP1 = L1+L2+L3+QF1+VC5+L4+L5+QD1+L6+L7+L8+VC5+BEND+VC5+L9+SF+L10+ L11+QFA1+L12+SD+L13+ L14+BEND+L15+L16+SD+L17+ QFA2+L18+L19+SF+L20+BEND+L21+ L22+QD2+L23+L24+QF2+L25+ L26+VC5+L27 SUPB = L1+L2+L3+QF1+VC5+L4+L5+QD1+L6+L7+L8+VC5+BEND+VC5+L9+SF+L10+ L11+QFA1+L12+SD+L13+ L14+BEND+L15+L16+SD+L17+ QFA2+L18+L19+SF+L20+BEND1+L21+ L22+QD2+L23+L24+QF2+L25+ L26+VC5+L27 return sequ 'ALS' { 11*SUP1+SUPB+CAV } end 23 Sequences, subsequences and elements (details) BE Beams Department ๏ Element position <refer, at, from> unified in line, sequences and subsequences ➡ Support MAD8, MAD9, MAD-X and more combinations and options safely Laurent Deniau, CERN BE/ABP, 1211 Geneva 23, [email protected] function element_spos (self, elem) -- self is the parent sequence local s_pos = elem.s_pos if type(s_pos) == 'number' then return s_pos end if s_pos == 'ongoing' then error("cycle detected: "..elem.name) end elem.s_pos local len local idx local seq local pos local from local refer = = = = = = = 'ongoing' -- cycle detection self.length elem._idx elem._seq elem._at or 0 elem._from or elem._at and 'start' or 'prev' elem._refer or self.refer or 'entry' if refer == 'entry' then ; elseif refer == 'centre' then pos = pos elseif refer == 'exit' then pos = pos elseif seq and seq[refer] then pos = pos else error("invalid refer: "..elem._refer) clear ➠ simple (seq and seq.length/2 or elem.length/2) (seq and seq.length or elem.length) seq[refer].s_pos end if from == 'start' then ; elseif from == 'end' and len then pos = len elseif from == 'prev' then pos = pos + elseif from == 'next' then pos = pos + elseif self[from] then pos = pos + else error("invalid from: "..elem._from) end pos self[idx-1].s_pos + self[idx-1].length element_spos(self, self[idx+1]) element_spos(self, self[from]) elem.s_pos = pos -- s_pos is computed ‘at’ return pos end 24 Flexible data structures examples (user) BE Beams Department Laurent Deniau, CERN BE/ABP, 1211 Geneva 23, [email protected] ๏ Sequences, assemblies and thick elements are containers (array + dictionary) mb = sbend ‘mb’ { length = 14.30, angle = 0.005 } mq = quad ‘mq’ { length = 3.10, k1 = 0.008 } fcell = sequ ‘fcell’ { length = 53.5, mq ‘qf’ {at=1.5}, mb ‘mb’ {at=8}, 2*(mb ‘mb’ {}) } -- sequence as array (used by tracking) fcell[1].k1 = 0.007 -- update 1st mq strength fcell[2].angle = 0.006 -- update 1st mb strength fcell[3].angle = 0.006 -- update 2nd mb strength (but not 3rd) -- sequence as dictionary fcell.qf.k1 = 0.006 -- update 1st mq strength fcell.mb[1].angle = 0.007 -- update 1st mb strength fcell.mb[2].angle = 0.007 -- update 2nd mb strength fcell.mb.angle = 0.007 -- error, mb needs an index fcell.qf[2].k1 = 0.006 -- error, qf is not an array Sequences and tables are much more flexible than in MAD-X, and used everywhere inside MAD-NG ๏ Tables are containers (array of arrays + dictionaries) tab = table 'survey' { {'name'}, 'x', 'y', 'z', 'theta', 'phi', 'psi' } -- column names tab = tab + { 'drift', 0.1, 0.2, 0.5, 0, 0, 0 } -- unnamed array + { name='mq', x=0.2, y=0.4, z=1, theta=0, phi=0, psi=0 } + { name='mb', x=0.3, y=0.5, z=1, theta=0, phi=0, psi=0 } for i=1,1000000 do tab = tab + { 'mq', i*0.5, i*0.6, 1, 0, 0, 0 } -- add a million rows named ‘mq’ end tab.mq[10] = { x=0.3, y=0.5, z=1, theta=0, phi=0, psi=0 } -- full update of the 10th mq print(tab.mq[10].x) -- column x of 10th mq print(tab.x[3]) -- column x of 3rd row = tab.mb.x Ambiguities on names can print(#tab) -- print number of rows using .row, .column and print(#tab.mq) -- print number of mq print(#tab.column) -- print number of columns tab.title = ‘survey’ -- set the table title in the header (dictionary) be resolved by .header access 25 Survey: 3D geometrical tracking (user, details) BE Beams Department ๏ Tracking code for 3D affine maps ๏ Survey module extends the elements from module Element Laurent Deniau, CERN BE/ABP, 1211 Geneva 23, [email protected] ➡ E hereafter refers to the imported module Element within module Survey function E.sbend.survey (elem, m) -- elem is local angle, L = elem.angle, elem.length -- m is local rho, ca, sa = L/angle, cos(angle), sin(angle) local R = vec{rho*(ca-1), 0, rho*sa} local S = mat{{ ca, 0, -sa }, { 0, 1, 0 }, { sa, 0, ca }} local tilt = elem.tilt or 0 if tilt ~= 0 then local ct, st = cos(tilt), sin(tilt) local T = mat{{ ct, -st, 0 }, { st, ct, 0 }, { 0, 0, 1 }} R, S = T*R, T*S*T.t() -- matrix equ. end m.V = m.W * R + m.V -- matrix equ. m.W = m.W * S -- matrix equ. return elem.s_pos + L end the current sbend the tracked “map” As simple and clean as the mad8 physics guide... MAD-X survey: ~600 lines MAD-NG survey: ~100 lines function E.element.survey (elem, m) -- drift local L = elem.length local R = vec{0, 0, L} m.V = m.W * R + m.V -- matrix equ. return elem.s_pos + L end 26 Track: 6D dynamical tracking (user, details) BE Beams Department ๏ Tracking code for 6D dynamical maps ➡ One tracking code to “rule them all” (PTC philosophy) ‣ same code for particles and high order maps (but not same performance...) ๏ Track module extends the elements from module Element Laurent Deniau, CERN BE/ABP, 1211 Geneva 23, [email protected] ➡ E hereafter refers to the imported module Element within module Track function E.multipole.track (elem, m) -- elem is the current multipole local iB0, byt = 1/m.beam.beta0 -- m is the tracked “map” local knl, ksl = elem.knl or {}, elem.ksl or {} local kn0l, ks0l = knl[1] or 0, ksl[1] or 0 local nmul = max(#knl, #ksl) m.by = scalar(m.by or same(m.px), knl[nmul] or 0) m.bx = scalar(m.bx or same(m.py), ksl[nmul] or 0) for j=nmul-1,1,-1 do byt = m.x * m.by - m.y * m.bx + (knl[j] or 0) m.bx = m.y * m.by + m.x * m.bx + (ksl[j] or 0) m.by = byt end m.px = m.px - m.by + kn0l m.py = m.py + m.bx if kn0l ~= 0 or ks0l ~= 0 then m.pz = sqrt( 1 + 2*iB0*m.pt + m.pt^2 ) m.t = m.t + ( kn0l * m.x - ks0l * m.y ) * (iB0 + m.pt) / m.pz end return elem.s_pos function E.element.track (elem, m) -- drift end local L, iB0, T = elem.length, 1/m.beam.beta0, m.total_path m.l_pz = L/sqrt(1 + 2*iB0*m.pt + m.pt^2 - m.px^2 - m.py^2) m.x = m.x + m.px * m.l_pz m.y = m.y + m.py * m.l_pz m.t = m.t + (iB0 + m.pt) * m.l_pz - (1-T)*L*iB0 return elem.s_pos + L end 27 Conclusions BE Beams Department ๏ MAD-NG is a fantastic project (early stage) ➡ True general purpose dynamic scripting language, very expressive ➡ Powerful tool to study, understand and debug the physics (x-checks) ➡ Extremely flexible and efficient, good performance, good ratio progress/resource Laurent Deniau, CERN BE/ABP, 1211 Geneva 23, [email protected] ➡ Very useful for reverse engineering of other codes (e.g. MAD-X) ➡ Unify phase space dimensions, maps orders and tracking methods ➡ Provides few flexible approaches to implement new modules and extensions ➡ Integrated help (man like) and tests (unit tests) per module and function ๏ Next BIG steps (2016-2017) ➡ Finalize the scripting language (simplify and unify the DSL) ➡ Finalize the design of the existing components (simplify and unify the styles) ➡ Integration of components for portability, robustness and benchmark ➡ Implement integrators and maps of MAD-X, PTC and the literature (workhorse) ➡ Implement missing features (modules, elements, algorithms) ➡ Implement high order normal form analysis (E. Forest new book) ➡ Explore new possibilities (GTPSA & Knobs) 28
© Copyright 2026 Paperzz