From 655faa15f262bbb8765c2b611ff4b477036130a0 Mon Sep 17 00:00:00 2001 From: Alexis Pereda Date: Mon, 19 Jul 2021 14:59:37 +0200 Subject: [PATCH] thesis version --- .gitignore | 1 + CMakeLists.txt | 78 + README.md | 101 + UseLATEX.cmake | 2074 ++++++++++++++ .../rt_graspels_qa194_12_20_20_speedup.pdf | Bin 0 -> 8351 bytes .../rt_graspels_qa194_16_20_20_speedup.pdf | Bin 0 -> 8345 bytes .../rt_graspels_qa194_20_20_20_speedup.pdf | Bin 0 -> 9313 bytes img/exec/rt_graspels_qa194_24_20_20_par.pdf | Bin 0 -> 8578 bytes img/exec/rt_graspels_qa194_24_20_20_seq.pdf | Bin 0 -> 7069 bytes .../rt_graspels_qa194_4_20_20_speedup.pdf | Bin 0 -> 9305 bytes .../rt_graspels_qa194_8_20_20_speedup.pdf | Bin 0 -> 9313 bytes img/pfor/ct.pdf | Bin 0 -> 6941 bytes img/pfor/rt_par_1.pdf | Bin 0 -> 9586 bytes img/pfor/rt_par_10.pdf | Bin 0 -> 9583 bytes img/pfor/rt_par_12.pdf | Bin 0 -> 9588 bytes img/pfor/rt_par_14.pdf | Bin 0 -> 9588 bytes img/pfor/rt_par_16.pdf | Bin 0 -> 9591 bytes img/pfor/rt_par_18.pdf | Bin 0 -> 9587 bytes img/pfor/rt_par_2.pdf | Bin 0 -> 9591 bytes img/pfor/rt_par_4.pdf | Bin 0 -> 9583 bytes img/pfor/rt_par_6.pdf | Bin 0 -> 9577 bytes img/pfor/rt_par_8.pdf | Bin 0 -> 9580 bytes img/pfor/rt_seq.pdf | Bin 0 -> 9656 bytes img/repeat/exp_0.pdf | Bin 0 -> 6387 bytes img/repeat/exp_1.pdf | Bin 0 -> 19173 bytes img/repeat/exp_2.pdf | Bin 0 -> 29037 bytes raw/cpplogo.pdf | Bin 0 -> 1673 bytes raw/cpplogo.pdf_tex | 58 + src/acronyms.tex | 80 + src/alg/alsk/grasp.tex | 10 + src/alg/app/els.tex | 20 + src/alg/app/grasp.tex | 10 + src/alg/app/graspels.tex | 10 + src/alg/app/greedy.tex | 12 + src/commands.tex | 4 + src/defense/0_intro.tex | 25 + src/defense/1_context.tex | 5 + src/defense/1_context/0_par.tex | 56 + src/defense/1_context/1_app.tex | 106 + src/defense/1_context/2_mp.tex | 249 ++ src/defense/2_alsk.tex | 6 + src/defense/2_alsk/0_alsk.tex | 154 ++ src/defense/2_alsk/1_exec.tex | 121 + src/defense/2_alsk/2_repeat.tex | 314 +++ src/defense/2_alsk/3_conclusion.tex | 26 + src/defense/3_pfor.tex | 5 + src/defense/3_pfor/0_ctanalysis.tex | 98 + src/defense/3_pfor/1_edsl.tex | 18 + src/defense/3_pfor/2_results.tex | 37 + src/defense/4_conclusion.tex | 59 + src/document.tex | 23 + src/fig/alsk/farmsel.tex | 26 + src/fig/alsk/forkjoin.tex | 23 + src/fig/alsk/grasp.tex | 72 + src/fig/alsk/grasp_links.tex | 54 + src/fig/alsk/grasp_struct.tex | 75 + src/fig/alsk/graspels.tex | 133 + src/fig/alsk/seq.tex | 12 + src/fig/alsk/tree_grasp.tex | 6 + src/fig/app/graspels.tex | 133 + src/fig/app/tspels.tex | 104 + src/fig/app/tspgraspels.tex | 330 +++ src/fig/app/tspgreedysolution.tex | 35 + src/fig/app/tspinstance.tex | 18 + src/fig/app/tspopti.tex | 18 + src/fig/app/tsprp.tex | 9 + src/fig/app/tspsolution.tex | 18 + src/fig/context/farmsel.tex | 26 + src/fig/context/par.tex | 31 + src/fig/context/seq.tex | 31 + src/fig/context/threadpool.tex | 51 + src/fig/exec/firstlevel.tex | 70 + src/fig/exec/firstleveldetails.tex | 76 + src/fig/exec/multilevel.tex | 85 + src/fig/exec/threadpool.tex | 50 + src/fig/mp/et_basic.tex | 7 + src/fig/mp/et_linexpr.tex | 14 + src/fig/mp/et_linexpr_opti0.tex | 11 + src/fig/mp/et_linexpr_opti1.tex | 7 + src/fig/mp/metaprogram.tex | 17 + src/fig/pagemask.tex | 6 + src/fig/pfor/indices.tex | 16 + src/fig/pfor/indices_small.tex | 10 + src/fig/repeat/identify.tex | 92 + src/fig/repeat/par.tex | 63 + src/fig/repeat/prng/par.tex | 28 + src/fig/repeat/prng/parthread.tex | 23 + src/fig/repeat/prng/seq.tex | 18 + src/fig/repeat/seq.tex | 28 + src/lst/alsk/elsbody.tex | 6 + src/lst/alsk/grasp.tex | 13 + src/lst/alsk/grasp_links.tex | 13 + src/lst/alsk/grasp_struct.tex | 12 + src/lst/alsk/graspbody.tex | 6 + src/lst/alsk/graspexec.tex | 11 + src/lst/intro/loop_par.tex | 4 + src/lst/intro/loop_par_hard.tex | 4 + src/lst/intro/loop_seq.tex | 4 + src/lst/mp/cpplogo.tex | 22 + src/lst/mp/edsl_basic.tex | 3 + src/lst/mp/edsl_linexpr.tex | 3 + src/lst/mp/edsl_linexpr_opti.tex | 3 + src/lst/mp/edsl_linexpr_opti0.tex | 3 + src/lst/mp/et.tex | 16 + src/lst/mp/et_basic.tex | 9 + src/lst/mp/et_pattern_lin.tex | 7 + src/lst/mp/et_pattern_mulcstlin.tex | 4 + src/lst/mp/et_pattern_sublinlin.tex | 4 + src/lst/mp/opadd.tex | 6 + src/lst/mp/opmul.tex | 6 + src/lst/mp/pow.ct.asm.tex | 7 + src/lst/mp/pow.ct.call.tex | 4 + src/lst/mp/pow.ct.tex | 11 + src/lst/mp/pow.rt.asm.tex | 12 + src/lst/mp/pow.rt.call.tex | 4 + src/lst/mp/pow.rt.tex | 7 + src/lst/mp/tmptype.tex | 6 + src/lst/mp/tmptype_Foo_256.tex | 5 + src/lst/mp/tmptype_float_3.tex | 5 + src/lst/mp/tmptype_int_5.tex | 5 + src/lst/pfor/indices_small.tex | 4 + src/lst/pfor/loop.tex | 9 + src/lst/pfor/loop_noanim.tex | 9 + src/lst/pfor/loop_par.tex | 13 + src/lst/pfor/loop_pfor.tex | 9 + src/lst/pfor/loop_split.tex | 14 + src/main_default.tex | 11 + src/main_notes.tex | 18 + src/preamble.tex | 168 ++ src/references.bib | 2457 +++++++++++++++++ src/tikz/alsk.tex | 92 + src/tikz/ast.tex | 11 + src/tikz/common.tex | 84 + src/tikz/et.tex | 18 + src/tikz/exec.tex | 21 + src/tikz/mp.tex | 63 + src/tikz/orchestration.tex | 15 + src/tikz/parallel.tex | 27 + src/tikz/repeat.tex | 13 + src/tikz/tsp.tex | 30 + src/usr/alg.tex | 28 + src/usr/beamer.tex | 101 + src/usr/bibstyle.tex | 58 + src/usr/colors.tex | 21 + src/usr/listing.tex | 84 + src/usr/math.tex | 18 + src/usr/ocg.tex | 246 ++ src/usr/silence.tex | 5 + src/usr/tikz.tex | 3 + sty/acref.sty | 132 + 150 files changed, 9593 insertions(+) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 README.md create mode 100644 UseLATEX.cmake create mode 100644 img/exec/rt_graspels_qa194_12_20_20_speedup.pdf create mode 100644 img/exec/rt_graspels_qa194_16_20_20_speedup.pdf create mode 100644 img/exec/rt_graspels_qa194_20_20_20_speedup.pdf create mode 100644 img/exec/rt_graspels_qa194_24_20_20_par.pdf create mode 100644 img/exec/rt_graspels_qa194_24_20_20_seq.pdf create mode 100644 img/exec/rt_graspels_qa194_4_20_20_speedup.pdf create mode 100644 img/exec/rt_graspels_qa194_8_20_20_speedup.pdf create mode 100644 img/pfor/ct.pdf create mode 100644 img/pfor/rt_par_1.pdf create mode 100644 img/pfor/rt_par_10.pdf create mode 100644 img/pfor/rt_par_12.pdf create mode 100644 img/pfor/rt_par_14.pdf create mode 100644 img/pfor/rt_par_16.pdf create mode 100644 img/pfor/rt_par_18.pdf create mode 100644 img/pfor/rt_par_2.pdf create mode 100644 img/pfor/rt_par_4.pdf create mode 100644 img/pfor/rt_par_6.pdf create mode 100644 img/pfor/rt_par_8.pdf create mode 100644 img/pfor/rt_seq.pdf create mode 100644 img/repeat/exp_0.pdf create mode 100644 img/repeat/exp_1.pdf create mode 100644 img/repeat/exp_2.pdf create mode 100644 raw/cpplogo.pdf create mode 100644 raw/cpplogo.pdf_tex create mode 100644 src/acronyms.tex create mode 100644 src/alg/alsk/grasp.tex create mode 100644 src/alg/app/els.tex create mode 100644 src/alg/app/grasp.tex create mode 100644 src/alg/app/graspels.tex create mode 100644 src/alg/app/greedy.tex create mode 100644 src/commands.tex create mode 100644 src/defense/0_intro.tex create mode 100644 src/defense/1_context.tex create mode 100644 src/defense/1_context/0_par.tex create mode 100644 src/defense/1_context/1_app.tex create mode 100644 src/defense/1_context/2_mp.tex create mode 100644 src/defense/2_alsk.tex create mode 100644 src/defense/2_alsk/0_alsk.tex create mode 100644 src/defense/2_alsk/1_exec.tex create mode 100644 src/defense/2_alsk/2_repeat.tex create mode 100644 src/defense/2_alsk/3_conclusion.tex create mode 100644 src/defense/3_pfor.tex create mode 100644 src/defense/3_pfor/0_ctanalysis.tex create mode 100644 src/defense/3_pfor/1_edsl.tex create mode 100644 src/defense/3_pfor/2_results.tex create mode 100644 src/defense/4_conclusion.tex create mode 100644 src/document.tex create mode 100644 src/fig/alsk/farmsel.tex create mode 100644 src/fig/alsk/forkjoin.tex create mode 100644 src/fig/alsk/grasp.tex create mode 100644 src/fig/alsk/grasp_links.tex create mode 100644 src/fig/alsk/grasp_struct.tex create mode 100644 src/fig/alsk/graspels.tex create mode 100644 src/fig/alsk/seq.tex create mode 100644 src/fig/alsk/tree_grasp.tex create mode 100644 src/fig/app/graspels.tex create mode 100644 src/fig/app/tspels.tex create mode 100644 src/fig/app/tspgraspels.tex create mode 100644 src/fig/app/tspgreedysolution.tex create mode 100644 src/fig/app/tspinstance.tex create mode 100644 src/fig/app/tspopti.tex create mode 100644 src/fig/app/tsprp.tex create mode 100644 src/fig/app/tspsolution.tex create mode 100644 src/fig/context/farmsel.tex create mode 100644 src/fig/context/par.tex create mode 100644 src/fig/context/seq.tex create mode 100644 src/fig/context/threadpool.tex create mode 100644 src/fig/exec/firstlevel.tex create mode 100644 src/fig/exec/firstleveldetails.tex create mode 100644 src/fig/exec/multilevel.tex create mode 100644 src/fig/exec/threadpool.tex create mode 100644 src/fig/mp/et_basic.tex create mode 100644 src/fig/mp/et_linexpr.tex create mode 100644 src/fig/mp/et_linexpr_opti0.tex create mode 100644 src/fig/mp/et_linexpr_opti1.tex create mode 100644 src/fig/mp/metaprogram.tex create mode 100644 src/fig/pagemask.tex create mode 100644 src/fig/pfor/indices.tex create mode 100644 src/fig/pfor/indices_small.tex create mode 100644 src/fig/repeat/identify.tex create mode 100644 src/fig/repeat/par.tex create mode 100644 src/fig/repeat/prng/par.tex create mode 100644 src/fig/repeat/prng/parthread.tex create mode 100644 src/fig/repeat/prng/seq.tex create mode 100644 src/fig/repeat/seq.tex create mode 100644 src/lst/alsk/elsbody.tex create mode 100644 src/lst/alsk/grasp.tex create mode 100644 src/lst/alsk/grasp_links.tex create mode 100644 src/lst/alsk/grasp_struct.tex create mode 100644 src/lst/alsk/graspbody.tex create mode 100644 src/lst/alsk/graspexec.tex create mode 100644 src/lst/intro/loop_par.tex create mode 100644 src/lst/intro/loop_par_hard.tex create mode 100644 src/lst/intro/loop_seq.tex create mode 100644 src/lst/mp/cpplogo.tex create mode 100644 src/lst/mp/edsl_basic.tex create mode 100644 src/lst/mp/edsl_linexpr.tex create mode 100644 src/lst/mp/edsl_linexpr_opti.tex create mode 100644 src/lst/mp/edsl_linexpr_opti0.tex create mode 100644 src/lst/mp/et.tex create mode 100644 src/lst/mp/et_basic.tex create mode 100644 src/lst/mp/et_pattern_lin.tex create mode 100644 src/lst/mp/et_pattern_mulcstlin.tex create mode 100644 src/lst/mp/et_pattern_sublinlin.tex create mode 100644 src/lst/mp/opadd.tex create mode 100644 src/lst/mp/opmul.tex create mode 100644 src/lst/mp/pow.ct.asm.tex create mode 100644 src/lst/mp/pow.ct.call.tex create mode 100644 src/lst/mp/pow.ct.tex create mode 100644 src/lst/mp/pow.rt.asm.tex create mode 100644 src/lst/mp/pow.rt.call.tex create mode 100644 src/lst/mp/pow.rt.tex create mode 100644 src/lst/mp/tmptype.tex create mode 100644 src/lst/mp/tmptype_Foo_256.tex create mode 100644 src/lst/mp/tmptype_float_3.tex create mode 100644 src/lst/mp/tmptype_int_5.tex create mode 100644 src/lst/pfor/indices_small.tex create mode 100644 src/lst/pfor/loop.tex create mode 100644 src/lst/pfor/loop_noanim.tex create mode 100644 src/lst/pfor/loop_par.tex create mode 100644 src/lst/pfor/loop_pfor.tex create mode 100644 src/lst/pfor/loop_split.tex create mode 100644 src/main_default.tex create mode 100644 src/main_notes.tex create mode 100644 src/preamble.tex create mode 100644 src/references.bib create mode 100644 src/tikz/alsk.tex create mode 100644 src/tikz/ast.tex create mode 100644 src/tikz/common.tex create mode 100644 src/tikz/et.tex create mode 100644 src/tikz/exec.tex create mode 100644 src/tikz/mp.tex create mode 100644 src/tikz/orchestration.tex create mode 100644 src/tikz/parallel.tex create mode 100644 src/tikz/repeat.tex create mode 100644 src/tikz/tsp.tex create mode 100644 src/usr/alg.tex create mode 100644 src/usr/beamer.tex create mode 100644 src/usr/bibstyle.tex create mode 100644 src/usr/colors.tex create mode 100644 src/usr/listing.tex create mode 100644 src/usr/math.tex create mode 100644 src/usr/ocg.tex create mode 100644 src/usr/silence.tex create mode 100644 src/usr/tikz.tex create mode 100644 sty/acref.sty diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..567609b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +build/ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..4f63e1a --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,78 @@ +cmake_minimum_required(VERSION 3.1) + +project(defense) + +set(LATEX_COMPILER_FLAGS "-interaction=batchmode -file-line-error -shell-escape" + CACHE STRING "Flags passed to latex.") +include(UseLATEX.cmake) + +# Global +set(LATEX_USE_SYNCTEX ON) +set(imgdir img) + +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/pdf) + +# Functions +macro(subdirlist result curdir) + file(GLOB children RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${curdir}/*) + foreach(child ${children}) + if(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${child}) + subdirlist(${result} ${child}) + list(APPEND ${result} ${child}) + endif() + endforeach() +endmacro() + +set(imgdirs ${imgdir}) +subdirlist(imgdirs ${imgdir}) + +# Document +set(modes default notes) +set(srcdir src) +set(stydir sty) + +file(GLOB_RECURSE src RELATIVE ${CMAKE_SOURCE_DIR} ${srcdir}/*.tex) +file(GLOB_RECURSE bib RELATIVE ${CMAKE_SOURCE_DIR} ${srcdir}/*.bib) +file(GLOB_RECURSE sty RELATIVE ${CMAKE_SOURCE_DIR} ${stydir}/*.sty) +set(other_in raw/cpplogo.pdf_tex raw/cpplogo.pdf) + +set(latex_document_options) +set(custom_command_options ALL) + +foreach(mode ${modes}) + set(maintex main_${mode}) + + execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink + ${CMAKE_CURRENT_BINARY_DIR}/${srcdir}/${maintex}.tex + ${CMAKE_CURRENT_BINARY_DIR}/${maintex}.tex + ) + + add_latex_document( + ${srcdir}/main_${mode}.tex + INPUTS ${src} ${lst} ${sty} ${other_in} + # BIBFILES ${bib} + IMAGE_DIRS ${imgdirs} + # USE_BIBLATEX + # USE_GLOSSARY + ${latex_document_options} + ) + + if(NOT ${mode} STREQUAL genfigures) + set(synctex_file ${CMAKE_PROJECT_NAME}_${mode}.synctex.gz) + add_custom_target(pdf_${synctex_file} ${custom_command_options} + DEPENDS ${maintex}.pdf + COMMAND ${CMAKE_COMMAND} -E copy ${maintex}.synctex.gz pdf/${synctex_file} + ) + + set(pdf_file ${CMAKE_PROJECT_NAME}_${mode}.pdf) + add_custom_target(pdf_${pdf_file} ${custom_command_options} + DEPENDS ${maintex}.pdf + COMMAND ${CMAKE_COMMAND} -E copy ${maintex}.pdf pdf/${pdf_file} + ) + + add_custom_target(pdf_${CMAKE_PROJECT_NAME}_${mode} DEPENDS pdf_${synctex_file} pdf_${pdf_file}) + endif() + + set(latex_document_options EXCLUDE_FROM_ALL) + set(custom_command_options) +endforeach() diff --git a/README.md b/README.md new file mode 100644 index 0000000..6d97a43 --- /dev/null +++ b/README.md @@ -0,0 +1,101 @@ +# About + +Thesis title: using template metaprogramming to design active libraries for assisted parallelisation. + +(French: *application de la métaprogrammation template à la conception de bibliothèques actives +de parallélisation assitée*) + +## Download + +- [Slides](https://phd.pereda.fr/assets/thesis/alexis_pereda_defense.pdf). + +## Abstract + +
+Hardware performance has been increasing through the addition of computing cores rather than through +increasing their frequency since the early 2000s. +This means that parallel programming is no longer optional should you need to make the best use of +the hardware at your disposal. +Yet many programs are still written sequentially: parallel programming introduces numerous +difficulties. +Amongst these, it is notably hard to determine whether a sequence of a program can be executed in +parallel, i.e. preserving its behaviour as well as its overall result. +Even knowing that it is possible to parallelise a piece of code, doing it correctly is another +problem. +In this thesis, we present two approaches to make writing parallel software easier. + +We present an active library (using C++ template metaprogramming to operate during the compilation +process) whose purpose is to analyse and parallelise loops. +To do so, it builds a representation of each processed loop using expression templates through an +embedded language. +This allows to know which variables are used and how they are used. +For the case of arrays, which are common within loops, it also acquires the index functions. +The analysis of this information enables the library to identify which instructions in the loop can +be run in parallel. +Interdependent instructions are detected by knowing the variables and their access mode for each +instruction. +Given a group of interdependent instructions and the known index functions, the library decides if +the instructions can be run in parallel or not. +We want this library to help developers writing loops that will be automatically parallelised +whenever possible and run sequentially as without the library otherwise. +Another focus is to provide this to serve as a framework to integrate new methods for parallelising +programs and extended analysis rules. + +We introduce another active library that aims to help developers by assisting them in writing +parallel software instead of fully automating it. +This library uses algorithmic skeletons to let the developer describe its algorithms with both its +sequential and parallel parts by assembling atomic execution patterns such as a series of tasks or a +parallel execution of a repeated task. +This description includes the data flow, that is how parameters and function returns are +transmitted. +Usually, this is automatically set by the algorithmic skeleton library, however it gives the +developer greater flexibility and it makes it possible, amongst other things, for our library to +automatically transmit special parameters that must not be shared between parallel tasks. +One feature that this allows is to ensure repeatability from one execution to another even for +stochastic algorithms. +Considering the distribution of tasks on the different cores, we even reduce the number of these +non-shared parameters. +Once again, this library provides a framework at several levels. +Low-level extensions consist of the implementation of new execution patterns to be used to build +skeletons. +Another low-level axis is the integration of new execution policies that decide how tasks are +distributed on the available computing cores. +High-level additions will be libraries using ours to offer ready-to-use algorithmic skeletons for +various fields. +
+ +Keywords: template metaprogramming; assisted parallelisation; automatic parallelisation; active libraries; algorithmic skeletons; repeatability. + +## Related publications + +- "Repeatability with Random Numbers Using Algorithmic Skeletons", ESM 2020 (https://hal.archives-ouvertes.fr/hal-02980472); +- "Modeling Algorithmic Skeletons for Automatic Parallelization Using Template Metaprogramming", HPCS 2019 (IEEE) [10.1109/HPCS48598.2019.9188128](https://doi.org/10.1109/HPCS48598.2019.9188128); +- "Processing Algorithmic Skeletons at Compile-Time", ROADEF 2020 (https://hal.archives-ouvertes.fr/hal-02573660); +- "Algorithmic Skeletons Using Template Metaprogramming", ICAST 2019; +- "Parallel Algorithmic Skeletons for Metaheuristics", ROADEF 2019 (https://hal.archives-ouvertes.fr/hal-02059533); +- "Static Loop Parallelization Decision Using Template Metaprogramming", HPCS 2018 (IEEE) [10.1109/HPCS.2018.00159](https://doi.org/10.1109/HPCS.2018.00159). + +## Related projects + +- [AlSk](https://phd.pereda.fr/dev/alsk), an algorithmic skeletons active library; +- [pfor](https://phd.pereda.fr/dev/pfor), an automatic parallelisation active library; +- [ROSA](https://phd.pereda.fr/dev/rosa), an algorithmic skeletons collection for [OR](https://en.wikipedia.org/wiki/Operations_research) algorithms; +- [TMP](https://phd.pereda.fr/dev/tmp), template metaprogramming library used to implement this library. + +## Usage + +To produce the `Makefile`: +```bash +mkdir build +cd build +cmake .. +``` + +Compilation has been tested with `texlive-full` version 2020.20210202-3. + +To build the project: +``` +make +``` + +PDF files are generated in `build/pdf/`. diff --git a/UseLATEX.cmake b/UseLATEX.cmake new file mode 100644 index 0000000..bb1fd9e --- /dev/null +++ b/UseLATEX.cmake @@ -0,0 +1,2074 @@ +# File: UseLATEX.cmake +# CMAKE commands to actually use the LaTeX compiler +# Version: 2.7.0 +# Author: Kenneth Moreland +# +# Copyright 2004, 2015 Sandia Corporation. +# Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive +# license for use of this work by or on behalf of the U.S. Government. +# +# This software is released under the BSD 3-Clause License. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from this +# software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# +# The following function is defined: +# +# add_latex_document( +# [BIBFILES ] +# [INPUTS ] +# [IMAGE_DIRS ] +# [IMAGES ] +# [CONFIGURE ] +# [DEPENDS ] +# [MULTIBIB_NEWCITES ] +# [USE_BIBLATEX] +# [USE_INDEX] +# [INDEX_NAMES ] +# [USE_GLOSSARY] [USE_NOMENCL] +# [FORCE_PDF] [FORCE_DVI] [FORCE_HTML] +# [TARGET_NAME ] +# [INCLUDE_DIRECTORIES ] +# [EXCLUDE_FROM_ALL] +# [EXCLUDE_FROM_DEFAULTS]) +# Adds targets that compile . The latex output is placed +# in LATEX_OUTPUT_PATH or CMAKE_CURRENT_BINARY_DIR if the former is +# not set. The latex program is picky about where files are located, +# so all input files are copied from the source directory to the +# output directory. This includes the target tex file, any tex file +# listed with the INPUTS option, the bibliography files listed with +# the BIBFILES option, and any .cls, .bst, .clo, .sty, .ist, and .fd +# files found in the current source directory. Images found in the +# IMAGE_DIRS directories or listed by IMAGES are also copied to the +# output directory and converted to an appropriate format if necessary. +# Any tex files also listed with the CONFIGURE option are also processed +# with the CMake CONFIGURE_FILE command (with the @ONLY flag). Any file +# listed in CONFIGURE but not the target tex file or listed with INPUTS +# has no effect. DEPENDS can be used to specify generated files that are +# needed to compile the latex target. +# +# The following targets are made. The name prefix is based off of the +# base name of the tex file unless TARGET_NAME is specified. If +# TARGET_NAME is specified, then that name is used for the targets. +# +# name_dvi: Makes .dvi +# name_pdf: Makes .pdf using pdflatex. +# name_safepdf: Makes .pdf using ps2pdf. If using the +# default program arguments, this will ensure all fonts +# are embedded and no lossy compression has been +# performed on images. +# name_ps: Makes .ps +# name_html: Makes .html +# name_auxclean: Deletes .aux and other auxiliary files. +# This is sometimes necessary if a LaTeX error occurs +# and writes a bad aux file. Unlike the regular clean +# target, it does not delete other input files, such as +# converted images, to save time on the rebuild. +# +# Unless the EXCLUDE_FROM_ALL option is given, one of these targets +# is added to the ALL target and built by default. Which target is +# determined by the LATEX_DEFAULT_BUILD CMake variable. See the +# documentation of that variable for more details. +# +# Unless the EXCLUDE_FROM_DEFAULTS option is given, all these targets +# are added as dependencies to targets named dvi, pdf, safepdf, ps, +# html, and auxclean, respectively. +# +# USE_BIBLATEX enables the use of biblatex/biber as an alternative to +# bibtex. Bibtex remains the default if USE_BIBLATEX is not +# specified. +# +# If the argument USE_INDEX is given, then commands to build an index +# are made. If the argument INDEX_NAMES is given, an index file is +# generated for each name in this list. See the LaTeX package multind +# for more information about how to generate multiple indices. +# +# If the argument USE_GLOSSARY is given, then commands to +# build a glossary are made. If the argument MULTIBIB_NEWCITES is +# given, then additional bibtex calls are added to the build to +# support the extra auxiliary files created with the \newcite command +# in the multibib package. +# +# INCLUDE_DIRECTORIES provides a list of directories in which LaTeX +# should look for input files. It accepts both files relative to the +# binary directory and absolute paths. +# +# History: +# +# 2.7.0 Add INCLUDE_DIRECTORIES parameters. (Thanks to Eric Dönges.) +# +# 2.6.1 Fix issue with detecting long undefined reference warnings that +# LaTeX "helpfully" split across lines (and which fowled up our +# regex). +# +# 2.6.0 Skip image conversion targets that are not used when a force option +# is given. This helps prevent errors for missing conversion programs +# that are not needed. (Thanks to Martin Wetzel.) +# +# 2.5.0 Parse biber output for warnings. +# +# For regular bibtex, you get warnings about undefined references +# when you run latex. However, when using biber, biber itself prints +# out the said warning and latex sees nothing. Thus, when using biber +# the regular output is now suppressed and the log file is scanned +# for potential issues. +# +# 2.4.9 Use biblatex.cfg file if it exists and the USE_BIBLATEX option is ON. +# +# 2.4.8 Fix synctex issue with absolute paths not being converted. +# +# 2.4.7 Fix some issues with spaces in the path of the working directory where +# LaTeX is executed. +# +# 2.4.6 Fix parse issue with older versions of CMake. +# +# 2.4.5 Fix issues with files and paths containing spaces. +# +# 2.4.4 Improve error reporting message when LaTeX fails. +# +# When LaTeX fails, delete the output file, which is invalid. +# +# Add warnings for "missing characters." These usually mean that a +# non-ASCII character is in the document and will not be printed +# correctly. +# +# 2.4.3 Check for warnings from the natbib package. When using natbib, +# warnings for missing bibliography references look different. So +# far, natbib seems to be quiet unless something is important, so +# look for all natbib warnings. (We can change this later if +# necessary.) +# +# 2.4.2 Fix an issue where new versions of ImageMagick expect the order of +# options in command line execution of magick/convert. (See, for +# example, http://www.imagemagick.org/Usage/basics/#why.) +# +# 2.4.1 Add ability to dump LaTeX log file when using batch mode. Batch +# mode suppresses most output, often including error messages. To +# make sure critical error messages get displayed, show the full log +# on failures. +# +# 2.4.0 Remove "-r 600" from the default PDFTOPS_CONVERTER_FLAGS. The -r flag +# is available from the Poppler version of pdftops, but not the Xpdf +# version. +# +# Fix an issue with the flags for the different programs not being +# properly separated. +# +# Fix an issue on windows where the = character is not allowed for +# ps2pdf arguments. +# +# Change default arguments for latex and pdflatex commands. Makes the +# output more quiet and prints out the file/line where errors occur. +# (Thanks to Nikos Koukis.) +# +# After a LaTeX build, check the log file for warnings that are +# indicative of problems with the build. +# +# Remove support for latex2html. Instead, use the htlatex program. +# This is now part of TeX Live and most other distributions. It also +# behaves much more like the other LaTeX programs. Also fixed some +# nasty issues with the htlatex arguments. +# +# 2.3.2 Declare LaTeX input files as sources for targets so that they show +# up in IDEs like QtCreator. +# +# Fix issue where main tex files in subdirectories were creating +# invalid targets for building HTML. Just disable the HTML targets in +# this case. +# +# 2.3.1 Support use of magick command instead of convert command for +# ImageMagick 7. +# +# 2.3.0 Add USE_BIBLATEX option to support the biblatex package, which +# requires using the program biber as a replacement for bibtex +# (thanks to David Tracey). +# +# 2.2.1 Add STRINGS property to LATEX_DEFAULT_BUILD to make it easier to +# select the default build in the CMake GUI. +# +# 2.2.0 Add TARGET_NAME option. +# +# 2.1.1 Support for finding bmp, ppm, and other image files. +# +# 2.1.0 Fix an error where the pdf target and others were defined multiple +# times if UseLATEX.cmake was included multiple times. +# +# Added INDEX_NAMES option to support multiple indexes in a single +# document from the multind package (thanks to Dan Lipsa). +# +# 2.0.0 First major revision of UseLATEX.cmake updates to more recent features +# of CMake and some non-backward compatible changes. +# +# Changed all function and macro names to lower case. CMake's identifiers +# are case insensitive, but the convention moved from all upper case to +# all lower case somewhere around the release of CMake 2. (The original +# version of UseLATEX.cmake predates that.) +# +# Remove condition matching in if statements. They are no longer necessary +# and are even discouraged (because else clauses get confusing). +# +# Use "new" features available in CMake such as list and argument parsing. +# +# Remove some code that has been deprecated for a while. +# +# Mark variables for compiler and converter executables as advanced to +# match the more conventional CMake behavior. +# +# Changed how default builds are specified and add the ability to force +# a particular build. +# +# Made the base targets (pdf, dvi, etc.) global. add_latex_document +# always mangles its target names and these base targets depend on +# the targets with mangled names. +# +# 1.10.5 Fix for Window's convert check (thanks to Martin Baute). +# +# 1.10.4 Copy font files to binary directory for packages that come with +# their own fonts. +# +# 1.10.3 Check for Windows version of convert being used instead of +# ImageMagick's version (thanks to Martin Baute). +# +# 1.10.2 Use htlatex as a fallback when latex2html is not available (thanks +# to Tomasz Grzegurzko). +# +# 1.10.1 Make convert program mandatory only if actually used (thanks to +# Julien Schueller). +# +# 1.10.0 Added NO_DEFAULT and DEFAULT_PS options. +# Fixed issue with cleaning files for LaTeX documents originating in +# a subdirectory. +# +# 1.9.6 Fixed problem with LATEX_SMALL_IMAGES. +# Strengthened check to make sure the output directory does not contain +# the source files. +# +# 1.9.5 Add support for image types not directly supported by either latex +# or pdflatex. (Thanks to Jorge Gerardo Pena Pastor for SVG support.) +# +# 1.9.4 Fix issues with filenames containing multiple periods. +# +# 1.9.3 Hide some variables that are now cached but should not show up in +# the ccmake list of variables. +# +# 1.9.2 Changed MACRO declarations to FUNCTION declarations. The better +# FUNCTION scoping will hopefully avoid some common but subtle bugs. +# This implicitly increases the minimum CMake version to 4.6 (although +# I honestly only test it with the latest 4.8 version). +# +# Since we are updating the minimum CMake version, I'm going to start +# using the builtin LIST commands that are now available. +# +# Favor using pdftops from the Poppler package to convert from pdf to +# eps. It does a much better job than ImageMagick or ghostscript. +# +# 1.9.1 Fixed typo that caused the LATEX_SMALL_IMAGES option to fail to +# activate. +# +# 1.9.0 Add support for the multibib package (thanks to Antonio LaTorre). +# +# 1.8.2 Fix corner case when an argument name was also a variable containing +# the text of an argument. In this case, the CMake IF was matching +# the argument text with the contents of the variable with the same +# argument name. +# +# 1.8.1 Fix problem where ps2pdf was not getting the appropriate arguments. +# +# 1.8.0 Add support for synctex. +# +# 1.7.7 Support calling xindy when making glossaries. +# +# Improved make clean support. +# +# 1.7.6 Add support for the nomencl package (thanks to Myles English). +# +# 1.7.5 Fix issue with bibfiles being copied two different ways, which causes +# Problems with dependencies (thanks to Edwin van Leeuwen). +# +# 1.7.4 Added the DEFAULT_SAFEPDF option (thanks to Raymond Wan). +# +# Added warnings when image directories are not found (and were +# probably not given relative to the source directory). +# +# 1.7.3 Fix some issues with interactions between makeglossaries and bibtex +# (thanks to Mark de Wever). +# +# 1.7.2 Use ps2pdf to convert eps to pdf to get around the problem with +# ImageMagick dropping the bounding box (thanks to Lukasz Lis). +# +# 1.7.1 Fixed some dependency issues. +# +# 1.7.0 Added DEPENDS options (thanks to Theodore Papadopoulo). +# +# 1.6.1 Ported the makeglossaries command to CMake and embedded the port +# into UseLATEX.cmake. +# +# 1.6.0 Allow the use of the makeglossaries command. Thanks to Oystein +# S. Haaland for the patch. +# +# 1.5.0 Allow any type of file in the INPUTS lists, not just tex file +# (suggested by Eric Noulard). As a consequence, the ability to +# specify tex files without the .tex extension is removed. The removed +# function is of dubious value anyway. +# +# When copying input files, skip over any file that exists in the +# binary directory but does not exist in the source directory with the +# assumption that these files were added by some other mechanism. I +# find this useful when creating large documents with multiple +# chapters that I want to build separately (for speed) as I work on +# them. I use the same boilerplate as the starting point for all +# and just copy it with different configurations. This was what the +# separate ADD_LATEX_DOCUMENT method was supposed to originally be for. +# Since its external use is pretty much deprecated, I removed that +# documentation. +# +# 1.4.1 Copy .sty files along with the other class and package files. +# +# 1.4.0 Added a MANGLE_TARGET_NAMES option that will mangle the target names. +# +# Fixed problem with copying bib files that became apparent with +# CMake 2.4. +# +# 1.3.0 Added a LATEX_OUTPUT_PATH variable that allows you or the user to +# specify where the built latex documents to go. This is especially +# handy if you want to do in-source builds. +# +# Removed the ADD_LATEX_IMAGES macro and absorbed the functionality +# into ADD_LATEX_DOCUMENT. The old interface was always kind of +# clunky anyway since you had to specify the image directory in both +# places. It also made supporting LATEX_OUTPUT_PATH problematic. +# +# Added support for jpeg files. +# +# 1.2.0 Changed the configuration options yet again. Removed the NO_CONFIGURE +# Replaced it with a CONFIGURE option that lists input files for which +# configure should be run. +# +# The pdf target no longer depends on the dvi target. This allows you +# to build latex documents that require pdflatex. Also added an option +# to make the pdf target the default one. +# +# 1.1.1 Added the NO_CONFIGURE option. The @ character can be used when +# specifying table column separators. If two or more are used, then +# will incorrectly substitute them. +# +# 1.1.0 Added ability include multiple bib files. Added ability to do copy +# sub-tex files for multipart tex files. +# +# 1.0.0 If both ps and pdf type images exist, just copy the one that +# matches the current render mode. Replaced a bunch of STRING +# commands with GET_FILENAME_COMPONENT commands that were made to do +# the desired function. +# +# 0.4.0 First version posted to CMake Wiki. +# + +if(__USE_LATEX_INCLUDED) + return() +endif() +set(__USE_LATEX_INCLUDED TRUE) + +############################################################################# +# Find the location of myself while originally executing. If you do this +# inside of a macro, it will recode where the macro was invoked. +############################################################################# +set(LATEX_USE_LATEX_LOCATION ${CMAKE_CURRENT_LIST_FILE} + CACHE INTERNAL "Location of UseLATEX.cmake file." FORCE + ) + +############################################################################# +# Generic helper functions +############################################################################# + +include(CMakeParseArguments) + +function(latex_list_contains var value) + set(input_list ${ARGN}) + list(FIND input_list "${value}" index) + if(index GREATER -1) + set(${var} TRUE PARENT_SCOPE) + else() + set(${var} PARENT_SCOPE) + endif() +endfunction(latex_list_contains) + +# Match the contents of a file to a regular expression. +function(latex_file_match variable filename regexp default) + # The FILE STRINGS command would be a bit better, but I'm not totally sure + # the match will always be to a whole line, and I don't want to break things. + file(READ ${filename} file_contents) + string(REGEX MATCHALL "${regexp}" + match_result ${file_contents} + ) + if(match_result) + set(${variable} "${match_result}" PARENT_SCOPE) + else() + set(${variable} "${default}" PARENT_SCOPE) + endif() +endfunction(latex_file_match) + +# A version of GET_FILENAME_COMPONENT that treats extensions after the last +# period rather than the first. To the best of my knowledge, all filenames +# typically used by LaTeX, including image files, have small extensions +# after the last dot. +function(latex_get_filename_component varname filename type) + set(result) + if("${type}" STREQUAL "NAME_WE") + get_filename_component(name ${filename} NAME) + string(REGEX REPLACE "\\.[^.]*\$" "" result "${name}") + elseif("${type}" STREQUAL "EXT") + get_filename_component(name ${filename} NAME) + string(REGEX MATCH "\\.[^.]*\$" result "${name}") + else() + get_filename_component(result ${filename} ${type}) + endif() + set(${varname} "${result}" PARENT_SCOPE) +endfunction(latex_get_filename_component) + +############################################################################# +# Functions that perform processing during a LaTeX build. +############################################################################# +function(latex_execute_latex) + if(NOT LATEX_WORKING_DIRECTORY) + message(SEND_ERROR "Need to define LATEX_WORKING_DIRECTORY") + endif() + + if(NOT LATEX_FULL_COMMAND) + message(SEND_ERROR "Need to define LATEX_FULL_COMMAND") + endif() + + if(NOT LATEX_OUTPUT_FILE) + message(SEND_ERROR "Need to define LATEX_OUTPUT_FILE") + endif() + + if(NOT LATEX_LOG_FILE) + message(SEND_ERROR "Need to define LATEX_LOG_FILE") + endif() + + set(full_command_original "${LATEX_FULL_COMMAND}") + + # Chose the native method for parsing command arguments. Newer versions of + # CMake allow you to just use NATIVE_COMMAND. + if (CMAKE_VERSION VERSION_GREATER 3.8) + set(separate_arguments_mode NATIVE_COMMAND) + else() + if (WIN32) + set(separate_arguments_mode WINDOWS_COMMAND) + else() + set(separate_arguments_mode UNIX_COMMAND) + endif() + endif() + + # Preps variables for use in execute_process. + # Even though we expect LATEX_WORKING_DIRECTORY to have a single "argument," + # we also want to make sure that we strip out any escape characters that can + # foul up the WORKING_DIRECTORY argument. + separate_arguments(LATEX_FULL_COMMAND UNIX_COMMAND "${LATEX_FULL_COMMAND}") + separate_arguments(LATEX_WORKING_DIRECTORY_SEP UNIX_COMMAND "${LATEX_WORKING_DIRECTORY}") + + execute_process( + COMMAND ${LATEX_FULL_COMMAND} + WORKING_DIRECTORY "${LATEX_WORKING_DIRECTORY_SEP}" + RESULT_VARIABLE execute_result + OUTPUT_VARIABLE ignore + ERROR_VARIABLE ignore + ) + + if(NOT ${execute_result} EQUAL 0) + # LaTeX tends to write a file when a failure happens. Delete that file so + # that LaTeX will run again. + file(REMOVE "${LATEX_WORKING_DIRECTORY}/${LATEX_OUTPUT_FILE}") + + message("\n\nLaTeX command failed") + message("${full_command_original}") + message("Log output:") + file(READ "${LATEX_WORKING_DIRECTORY}/${LATEX_LOG_FILE}" log_output) + message("${log_output}") + message(FATAL_ERROR "Executed LaTeX, but LaTeX returned an error.") + endif() +endfunction(latex_execute_latex) + +function(latex_makeglossaries) + # This is really a bare bones port of the makeglossaries perl script into + # CMake scripting. + message("**************************** In makeglossaries") + if(NOT LATEX_TARGET) + message(SEND_ERROR "Need to define LATEX_TARGET") + endif() + + set(aux_file ${LATEX_TARGET}.aux) + + if(NOT EXISTS ${aux_file}) + message(SEND_ERROR "${aux_file} does not exist. Run latex on your target file.") + endif() + + latex_file_match(newglossary_lines ${aux_file} + "@newglossary[ \t]*{([^}]*)}{([^}]*)}{([^}]*)}{([^}]*)}" + "@newglossary{main}{glg}{gls}{glo}" + ) + + latex_file_match(istfile_line ${aux_file} + "@istfilename[ \t]*{([^}]*)}" + "@istfilename{${LATEX_TARGET}.ist}" + ) + string(REGEX REPLACE "@istfilename[ \t]*{([^}]*)}" "\\1" + istfile ${istfile_line} + ) + + string(REGEX MATCH ".*\\.xdy" use_xindy "${istfile}") + if(use_xindy) + message("*************** Using xindy") + if(NOT XINDY_COMPILER) + message(SEND_ERROR "Need to define XINDY_COMPILER") + endif() + else() + message("*************** Using makeindex") + if(NOT MAKEINDEX_COMPILER) + message(SEND_ERROR "Need to define MAKEINDEX_COMPILER") + endif() + endif() + + foreach(newglossary ${newglossary_lines}) + string(REGEX REPLACE + "@newglossary[ \t]*{([^}]*)}{([^}]*)}{([^}]*)}{([^}]*)}" + "\\1" glossary_name ${newglossary} + ) + string(REGEX REPLACE + "@newglossary[ \t]*{([^}]*)}{([^}]*)}{([^}]*)}{([^}]*)}" + "${LATEX_TARGET}.\\2" glossary_log ${newglossary} + ) + string(REGEX REPLACE + "@newglossary[ \t]*{([^}]*)}{([^}]*)}{([^}]*)}{([^}]*)}" + "${LATEX_TARGET}.\\3" glossary_out ${newglossary} + ) + string(REGEX REPLACE + "@newglossary[ \t]*{([^}]*)}{([^}]*)}{([^}]*)}{([^}]*)}" + "${LATEX_TARGET}.\\4" glossary_in ${newglossary} + ) + + if(use_xindy) + latex_file_match(xdylanguage_line ${aux_file} + "@xdylanguage[ \t]*{${glossary_name}}{([^}]*)}" + "@xdylanguage{${glossary_name}}{english}" + ) + string(REGEX REPLACE + "@xdylanguage[ \t]*{${glossary_name}}{([^}]*)}" + "\\1" + language + ${xdylanguage_line} + ) + # What crazy person makes a LaTeX index generator that uses different + # identifiers for language than babel (or at least does not support + # the old ones)? + if(${language} STREQUAL "frenchb") + set(language "french") + elseif(${language} MATCHES "^n?germanb?$") + set(language "german") + elseif(${language} STREQUAL "magyar") + set(language "hungarian") + elseif(${language} STREQUAL "lsorbian") + set(language "lower-sorbian") + elseif(${language} STREQUAL "norsk") + set(language "norwegian") + elseif(${language} STREQUAL "portuges") + set(language "portuguese") + elseif(${language} STREQUAL "russianb") + set(language "russian") + elseif(${language} STREQUAL "slovene") + set(language "slovenian") + elseif(${language} STREQUAL "ukraineb") + set(language "ukrainian") + elseif(${language} STREQUAL "usorbian") + set(language "upper-sorbian") + endif() + if(language) + set(language_flags "-L ${language}") + else() + set(language_flags "") + endif() + + latex_file_match(codepage_line ${aux_file} + "@gls@codepage[ \t]*{${glossary_name}}{([^}]*)}" + "@gls@codepage{${glossary_name}}{utf}" + ) + string(REGEX REPLACE + "@gls@codepage[ \t]*{${glossary_name}}{([^}]*)}" + "\\1" + codepage + ${codepage_line} + ) + if(codepage) + set(codepage_flags "-C ${codepage}") + else() + # Ideally, we would check that the language is compatible with the + # default codepage, but I'm hoping that distributions will be smart + # enough to specify their own codepage. I know, it's asking a lot. + set(codepage_flags "") + endif() + + message("${XINDY_COMPILER} ${MAKEGLOSSARIES_COMPILER_ARGS} ${language_flags} ${codepage_flags} -I xindy -M ${glossary_name} -t ${glossary_log} -o ${glossary_out} ${glossary_in}" + ) + exec_program(${XINDY_COMPILER} + ARGS ${MAKEGLOSSARIES_COMPILER_ARGS} + ${language_flags} + ${codepage_flags} + -I xindy + -M ${glossary_name} + -t ${glossary_log} + -o ${glossary_out} + ${glossary_in} + OUTPUT_VARIABLE xindy_output + ) + message("${xindy_output}") + + # So, it is possible (perhaps common?) for aux files to specify a + # language and codepage that are incompatible with each other. Check + # for that condition, and if it happens run again with the default + # codepage. + if("${xindy_output}" MATCHES "^Cannot locate xindy module for language (.+) in codepage (.+)\\.$") + message("*************** Retrying xindy with default codepage.") + exec_program(${XINDY_COMPILER} + ARGS ${MAKEGLOSSARIES_COMPILER_ARGS} + ${language_flags} + -I xindy + -M ${glossary_name} + -t ${glossary_log} + -o ${glossary_out} + ${glossary_in} + ) + endif() + + else() + message("${MAKEINDEX_COMPILER} ${MAKEGLOSSARIES_COMPILER_ARGS} -s ${istfile} -t ${glossary_log} -o ${glossary_out} ${glossary_in}") + exec_program(${MAKEINDEX_COMPILER} ARGS ${MAKEGLOSSARIES_COMPILER_ARGS} + -s ${istfile} -t ${glossary_log} -o ${glossary_out} ${glossary_in} + ) + endif() + + endforeach(newglossary) +endfunction(latex_makeglossaries) + +function(latex_makenomenclature) + message("**************************** In makenomenclature") + if(NOT LATEX_TARGET) + message(SEND_ERROR "Need to define LATEX_TARGET") + endif() + + if(NOT MAKEINDEX_COMPILER) + message(SEND_ERROR "Need to define MAKEINDEX_COMPILER") + endif() + + set(nomencl_out ${LATEX_TARGET}.nls) + set(nomencl_in ${LATEX_TARGET}.nlo) + + exec_program(${MAKEINDEX_COMPILER} ARGS ${MAKENOMENCLATURE_COMPILER_ARGS} + ${nomencl_in} -s "nomencl.ist" -o ${nomencl_out} + ) +endfunction(latex_makenomenclature) + +function(latex_correct_synctex) + message("**************************** In correct SyncTeX") + if(NOT LATEX_TARGET) + message(SEND_ERROR "Need to define LATEX_TARGET") + endif() + + if(NOT GZIP) + message(SEND_ERROR "Need to define GZIP") + endif() + + if(NOT LATEX_SOURCE_DIRECTORY) + message(SEND_ERROR "Need to define LATEX_SOURCE_DIRECTORY") + endif() + + if(NOT LATEX_BINARY_DIRECTORY) + message(SEND_ERROR "Need to define LATEX_BINARY_DIRECTORY") + endif() + message("${LATEX_BINARY_DIRECTORY}") + message("${LATEX_SOURCE_DIRECTORY}") + + set(synctex_file ${LATEX_BINARY_DIRECTORY}/${LATEX_TARGET}.synctex) + set(synctex_file_gz ${synctex_file}.gz) + + if(EXISTS ${synctex_file_gz}) + + message("Making backup of synctex file.") + configure_file(${synctex_file_gz} ${synctex_file}.bak.gz COPYONLY) + + message("Uncompressing synctex file.") + exec_program(${GZIP} + ARGS --decompress ${synctex_file_gz} + ) + + message("Reading synctex file.") + file(READ ${synctex_file} synctex_data) + + message("Replacing output paths with input paths.") + foreach(extension tex cls bst clo sty ist fd) + # Relative paths + string(REGEX REPLACE + "(Input:[0-9]+:)([^/\n][^\n]\\.${extension}*)" + "\\1${LATEX_SOURCE_DIRECTORY}/\\2" + synctex_data + "${synctex_data}" + ) + + # Absolute paths + string(REGEX REPLACE + "(Input:[0-9]+:)${LATEX_BINARY_DIRECTORY}([^\n]*\\.${extension})" + "\\1${LATEX_SOURCE_DIRECTORY}\\2" + synctex_data + "${synctex_data}" + ) + endforeach(extension) + + message("Writing synctex file.") + file(WRITE ${synctex_file} "${synctex_data}") + + message("Compressing synctex file.") + exec_program(${GZIP} + ARGS ${synctex_file} + ) + + else() + + message(SEND_ERROR "File ${synctex_file_gz} not found. Perhaps synctex is not supported by your LaTeX compiler.") + + endif() + +endfunction(latex_correct_synctex) + +function(latex_check_important_warnings) + # Check for biber warnings/errors if that was run + set(bib_log_file ${LATEX_TARGET}.blg) + if(EXISTS ${bib_log_file}) + file(READ ${bib_log_file} bib_log) + if(bib_log MATCHES "INFO - This is Biber") + message("\nChecking ${bib_log_file} for Biber warnings/errors.") + + string(REGEX MATCHALL + "[A-Z]+ - [^\n]*" + biber_messages + "${bib_log}") + + set(found_error) + foreach(message ${biber_messages}) + if(NOT message MATCHES "^INFO - ") + set(found_error TRUE) + message("${message}") + endif() + endforeach(message) + + if(found_error) + latex_get_filename_component(log_file_path ${bib_log_file} ABSOLUTE) + message("\nConsult ${log_file_path} for more information on Biber output.") + else() + message("No known important Biber output found.") + endif(found_error) + else() # Biber output not in log file + message("Skipping biber checks (biber not used)") + endif() + else() # No bib log file + message("Skipping bibliography checks (not run)") + endif() + + set(log_file ${LATEX_TARGET}.log) + + message("\nChecking ${log_file} for important warnings.") + if(NOT LATEX_TARGET) + message(SEND_ERROR "Need to define LATEX_TARGET") + endif() + + if(NOT EXISTS ${log_file}) + message("Could not find log file: ${log_file}") + return() + endif() + + set(found_error) + + file(READ ${log_file} log) + + # Check for declared LaTeX warnings + string(REGEX MATCHALL + "\nLaTeX Warning:[^\n]*" + latex_warnings + "${log}") + if(latex_warnings) + set(found_error TRUE) + message("\nFound declared LaTeX warnings.") + foreach(warning ${latex_warnings}) + string(STRIP "${warning}" warning_no_newline) + message("${warning_no_newline}") + endforeach(warning) + endif() + + # Check for natbib warnings + string(REGEX MATCHALL + "\nPackage natbib Warning:[^\n]*" + natbib_warnings + "${log}") + if(natbib_warnings) + set(found_error TRUE) + message("\nFound natbib package warnings.") + foreach(warning ${natbib_warnings}) + string(STRIP "${warning}" warning_no_newline) + message("${warning_no_newline}") + endforeach(warning) + endif() + + # Check for overfull + string(REGEX MATCHALL + "\nOverfull[^\n]*" + overfull_warnings + "${log}") + if(overfull_warnings) + set(found_error TRUE) + message("\nFound overfull warnings. These are indicative of layout errors.") + foreach(warning ${overfull_warnings}) + string(STRIP "${warning}" warning_no_newline) + message("${warning_no_newline}") + endforeach(warning) + endif() + + # Check for invalid characters + string(REGEX MATCHALL + "\nMissing character:[^\n]*" + invalid_character_warnings + "${log}") + if(invalid_character_warnings) + set(found_error TRUE) + message("\nFound invalid character warnings. These characters are likely not printed correctly.") + foreach(warning ${invalid_character_warnings}) + string(STRIP "${warning}" warning_no_newline) + message("${warning_no_newline}") + endforeach(warning) + endif() + + if(found_error) + latex_get_filename_component(log_file_path ${log_file} ABSOLUTE) + message("\nConsult ${log_file_path} for more information on LaTeX build.") + else() + message("No known important warnings found.") + endif(found_error) +endfunction(latex_check_important_warnings) + +############################################################################# +# Helper functions for establishing LaTeX build. +############################################################################# + +function(latex_needit VAR NAME) + if(NOT ${VAR}) + message(SEND_ERROR "I need the ${NAME} command.") + endif() +endfunction(latex_needit) + +function(latex_wantit VAR NAME) + if(NOT ${VAR}) + message(STATUS "I could not find the ${NAME} command.") + endif() +endfunction(latex_wantit) + +function(latex_setup_variables) + set(LATEX_OUTPUT_PATH "${LATEX_OUTPUT_PATH}" + CACHE PATH "If non empty, specifies the location to place LaTeX output." + ) + + find_package(LATEX) + + find_program(XINDY_COMPILER + NAME xindy + PATHS ${MIKTEX_BINARY_PATH} /usr/bin + ) + + find_package(UnixCommands) + + find_program(PDFTOPS_CONVERTER + NAMES pdftops + DOC "The pdf to ps converter program from the Poppler package." + ) + + find_program(HTLATEX_COMPILER + NAMES htlatex + PATHS ${MIKTEX_BINARY_PATH} + /usr/bin + ) + + mark_as_advanced( + LATEX_COMPILER + PDFLATEX_COMPILER + BIBTEX_COMPILER + BIBER_COMPILER + MAKEINDEX_COMPILER + XINDY_COMPILER + DVIPS_CONVERTER + PS2PDF_CONVERTER + PDFTOPS_CONVERTER + LATEX2HTML_CONVERTER + HTLATEX_COMPILER + ) + + latex_needit(LATEX_COMPILER latex) + latex_wantit(PDFLATEX_COMPILER pdflatex) + latex_wantit(HTLATEX_COMPILER htlatex) + latex_needit(BIBTEX_COMPILER bibtex) + latex_wantit(BIBER_COMPILER biber) + latex_needit(MAKEINDEX_COMPILER makeindex) + latex_wantit(DVIPS_CONVERTER dvips) + latex_wantit(PS2PDF_CONVERTER ps2pdf) + latex_wantit(PDFTOPS_CONVERTER pdftops) + + set(LATEX_COMPILER_FLAGS "-interaction=batchmode -file-line-error" + CACHE STRING "Flags passed to latex.") + set(PDFLATEX_COMPILER_FLAGS ${LATEX_COMPILER_FLAGS} + CACHE STRING "Flags passed to pdflatex.") + set(HTLATEX_COMPILER_TEX4HT_FLAGS "html" + CACHE STRING "Options for the tex4ht.sty and *.4ht style files.") + set(HTLATEX_COMPILER_TEX4HT_POSTPROCESSOR_FLAGS "" + CACHE STRING "Options for the text4ht postprocessor.") + set(HTLATEX_COMPILER_T4HT_POSTPROCESSOR_FLAGS "" + CACHE STRING "Options for the t4ht postprocessor.") + set(HTLATEX_COMPILER_LATEX_FLAGS ${LATEX_COMPILER_FLAGS} + CACHE STRING "Flags passed from htlatex to the LaTeX compiler.") + set(LATEX_SYNCTEX_FLAGS "-synctex=1" + CACHE STRING "latex/pdflatex flags used to create synctex file.") + set(BIBTEX_COMPILER_FLAGS "" + CACHE STRING "Flags passed to bibtex.") + set(BIBER_COMPILER_FLAGS "" + CACHE STRING "Flags passed to biber.") + set(MAKEINDEX_COMPILER_FLAGS "" + CACHE STRING "Flags passed to makeindex.") + set(MAKEGLOSSARIES_COMPILER_FLAGS "" + CACHE STRING "Flags passed to makeglossaries.") + set(MAKENOMENCLATURE_COMPILER_FLAGS "" + CACHE STRING "Flags passed to makenomenclature.") + set(DVIPS_CONVERTER_FLAGS "-Ppdf -G0 -t letter" + CACHE STRING "Flags passed to dvips.") + if(NOT WIN32) + set(PS2PDF_CONVERTER_FLAGS "-dMaxSubsetPct=100 -dCompatibilityLevel=1.3 -dSubsetFonts=true -dEmbedAllFonts=true -dAutoFilterColorImages=false -dAutoFilterGrayImages=false -dColorImageFilter=/FlateEncode -dGrayImageFilter=/FlateEncode -dMonoImageFilter=/FlateEncode" + CACHE STRING "Flags passed to ps2pdf.") + else() + # Most windows ports of ghostscript utilities use .bat files for ps2pdf + # commands. bat scripts interpret "=" as a special character and separate + # those arguments. To get around this, the ghostscript utilities also + # support using "#" in place of "=". + set(PS2PDF_CONVERTER_FLAGS "-dMaxSubsetPct#100 -dCompatibilityLevel#1.3 -dSubsetFonts#true -dEmbedAllFonts#true -dAutoFilterColorImages#false -dAutoFilterGrayImages#false -dColorImageFilter#/FlateEncode -dGrayImageFilter#/FlateEncode -dMonoImageFilter#/FlateEncode" + CACHE STRING "Flags passed to ps2pdf.") + endif() + set(PDFTOPS_CONVERTER_FLAGS "" + CACHE STRING "Flags passed to pdftops.") + mark_as_advanced( + LATEX_COMPILER_FLAGS + PDFLATEX_COMPILER_FLAGS + HTLATEX_COMPILER_TEX4HT_FLAGS + HTLATEX_COMPILER_TEX4HT_POSTPROCESSOR_FLAGS + HTLATEX_COMPILER_T4HT_POSTPROCESSOR_FLAGS + HTLATEX_COMPILER_LATEX_FLAGS + LATEX_SYNCTEX_FLAGS + BIBTEX_COMPILER_FLAGS + BIBER_COMPILER_FLAGS + MAKEINDEX_COMPILER_FLAGS + MAKEGLOSSARIES_COMPILER_FLAGS + MAKENOMENCLATURE_COMPILER_FLAGS + DVIPS_CONVERTER_FLAGS + PS2PDF_CONVERTER_FLAGS + PDFTOPS_CONVERTER_FLAGS + ) + + # Because it is easier to type, the flags variables are entered as + # space-separated strings much like you would in a shell. However, when + # using a CMake command to execute a program, it works better to hold the + # arguments in semicolon-separated lists (otherwise the whole string will + # be interpreted as a single argument). Use the separate_arguments to + # convert the space-separated strings to semicolon-separated lists. + separate_arguments(LATEX_COMPILER_FLAGS) + separate_arguments(PDFLATEX_COMPILER_FLAGS) + separate_arguments(HTLATEX_COMPILER_LATEX_FLAGS) + separate_arguments(LATEX_SYNCTEX_FLAGS) + separate_arguments(BIBTEX_COMPILER_FLAGS) + separate_arguments(BIBER_COMPILER_FLAGS) + separate_arguments(MAKEINDEX_COMPILER_FLAGS) + separate_arguments(MAKEGLOSSARIES_COMPILER_FLAGS) + separate_arguments(MAKENOMENCLATURE_COMPILER_FLAGS) + separate_arguments(DVIPS_CONVERTER_FLAGS) + separate_arguments(PS2PDF_CONVERTER_FLAGS) + separate_arguments(PDFTOPS_CONVERTER_FLAGS) + + # Not quite done. When you call separate_arguments on a cache variable, + # the result is written to a local variable. That local variable goes + # away when this function returns (which is before any of them are used). + # So, copy these variables with local scope to cache variables with + # global scope. + set(LATEX_COMPILER_ARGS "${LATEX_COMPILER_FLAGS}" CACHE INTERNAL "") + set(PDFLATEX_COMPILER_ARGS "${PDFLATEX_COMPILER_FLAGS}" CACHE INTERNAL "") + set(HTLATEX_COMPILER_ARGS "${HTLATEX_COMPILER_LATEX_FLAGS}" CACHE INTERNAL "") + set(LATEX_SYNCTEX_ARGS "${LATEX_SYNCTEX_FLAGS}" CACHE INTERNAL "") + set(BIBTEX_COMPILER_ARGS "${BIBTEX_COMPILER_FLAGS}" CACHE INTERNAL "") + set(BIBER_COMPILER_ARGS "${BIBER_COMPILER_FLAGS}" CACHE INTERNAL "") + set(MAKEINDEX_COMPILER_ARGS "${MAKEINDEX_COMPILER_FLAGS}" CACHE INTERNAL "") + set(MAKEGLOSSARIES_COMPILER_ARGS "${MAKEGLOSSARIES_COMPILER_FLAGS}" CACHE INTERNAL "") + set(MAKENOMENCLATURE_COMPILER_ARGS "${MAKENOMENCLATURE_COMPILER_FLAGS}" CACHE INTERNAL "") + set(DVIPS_CONVERTER_ARGS "${DVIPS_CONVERTER_FLAGS}" CACHE INTERNAL "") + set(PS2PDF_CONVERTER_ARGS "${PS2PDF_CONVERTER_FLAGS}" CACHE INTERNAL "") + set(PDFTOPS_CONVERTER_ARGS "${PDFTOPS_CONVERTER_FLAGS}" CACHE INTERNAL "") + + find_program(IMAGEMAGICK_CONVERT + NAMES magick convert + DOC "The convert program that comes with ImageMagick (available at http://www.imagemagick.org)." + ) + mark_as_advanced(IMAGEMAGICK_CONVERT) + + if(DEFINED ENV{LATEX_DEFAULT_BUILD}) + set(default_build $ENV{LATEX_DEFAULT_BUILD}) + else() + set(default_build pdf) + endif() + + set(LATEX_DEFAULT_BUILD "${default_build}" CACHE STRING + "Choose the default type of LaTeX build. Valid options are pdf, dvi, ps, safepdf, html" + ) + set_property(CACHE LATEX_DEFAULT_BUILD + PROPERTY STRINGS pdf dvi ps safepdf html + ) + + option(LATEX_USE_SYNCTEX + "If on, have LaTeX generate a synctex file, which WYSIWYG editors can use to correlate output files like dvi and pdf with the lines of LaTeX source that generates them. In addition to adding the LATEX_SYNCTEX_FLAGS to the command line, this option also adds build commands that \"corrects\" the resulting synctex file to point to the original LaTeX files rather than those generated by UseLATEX.cmake." + OFF + ) + + option(LATEX_SMALL_IMAGES + "If on, the raster images will be converted to 1/6 the original size. This is because papers usually require 600 dpi images whereas most monitors only require at most 96 dpi. Thus, smaller images make smaller files for web distribution and can make it faster to read dvi files." + OFF) + if(LATEX_SMALL_IMAGES) + set(LATEX_RASTER_SCALE 16 PARENT_SCOPE) + set(LATEX_OPPOSITE_RASTER_SCALE 100 PARENT_SCOPE) + else() + set(LATEX_RASTER_SCALE 100 PARENT_SCOPE) + set(LATEX_OPPOSITE_RASTER_SCALE 16 PARENT_SCOPE) + endif() + + # Just holds extensions for known image types. They should all be lower case. + # For historical reasons, these are all declared in the global scope. + set(LATEX_DVI_VECTOR_IMAGE_EXTENSIONS .eps CACHE INTERNAL "") + set(LATEX_DVI_RASTER_IMAGE_EXTENSIONS CACHE INTERNAL "") + set(LATEX_DVI_IMAGE_EXTENSIONS + ${LATEX_DVI_VECTOR_IMAGE_EXTENSIONS} + ${LATEX_DVI_RASTER_IMAGE_EXTENSIONS} + CACHE INTERNAL "" + ) + + set(LATEX_PDF_VECTOR_IMAGE_EXTENSIONS .pdf CACHE INTERNAL "") + set(LATEX_PDF_RASTER_IMAGE_EXTENSIONS .jpeg .jpg .png CACHE INTERNAL "") + set(LATEX_PDF_IMAGE_EXTENSIONS + ${LATEX_PDF_VECTOR_IMAGE_EXTENSIONS} + ${LATEX_PDF_RASTER_IMAGE_EXTENSIONS} + CACHE INTERNAL "" + ) + + set(LATEX_OTHER_VECTOR_IMAGE_EXTENSIONS .ai .dot .svg CACHE INTERNAL "") + set(LATEX_OTHER_RASTER_IMAGE_EXTENSIONS + .bmp .bmp2 .bmp3 .dcm .dcx .ico .gif .pict .ppm .tif .tiff + CACHE INTERNAL "") + set(LATEX_OTHER_IMAGE_EXTENSIONS + ${LATEX_OTHER_VECTOR_IMAGE_EXTENSIONS} + ${LATEX_OTHER_RASTER_IMAGE_EXTENSIONS} + CACHE INTERNAL "" + ) + + set(LATEX_VECTOR_IMAGE_EXTENSIONS + ${LATEX_DVI_VECTOR_IMAGE_EXTENSIONS} + ${LATEX_PDF_VECTOR_IMAGE_EXTENSIONS} + ${LATEX_OTHER_VECTOR_IMAGE_EXTENSIONS} + CACHE INTERNAL "" + ) + set(LATEX_RASTER_IMAGE_EXTENSIONS + ${LATEX_DVI_RASTER_IMAGE_EXTENSIONS} + ${LATEX_PDF_RASTER_IMAGE_EXTENSIONS} + ${LATEX_OTHER_RASTER_IMAGE_EXTENSIONS} + CACHE INTERNAL "" + ) + set(LATEX_IMAGE_EXTENSIONS + ${LATEX_DVI_IMAGE_EXTENSIONS} + ${LATEX_PDF_IMAGE_EXTENSIONS} + ${LATEX_OTHER_IMAGE_EXTENSIONS} + CACHE INTERNAL "" + ) +endfunction(latex_setup_variables) + +function(latex_setup_targets) + if(NOT TARGET pdf) + add_custom_target(pdf) + endif() + if(NOT TARGET dvi) + add_custom_target(dvi) + endif() + if(NOT TARGET ps) + add_custom_target(ps) + endif() + if(NOT TARGET safepdf) + add_custom_target(safepdf) + endif() + if(NOT TARGET html) + add_custom_target(html) + endif() + if(NOT TARGET auxclean) + add_custom_target(auxclean) + endif() +endfunction(latex_setup_targets) + +function(latex_get_output_path var) + set(latex_output_path) + if(LATEX_OUTPUT_PATH) + get_filename_component( + LATEX_OUTPUT_PATH_FULL "${LATEX_OUTPUT_PATH}" ABSOLUTE + ) + if("${LATEX_OUTPUT_PATH_FULL}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}") + message(SEND_ERROR "You cannot set LATEX_OUTPUT_PATH to the same directory that contains LaTeX input files.") + else() + set(latex_output_path "${LATEX_OUTPUT_PATH_FULL}") + endif() + else() + if("${CMAKE_CURRENT_BINARY_DIR}" STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}") + message(SEND_ERROR "LaTeX files must be built out of source or you must set LATEX_OUTPUT_PATH.") + else() + set(latex_output_path "${CMAKE_CURRENT_BINARY_DIR}") + endif() + endif() + set(${var} ${latex_output_path} PARENT_SCOPE) +endfunction(latex_get_output_path) + +function(latex_add_convert_command + output_path + input_path + output_extension + input_extension + flags + ) + set(require_imagemagick_convert TRUE) + set(convert_flags "") + if(${input_extension} STREQUAL ".eps" AND ${output_extension} STREQUAL ".pdf") + # ImageMagick has broken eps to pdf conversion + # use ps2pdf instead + if(PS2PDF_CONVERTER) + set(require_imagemagick_convert FALSE) + set(converter ${PS2PDF_CONVERTER}) + set(convert_flags -dEPSCrop ${PS2PDF_CONVERTER_ARGS}) + else() + message(SEND_ERROR "Using postscript files with pdflatex requires ps2pdf for conversion.") + endif() + elseif(${input_extension} STREQUAL ".pdf" AND ${output_extension} STREQUAL ".eps") + # ImageMagick can also be sketchy on pdf to eps conversion. Not good with + # color spaces and tends to unnecessarily rasterize. + # use pdftops instead + if(PDFTOPS_CONVERTER) + set(require_imagemagick_convert FALSE) + set(converter ${PDFTOPS_CONVERTER}) + set(convert_flags -eps ${PDFTOPS_CONVERTER_ARGS}) + else() + message(STATUS "Consider getting pdftops from Poppler to convert PDF images to EPS images.") + set(convert_flags ${flags}) + endif() + else() + set(convert_flags ${flags}) + endif() + + if(require_imagemagick_convert) + if(IMAGEMAGICK_CONVERT) + string(TOLOWER ${IMAGEMAGICK_CONVERT} IMAGEMAGICK_CONVERT_LOWERCASE) + if(${IMAGEMAGICK_CONVERT_LOWERCASE} MATCHES "system32[/\\\\]convert\\.exe") + message(SEND_ERROR "IMAGEMAGICK_CONVERT set to Window's convert.exe for changing file systems rather than ImageMagick's convert for changing image formats. Please make sure ImageMagick is installed (available at http://www.imagemagick.org). If you have a recent version of ImageMagick (7.0 or higher), use the magick program instead of convert for IMAGEMAGICK_CONVERT.") + else() + set(converter ${IMAGEMAGICK_CONVERT}) + # ImageMagick requires a special order of arguments where resize and + # arguments of that nature must be placed after the input image path. + add_custom_command(OUTPUT ${output_path} + COMMAND ${converter} + ARGS ${input_path} ${convert_flags} ${output_path} + DEPENDS ${input_path} + ) + endif() + else() + message(SEND_ERROR "Could not find convert program. Please download ImageMagick from http://www.imagemagick.org and install.") + endif() + else() # Not ImageMagick convert + add_custom_command(OUTPUT ${output_path} + COMMAND ${converter} + ARGS ${convert_flags} ${input_path} ${output_path} + DEPENDS ${input_path} + ) + endif() +endfunction(latex_add_convert_command) + +# Makes custom commands to convert a file to a particular type. +function(latex_convert_image + output_files_var + input_file + output_extension + convert_flags + output_extensions + other_files + ) + set(output_file_list) + set(input_dir ${CMAKE_CURRENT_SOURCE_DIR}) + latex_get_output_path(output_dir) + + latex_get_filename_component(extension "${input_file}" EXT) + + # Check input filename for potential problems with LaTeX. + latex_get_filename_component(name "${input_file}" NAME_WE) + set(suggested_name "${name}") + if(suggested_name MATCHES ".*\\..*") + string(REPLACE "." "-" suggested_name "${suggested_name}") + endif() + if(suggested_name MATCHES ".* .*") + string(REPLACE " " "-" suggested_name "${suggested_name}") + endif() + if(NOT suggested_name STREQUAL name) + message(WARNING "Some LaTeX distributions have problems with image file names with multiple extensions or spaces. Consider changing ${name}${extension} to something like ${suggested_name}${extension}.") + endif() + + string(REGEX REPLACE "\\.[^.]*\$" ${output_extension} output_file + "${input_file}") + + latex_list_contains(is_type ${extension} ${output_extensions}) + if(is_type) + if(convert_flags) + latex_add_convert_command(${output_dir}/${output_file} + ${input_dir}/${input_file} ${output_extension} ${extension} + "${convert_flags}") + set(output_file_list ${output_dir}/${output_file}) + else() + # As a shortcut, we can just copy the file. + add_custom_command(OUTPUT ${output_dir}/${input_file} + COMMAND ${CMAKE_COMMAND} + ARGS -E copy ${input_dir}/${input_file} ${output_dir}/${input_file} + DEPENDS ${input_dir}/${input_file} + ) + set(output_file_list ${output_dir}/${input_file}) + endif() + else() + set(do_convert TRUE) + # Check to see if there is another input file of the appropriate type. + foreach(valid_extension ${output_extensions}) + string(REGEX REPLACE "\\.[^.]*\$" ${output_extension} try_file + "${input_file}") + latex_list_contains(has_native_file "${try_file}" ${other_files}) + if(has_native_file) + set(do_convert FALSE) + endif() + endforeach(valid_extension) + + # If we still need to convert, do it. + if(do_convert) + latex_add_convert_command(${output_dir}/${output_file} + ${input_dir}/${input_file} ${output_extension} ${extension} + "${convert_flags}") + set(output_file_list ${output_dir}/${output_file}) + endif() + endif() + + set(${output_files_var} ${output_file_list} PARENT_SCOPE) +endfunction(latex_convert_image) + +# Adds custom commands to process the given files for dvi and pdf builds. +# Adds the output files to the given variables (does not replace). +function(latex_process_images dvi_outputs_var pdf_outputs_var) + latex_get_output_path(output_dir) + set(dvi_outputs) + set(pdf_outputs) + foreach(file ${ARGN}) + if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${file}") + latex_get_filename_component(extension "${file}" EXT) + set(convert_flags) + + # Check to see if we need to downsample the image. + latex_list_contains(is_raster "${extension}" + ${LATEX_RASTER_IMAGE_EXTENSIONS}) + if(LATEX_SMALL_IMAGES) + if(is_raster) + set(convert_flags -resize ${LATEX_RASTER_SCALE}%) + endif() + endif() + + # Make sure the output directory exists. + latex_get_filename_component(path "${output_dir}/${file}" PATH) + make_directory("${path}") + + # Do conversions for dvi. + if(NOT LATEX_FORCE_PDF) + latex_convert_image(output_files "${file}" .eps "${convert_flags}" + "${LATEX_DVI_IMAGE_EXTENSIONS}" "${ARGN}") + list(APPEND dvi_outputs ${output_files}) + endif () + + # Do conversions for pdf. + if(NOT LATEX_FORCE_DVI AND NOT LATEX_FORCE_HTML) + if(is_raster) + latex_convert_image(output_files "${file}" .png "${convert_flags}" + "${LATEX_PDF_IMAGE_EXTENSIONS}" "${ARGN}") + list(APPEND pdf_outputs ${output_files}) + else() + latex_convert_image(output_files "${file}" .pdf "${convert_flags}" + "${LATEX_PDF_IMAGE_EXTENSIONS}" "${ARGN}") + list(APPEND pdf_outputs ${output_files}) + endif() + endif() + else() + message(WARNING "Could not find file ${CMAKE_CURRENT_SOURCE_DIR}/${file}. Are you sure you gave relative paths to IMAGES?") + endif() + endforeach(file) + + set(${dvi_outputs_var} ${dvi_outputs} PARENT_SCOPE) + set(${pdf_outputs_var} ${pdf_outputs} PARENT_SCOPE) +endfunction(latex_process_images) + +function(latex_copy_globbed_files pattern dest) + file(GLOB file_list ${pattern}) + foreach(in_file ${file_list}) + latex_get_filename_component(out_file ${in_file} NAME) + configure_file(${in_file} ${dest}/${out_file} COPYONLY) + endforeach(in_file) +endfunction(latex_copy_globbed_files) + +function(latex_copy_input_file file) + latex_get_output_path(output_dir) + + if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${file}) + latex_get_filename_component(path ${file} PATH) + file(MAKE_DIRECTORY ${output_dir}/${path}) + + latex_list_contains(use_config ${file} ${LATEX_CONFIGURE}) + if(use_config) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${file} + ${output_dir}/${file} + @ONLY + ) + add_custom_command(OUTPUT ${output_dir}/${file} + COMMAND ${CMAKE_COMMAND} + ARGS ${CMAKE_BINARY_DIR} + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${file} + ) + else() + add_custom_command(OUTPUT ${output_dir}/${file} + COMMAND ${CMAKE_COMMAND} + ARGS -E copy ${CMAKE_CURRENT_SOURCE_DIR}/${file} ${output_dir}/${file} + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${file} + ) + endif() + else() + if(EXISTS ${output_dir}/${file}) + # Special case: output exists but input does not. Assume that it was + # created elsewhere and skip the input file copy. + else() + message("Could not find input file ${CMAKE_CURRENT_SOURCE_DIR}/${file}") + endif() + endif() +endfunction(latex_copy_input_file) + +############################################################################# +# Commands provided by the UseLATEX.cmake "package" +############################################################################# + +function(latex_usage command message) + message(SEND_ERROR + "${message}\n Usage: ${command}(\n [BIBFILES ...]\n [INPUTS ...]\n [IMAGE_DIRS ...]\n [IMAGES \n [CONFIGURE ...]\n [DEPENDS ...]\n [MULTIBIB_NEWCITES] \n [USE_BIBLATEX] [USE_INDEX] [USE_GLOSSARY] [USE_NOMENCL]\n [FORCE_PDF] [FORCE_DVI] [FORCE_HTML]\n [TARGET_NAME] \n [EXCLUDE_FROM_ALL]\n [EXCLUDE_FROM_DEFAULTS])" + ) +endfunction(latex_usage command message) + +# Parses arguments to add_latex_document and ADD_LATEX_TARGETS and sets the +# variables LATEX_TARGET, LATEX_IMAGE_DIR, LATEX_BIBFILES, LATEX_DEPENDS, and +# LATEX_INPUTS. +function(parse_add_latex_arguments command latex_main_input) + set(options + USE_BIBLATEX + USE_INDEX + USE_GLOSSARY + USE_NOMENCL + FORCE_PDF + FORCE_DVI + FORCE_HTML + EXCLUDE_FROM_ALL + EXCLUDE_FROM_DEFAULTS + # Deprecated options + USE_GLOSSARIES + DEFAULT_PDF + DEFAULT_SAFEPDF + DEFAULT_PS + NO_DEFAULT + MANGLE_TARGET_NAMES + ) + set(oneValueArgs + TARGET_NAME + ) + set(multiValueArgs + BIBFILES + MULTIBIB_NEWCITES + INPUTS + IMAGE_DIRS + IMAGES + CONFIGURE + DEPENDS + INDEX_NAMES + INCLUDE_DIRECTORIES + ) + cmake_parse_arguments( + LATEX "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + # Handle invalid and deprecated arguments + if(LATEX_UNPARSED_ARGUMENTS) + latex_usage(${command} "Invalid or deprecated arguments: ${LATEX_UNPARSED_ARGUMENTS}") + endif() + if(LATEX_USE_GLOSSARIES) + latex_usage(${command} "USE_GLOSSARIES option removed in version 1.6.1. Use USE_GLOSSARY instead.") + endif() + if(LATEX_DEFAULT_PDF) + latex_usage(${command} "DEFAULT_PDF option removed in version 2.0. Use FORCE_PDF option or LATEX_DEFAULT_BUILD CMake variable instead.") + endif() + if(LATEX_DEFAULT_SAFEPDF) + latex_usage(${command} "DEFAULT_SAFEPDF option removed in version 2.0. Use LATEX_DEFAULT_BUILD CMake variable instead.") + endif() + if(LATEX_DEFAULT_DVI) + latex_usage(${command} "DEFAULT_DVI option removed in version 2.0. Use FORCE_DVI option or LATEX_DEFAULT_BUILD CMake variable instead.") + endif() + if(LATEX_NO_DEFAULT) + latex_usage(${command} "NO_DEFAULT option removed in version 2.0. Use EXCLUDE_FROM_ALL instead.") + endif() + if(LATEX_MANGLE_TARGET_NAMES) + latex_usage(${command} "MANGLE_TARGET_NAMES option removed in version 2.0. All LaTeX targets use mangled names now.") + endif() + + # Capture the first argument, which is the main LaTeX input. + latex_get_filename_component(latex_target ${latex_main_input} NAME_WE) + set(LATEX_MAIN_INPUT ${latex_main_input} PARENT_SCOPE) + set(LATEX_TARGET ${latex_target} PARENT_SCOPE) + + # Propagate the result variables to the caller + foreach(arg_name ${options} ${oneValueArgs} ${multiValueArgs}) + set(var_name LATEX_${arg_name}) + set(${var_name} ${${var_name}} PARENT_SCOPE) + endforeach(arg_name) +endfunction(parse_add_latex_arguments) + +function(add_latex_targets_internal) + latex_get_output_path(output_dir) + + if(LATEX_USE_SYNCTEX) + set(synctex_flags ${LATEX_SYNCTEX_ARGS}) + else() + set(synctex_flags) + endif() + + # The commands to run LaTeX. They are repeated multiple times. + set(latex_build_command + ${LATEX_COMPILER} ${LATEX_COMPILER_ARGS} ${synctex_flags} ${LATEX_MAIN_INPUT} + ) + if(LATEX_COMPILER_ARGS MATCHES ".*batchmode.*") + # Wrap command in script that dumps the log file on error. This makes sure + # errors can be seen. + set(latex_build_command + ${CMAKE_COMMAND} + -D LATEX_BUILD_COMMAND=execute_latex + -D LATEX_WORKING_DIRECTORY="${output_dir}" + -D LATEX_FULL_COMMAND="${latex_build_command}" + -D LATEX_OUTPUT_FILE="${LATEX_TARGET}.dvi" + -D LATEX_LOG_FILE="${LATEX_TARGET}.log" + -P "${LATEX_USE_LATEX_LOCATION}" + ) + endif() + set(pdflatex_build_command + ${PDFLATEX_COMPILER} ${PDFLATEX_COMPILER_ARGS} ${synctex_flags} ${LATEX_MAIN_INPUT} + ) + if(PDFLATEX_COMPILER_ARGS MATCHES ".*batchmode.*") + # Wrap command in script that dumps the log file on error. This makes sure + # errors can be seen. + set(pdflatex_build_command + ${CMAKE_COMMAND} + -D LATEX_BUILD_COMMAND=execute_latex + -D LATEX_WORKING_DIRECTORY="${output_dir}" + -D LATEX_FULL_COMMAND="${pdflatex_build_command}" + -D LATEX_OUTPUT_FILE="${LATEX_TARGET}.pdf" + -D LATEX_LOG_FILE="${LATEX_TARGET}.log" + -P "${LATEX_USE_LATEX_LOCATION}" + ) + endif() + + if(LATEX_INCLUDE_DIRECTORIES) + # The include directories needs to start with the build directory so + # that the copied files can be found. It also needs to end with an + # empty directory so that the standard system directories are included + # after any specified. + set(LATEX_INCLUDE_DIRECTORIES . ${LATEX_INCLUDE_DIRECTORIES} "") + + # CMake separates items in a list with a semicolon. Lists of + # directories on most systems are separated by colons, so we can do a + # simple text replace. On Windows, directories are separated by + # semicolons, but we replace them with the $ generator + # expression to make sure CMake treats it as a single string. + if(CMAKE_HOST_WIN32) + string(REPLACE ";" "$" TEXINPUTS "${LATEX_INCLUDE_DIRECTORIES}") + else() + string(REPLACE ";" ":" TEXINPUTS "${LATEX_INCLUDE_DIRECTORIES}") + endif() + + # Set the TEXINPUTS environment variable + set(latex_build_command + ${CMAKE_COMMAND} -E env TEXINPUTS=${TEXINPUTS} ${latex_build_command}) + set(pdflatex_build_command + ${CMAKE_COMMAND} -E env TEXINPUTS=${TEXINPUTS} ${pdflatex_build_command}) + endif() + + if(NOT LATEX_TARGET_NAME) + # Use the main filename (minus the .tex) as the target name. Remove any + # spaces since CMake cannot have spaces in its target names. + string(REPLACE " " "_" LATEX_TARGET_NAME ${LATEX_TARGET}) + endif() + + # Some LaTeX commands may need to be modified (or may not work) if the main + # tex file is in a subdirectory. Make a flag for that. + get_filename_component(LATEX_MAIN_INPUT_SUBDIR ${LATEX_MAIN_INPUT} DIRECTORY) + + # Set up target names. + set(dvi_target ${LATEX_TARGET_NAME}_dvi) + set(pdf_target ${LATEX_TARGET_NAME}_pdf) + set(ps_target ${LATEX_TARGET_NAME}_ps) + set(safepdf_target ${LATEX_TARGET_NAME}_safepdf) + set(html_target ${LATEX_TARGET_NAME}_html) + set(auxclean_target ${LATEX_TARGET_NAME}_auxclean) + + # Probably not all of these will be generated, but they could be. + # Note that the aux file is added later. + set(auxiliary_clean_files + ${output_dir}/${LATEX_TARGET}.aux + ${output_dir}/${LATEX_TARGET}.bbl + ${output_dir}/${LATEX_TARGET}.blg + ${output_dir}/${LATEX_TARGET}-blx.bib + ${output_dir}/${LATEX_TARGET}.glg + ${output_dir}/${LATEX_TARGET}.glo + ${output_dir}/${LATEX_TARGET}.gls + ${output_dir}/${LATEX_TARGET}.idx + ${output_dir}/${LATEX_TARGET}.ilg + ${output_dir}/${LATEX_TARGET}.ind + ${output_dir}/${LATEX_TARGET}.ist + ${output_dir}/${LATEX_TARGET}.log + ${output_dir}/${LATEX_TARGET}.out + ${output_dir}/${LATEX_TARGET}.toc + ${output_dir}/${LATEX_TARGET}.lof + ${output_dir}/${LATEX_TARGET}.xdy + ${output_dir}/${LATEX_TARGET}.synctex.gz + ${output_dir}/${LATEX_TARGET}.synctex.bak.gz + ${output_dir}/${LATEX_TARGET}.dvi + ${output_dir}/${LATEX_TARGET}.ps + ${output_dir}/${LATEX_TARGET}.pdf + ) + + set(image_list ${LATEX_IMAGES}) + + # For each directory in LATEX_IMAGE_DIRS, glob all the image files and + # place them in LATEX_IMAGES. + foreach(dir ${LATEX_IMAGE_DIRS}) + if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${dir}) + message(WARNING "Image directory ${CMAKE_CURRENT_SOURCE_DIR}/${dir} does not exist. Are you sure you gave relative directories to IMAGE_DIRS?") + endif() + foreach(extension ${LATEX_IMAGE_EXTENSIONS}) + file(GLOB files ${CMAKE_CURRENT_SOURCE_DIR}/${dir}/*${extension}) + foreach(file ${files}) + latex_get_filename_component(filename ${file} NAME) + list(APPEND image_list ${dir}/${filename}) + endforeach(file) + endforeach(extension) + endforeach(dir) + + latex_process_images(dvi_images pdf_images ${image_list}) + + set(make_dvi_command + ${CMAKE_COMMAND} -E chdir ${output_dir} + ${latex_build_command}) + set(make_pdf_command + ${CMAKE_COMMAND} -E chdir ${output_dir} + ${pdflatex_build_command} + ) + + set(make_dvi_depends ${LATEX_DEPENDS} ${dvi_images}) + set(make_pdf_depends ${LATEX_DEPENDS} ${pdf_images}) + foreach(input ${LATEX_MAIN_INPUT} ${LATEX_INPUTS}) + list(APPEND make_dvi_depends ${output_dir}/${input}) + list(APPEND make_pdf_depends ${output_dir}/${input}) + if(${input} MATCHES "\\.tex$") + # Dependent .tex files might have their own .aux files created. Make + # sure these get cleaned as well. This might replicate the cleaning + # of the main .aux file, which is OK. + string(REGEX REPLACE "\\.tex$" "" input_we ${input}) + list(APPEND auxiliary_clean_files + ${output_dir}/${input_we}.aux + ${output_dir}/${input}.aux + ) + endif() + endforeach(input) + + set(all_latex_sources ${LATEX_MAIN_INPUT} ${LATEX_INPUTS} ${image_list}) + + if(LATEX_USE_GLOSSARY) + foreach(dummy 0 1) # Repeat these commands twice. + set(make_dvi_command ${make_dvi_command} + COMMAND ${CMAKE_COMMAND} -E chdir ${output_dir} + ${CMAKE_COMMAND} + -D LATEX_BUILD_COMMAND=makeglossaries + -D LATEX_TARGET=${LATEX_TARGET} + -D MAKEINDEX_COMPILER=${MAKEINDEX_COMPILER} + -D XINDY_COMPILER=${XINDY_COMPILER} + -D MAKEGLOSSARIES_COMPILER_ARGS=${MAKEGLOSSARIES_COMPILER_ARGS} + -P ${LATEX_USE_LATEX_LOCATION} + COMMAND ${CMAKE_COMMAND} -E chdir ${output_dir} + ${latex_build_command} + ) + set(make_pdf_command ${make_pdf_command} + COMMAND ${CMAKE_COMMAND} -E chdir ${output_dir} + ${CMAKE_COMMAND} + -D LATEX_BUILD_COMMAND=makeglossaries + -D LATEX_TARGET=${LATEX_TARGET} + -D MAKEINDEX_COMPILER=${MAKEINDEX_COMPILER} + -D XINDY_COMPILER=${XINDY_COMPILER} + -D MAKEGLOSSARIES_COMPILER_ARGS=${MAKEGLOSSARIES_COMPILER_ARGS} + -P ${LATEX_USE_LATEX_LOCATION} + COMMAND ${CMAKE_COMMAND} -E chdir ${output_dir} + ${pdflatex_build_command} + ) + endforeach(dummy) + endif() + + if(LATEX_USE_NOMENCL) + foreach(dummy 0 1) # Repeat these commands twice. + set(make_dvi_command ${make_dvi_command} + COMMAND ${CMAKE_COMMAND} -E chdir ${output_dir} + ${CMAKE_COMMAND} + -D LATEX_BUILD_COMMAND=makenomenclature + -D LATEX_TARGET=${LATEX_TARGET} + -D MAKEINDEX_COMPILER=${MAKEINDEX_COMPILER} + -D MAKENOMENCLATURE_COMPILER_ARGS=${MAKENOMENCLATURE_COMPILER_ARGS} + -P ${LATEX_USE_LATEX_LOCATION} + COMMAND ${CMAKE_COMMAND} -E chdir ${output_dir} + ${latex_build_command} + ) + set(make_pdf_command ${make_pdf_command} + COMMAND ${CMAKE_COMMAND} -E chdir ${output_dir} + ${CMAKE_COMMAND} + -D LATEX_BUILD_COMMAND=makenomenclature + -D LATEX_TARGET=${LATEX_TARGET} + -D MAKEINDEX_COMPILER=${MAKEINDEX_COMPILER} + -D MAKENOMENCLATURE_COMPILER_ARGS=${MAKENOMENCLATURE_COMPILER_ARGS} + -P ${LATEX_USE_LATEX_LOCATION} + COMMAND ${CMAKE_COMMAND} -E chdir ${output_dir} + ${pdflatex_build_command} + ) + endforeach(dummy) + endif() + + if(LATEX_BIBFILES) + set(suppress_bib_output) + if(LATEX_USE_BIBLATEX) + if(NOT BIBER_COMPILER) + message(SEND_ERROR "I need the biber command.") + endif() + set(bib_compiler ${BIBER_COMPILER}) + set(bib_compiler_flags ${BIBER_COMPILER_ARGS}) + + if(NOT BIBER_COMPILER_ARGS MATCHES ".*-q.*") + # Only suppress bib output if the quiet option is not specified. + set(suppress_bib_output TRUE) + endif() + + if(LATEX_USE_BIBLATEX_CONFIG) + list(APPEND auxiliary_clean_files ${output_dir}/biblatex.cfg) + list(APPEND make_dvi_depends ${output_dir}/biblatex.cfg) + list(APPEND make_pdf_depends ${output_dir}/biblatex.cfg) + endif() + else() + set(bib_compiler ${BIBTEX_COMPILER}) + set(bib_compiler_flags ${BIBTEX_COMPILER_ARGS}) + endif() + if(LATEX_MULTIBIB_NEWCITES) + # Suppressed bib output currently not supported for multibib + foreach (multibib_auxfile ${LATEX_MULTIBIB_NEWCITES}) + latex_get_filename_component(multibib_target ${multibib_auxfile} NAME_WE) + set(make_dvi_command ${make_dvi_command} + COMMAND ${CMAKE_COMMAND} -E chdir ${output_dir} + ${bib_compiler} ${bib_compiler_flags} ${multibib_target}) + set(make_pdf_command ${make_pdf_command} + COMMAND ${CMAKE_COMMAND} -E chdir ${output_dir} + ${bib_compiler} ${bib_compiler_flags} ${multibib_target}) + set(auxiliary_clean_files ${auxiliary_clean_files} + ${output_dir}/${multibib_target}.aux) + endforeach (multibib_auxfile ${LATEX_MULTIBIB_NEWCITES}) + else() + set(full_bib_command + ${bib_compiler} ${bib_compiler_flags} ${LATEX_TARGET}) + if(suppress_bib_output) + set(full_bib_command + ${CMAKE_COMMAND} + -D LATEX_BUILD_COMMAND=execute_latex + -D LATEX_WORKING_DIRECTORY="${output_dir}" + -D LATEX_FULL_COMMAND="${full_bib_command}" + -D LATEX_OUTPUT_FILE="${LATEX_TARGET}.bbl" + -D LATEX_LOG_FILE="${LATEX_TARGET}.blg" + -P "${LATEX_USE_LATEX_LOCATION}" + ) + endif() + set(make_dvi_command ${make_dvi_command} + COMMAND ${CMAKE_COMMAND} -E chdir ${output_dir} + ${full_bib_command}) + set(make_pdf_command ${make_pdf_command} + COMMAND ${CMAKE_COMMAND} -E chdir ${output_dir} + ${full_bib_command}) + endif() + + foreach (bibfile ${LATEX_BIBFILES}) + list(APPEND make_dvi_depends ${output_dir}/${bibfile}) + list(APPEND make_pdf_depends ${output_dir}/${bibfile}) + endforeach (bibfile ${LATEX_BIBFILES}) + else() + if(LATEX_MULTIBIB_NEWCITES) + message(WARNING "MULTIBIB_NEWCITES has no effect without BIBFILES option.") + endif() + endif() + + if(LATEX_USE_INDEX) + if(LATEX_INDEX_NAMES) + set(INDEX_NAMES ${LATEX_INDEX_NAMES}) + else() + set(INDEX_NAMES ${LATEX_TARGET}) + endif() + foreach(idx_name ${INDEX_NAMES}) + set(make_dvi_command ${make_dvi_command} + COMMAND ${CMAKE_COMMAND} -E chdir ${output_dir} + ${latex_build_command} + COMMAND ${CMAKE_COMMAND} -E chdir ${output_dir} + ${MAKEINDEX_COMPILER} ${MAKEINDEX_COMPILER_ARGS} ${idx_name}.idx) + set(make_pdf_command ${make_pdf_command} + COMMAND ${CMAKE_COMMAND} -E chdir ${output_dir} + ${pdflatex_build_command} + COMMAND ${CMAKE_COMMAND} -E chdir ${output_dir} + ${MAKEINDEX_COMPILER} ${MAKEINDEX_COMPILER_ARGS} ${idx_name}.idx) + set(auxiliary_clean_files ${auxiliary_clean_files} + ${output_dir}/${idx_name}.idx + ${output_dir}/${idx_name}.ilg + ${output_dir}/${idx_name}.ind) + endforeach() + else() + if(LATEX_INDEX_NAMES) + message(WARNING "INDEX_NAMES has no effect without USE_INDEX option.") + endif() + endif() + + set(make_dvi_command ${make_dvi_command} + COMMAND ${CMAKE_COMMAND} -E chdir ${output_dir} + ${latex_build_command} + COMMAND ${CMAKE_COMMAND} -E chdir ${output_dir} + ${latex_build_command}) + set(make_pdf_command ${make_pdf_command} + COMMAND ${CMAKE_COMMAND} -E chdir ${output_dir} + ${pdflatex_build_command} + COMMAND ${CMAKE_COMMAND} -E chdir ${output_dir} + ${pdflatex_build_command}) + + # Need to run one more time to remove biblatex' warning + # about page breaks that have changed. + if(LATEX_USE_BIBLATEX) + set(make_dvi_command ${make_dvi_command} + COMMAND ${CMAKE_COMMAND} -E chdir ${output_dir} + ${latex_build_command}) + set(make_pdf_command ${make_pdf_command} + COMMAND ${CMAKE_COMMAND} -E chdir ${output_dir} + ${pdflatex_build_command}) + endif() + + if(LATEX_USE_SYNCTEX) + if(NOT GZIP) + message(SEND_ERROR "UseLATEX.cmake: USE_SYNTEX option requires gzip program. Set GZIP variable.") + endif() + set(make_dvi_command ${make_dvi_command} + COMMAND ${CMAKE_COMMAND} + -D LATEX_BUILD_COMMAND=correct_synctex + -D LATEX_TARGET=${LATEX_TARGET} + -D GZIP=${GZIP} + -D "LATEX_SOURCE_DIRECTORY=${CMAKE_CURRENT_SOURCE_DIR}" + -D "LATEX_BINARY_DIRECTORY=${output_dir}" + -P ${LATEX_USE_LATEX_LOCATION} + ) + set(make_pdf_command ${make_pdf_command} + COMMAND ${CMAKE_COMMAND} + -D LATEX_BUILD_COMMAND=correct_synctex + -D LATEX_TARGET=${LATEX_TARGET} + -D GZIP=${GZIP} + -D "LATEX_SOURCE_DIRECTORY=${CMAKE_CURRENT_SOURCE_DIR}" + -D "LATEX_BINARY_DIRECTORY=${output_dir}" + -P ${LATEX_USE_LATEX_LOCATION} + ) + endif() + + # Check LaTeX output for important warnings at end of build + set(make_dvi_command ${make_dvi_command} + COMMAND ${CMAKE_COMMAND} -E chdir ${output_dir} + ${CMAKE_COMMAND} + -D LATEX_BUILD_COMMAND=check_important_warnings + -D LATEX_TARGET=${LATEX_TARGET} + -P ${LATEX_USE_LATEX_LOCATION} + ) + set(make_pdf_command ${make_pdf_command} + COMMAND ${CMAKE_COMMAND} -E chdir ${output_dir} + ${CMAKE_COMMAND} + -D LATEX_BUILD_COMMAND=check_important_warnings + -D LATEX_TARGET=${LATEX_TARGET} + -P ${LATEX_USE_LATEX_LOCATION} + ) + + # Capture the default build. + string(TOLOWER "${LATEX_DEFAULT_BUILD}" default_build) + + if((NOT LATEX_FORCE_PDF) AND (NOT LATEX_FORCE_DVI) AND (NOT LATEX_FORCE_HTML)) + set(no_force TRUE) + endif() + + # Add commands and targets for building pdf outputs (with pdflatex). + if(LATEX_FORCE_PDF OR no_force) + if(LATEX_FORCE_PDF) + set(default_build pdf) + endif() + + if(PDFLATEX_COMPILER) + add_custom_command(OUTPUT ${output_dir}/${LATEX_TARGET}.pdf + COMMAND ${make_pdf_command} + DEPENDS ${make_pdf_depends} + ) + add_custom_target(${pdf_target} + DEPENDS ${output_dir}/${LATEX_TARGET}.pdf + SOURCES ${all_latex_sources} + ) + if(NOT LATEX_EXCLUDE_FROM_DEFAULTS) + add_dependencies(pdf ${pdf_target}) + endif() + endif() + endif() + + # Add commands and targets for building dvi outputs. + if(LATEX_FORCE_DVI OR LATEX_FORCE_HTML OR no_force) + if(LATEX_FORCE_DVI) + if((NOT default_build STREQUAL dvi) AND + (NOT default_build STREQUAL ps) AND + (NOT default_build STREQUAL safepdf)) + set(default_build dvi) + endif() + endif() + + add_custom_command(OUTPUT ${output_dir}/${LATEX_TARGET}.dvi + COMMAND ${make_dvi_command} + DEPENDS ${make_dvi_depends} + ) + add_custom_target(${dvi_target} + DEPENDS ${output_dir}/${LATEX_TARGET}.dvi + SOURCES ${all_latex_sources} + ) + if(NOT LATEX_EXCLUDE_FROM_DEFAULTS) + add_dependencies(dvi ${dvi_target}) + endif() + + if(DVIPS_CONVERTER) + add_custom_command(OUTPUT ${output_dir}/${LATEX_TARGET}.ps + COMMAND ${CMAKE_COMMAND} -E chdir ${output_dir} + ${DVIPS_CONVERTER} ${DVIPS_CONVERTER_ARGS} -o ${LATEX_TARGET}.ps ${LATEX_TARGET}.dvi + DEPENDS ${output_dir}/${LATEX_TARGET}.dvi) + add_custom_target(${ps_target} + DEPENDS ${output_dir}/${LATEX_TARGET}.ps + SOURCES ${all_latex_sources} + ) + if(NOT LATEX_EXCLUDE_FROM_DEFAULTS) + add_dependencies(ps ${ps_target}) + endif() + if(PS2PDF_CONVERTER) + # Since both the pdf and safepdf targets have the same output, we + # cannot properly do the dependencies for both. When selecting safepdf, + # simply force a recompile every time. + add_custom_target(${safepdf_target} + ${CMAKE_COMMAND} -E chdir ${output_dir} + ${PS2PDF_CONVERTER} ${PS2PDF_CONVERTER_ARGS} ${LATEX_TARGET}.ps ${LATEX_TARGET}.pdf + DEPENDS ${ps_target} + ) + if(NOT LATEX_EXCLUDE_FROM_DEFAULTS) + add_dependencies(safepdf ${safepdf_target}) + endif() + endif() + endif() + endif() + + if(LATEX_FORCE_HTML OR no_force) + if (LATEX_FORCE_HTML) + set(default_build html) + endif() + + if(HTLATEX_COMPILER AND LATEX_MAIN_INPUT_SUBDIR) + message(STATUS + "Disabling HTML build for ${LATEX_TARGET_NAME}.tex because the main file is in subdirectory ${LATEX_MAIN_INPUT_SUBDIR}" + ) + # The code below to run HTML assumes that LATEX_TARGET.tex is in the + # current directory. I have tried to specify that LATEX_TARGET.tex is + # in a subdirectory. That makes the build targets correct, but the + # HTML build still fails (at least for htlatex) because files are not + # generated where expected. I am getting around the problem by simply + # disabling HTML in this case. If someone really cares, they can fix + # this, but make sure it runs on many platforms and build programs. + elseif(HTLATEX_COMPILER) + # htlatex places the output in a different location + set(HTML_OUTPUT "${output_dir}/${LATEX_TARGET}.html") + add_custom_command(OUTPUT ${HTML_OUTPUT} + COMMAND ${CMAKE_COMMAND} -E chdir ${output_dir} + ${HTLATEX_COMPILER} ${LATEX_MAIN_INPUT} + "${HTLATEX_COMPILER_TEX4HT_FLAGS}" + "${HTLATEX_COMPILER_TEX4HT_POSTPROCESSOR_FLAGS}" + "${HTLATEX_COMPILER_T4HT_POSTPROCESSOR_FLAGS}" + ${HTLATEX_COMPILER_ARGS} + DEPENDS + ${output_dir}/${LATEX_TARGET}.tex + ${output_dir}/${LATEX_TARGET}.dvi + VERBATIM + ) + add_custom_target(${html_target} + DEPENDS ${HTML_OUTPUT} ${dvi_target} + SOURCES ${all_latex_sources} + ) + if(NOT LATEX_EXCLUDE_FROM_DEFAULTS) + add_dependencies(html ${html_target}) + endif() + endif() + endif() + + # Set default targets. + if("${default_build}" STREQUAL "pdf") + add_custom_target(${LATEX_TARGET_NAME} DEPENDS ${pdf_target}) + elseif("${default_build}" STREQUAL "dvi") + add_custom_target(${LATEX_TARGET_NAME} DEPENDS ${dvi_target}) + elseif("${default_build}" STREQUAL "ps") + add_custom_target(${LATEX_TARGET_NAME} DEPENDS ${ps_target}) + elseif("${default_build}" STREQUAL "safepdf") + add_custom_target(${LATEX_TARGET_NAME} DEPENDS ${safepdf_target}) + elseif("${default_build}" STREQUAL "html") + add_custom_target(${LATEX_TARGET_NAME} DEPENDS ${html_target}) + else() + message(SEND_ERROR "LATEX_DEFAULT_BUILD set to an invalid value. See the documentation for that variable.") + endif() + + if(NOT LATEX_EXCLUDE_FROM_ALL) + add_custom_target(_${LATEX_TARGET_NAME} ALL DEPENDS ${LATEX_TARGET_NAME}) + endif() + + set_directory_properties(. + ADDITIONAL_MAKE_CLEAN_FILES "${auxiliary_clean_files}" + ) + + add_custom_target(${auxclean_target} + COMMENT "Cleaning auxiliary LaTeX files." + COMMAND ${CMAKE_COMMAND} -E remove ${auxiliary_clean_files} + ) + add_dependencies(auxclean ${auxclean_target}) +endfunction(add_latex_targets_internal) + +function(add_latex_targets latex_main_input) + latex_get_output_path(output_dir) + parse_add_latex_arguments(ADD_LATEX_TARGETS ${latex_main_input} ${ARGN}) + + add_latex_targets_internal() +endfunction(add_latex_targets) + +function(add_latex_document latex_main_input) + latex_get_output_path(output_dir) + if(output_dir) + parse_add_latex_arguments(add_latex_document ${latex_main_input} ${ARGN}) + + latex_copy_input_file(${LATEX_MAIN_INPUT}) + + foreach (bib_file ${LATEX_BIBFILES}) + latex_copy_input_file(${bib_file}) + endforeach (bib_file) + + if (LATEX_USE_BIBLATEX AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/biblatex.cfg) + latex_copy_input_file(biblatex.cfg) + set(LATEX_USE_BIBLATEX_CONFIG TRUE) + endif() + + foreach (input ${LATEX_INPUTS}) + latex_copy_input_file(${input}) + endforeach(input) + + latex_copy_globbed_files(${CMAKE_CURRENT_SOURCE_DIR}/*.cls ${output_dir}) + latex_copy_globbed_files(${CMAKE_CURRENT_SOURCE_DIR}/*.bst ${output_dir}) + latex_copy_globbed_files(${CMAKE_CURRENT_SOURCE_DIR}/*.clo ${output_dir}) + latex_copy_globbed_files(${CMAKE_CURRENT_SOURCE_DIR}/*.sty ${output_dir}) + latex_copy_globbed_files(${CMAKE_CURRENT_SOURCE_DIR}/*.ist ${output_dir}) + latex_copy_globbed_files(${CMAKE_CURRENT_SOURCE_DIR}/*.fd ${output_dir}) + + add_latex_targets_internal() + endif() +endfunction(add_latex_document) + +############################################################################# +# Actually do stuff +############################################################################# + +if(LATEX_BUILD_COMMAND) + set(command_handled) + + if("${LATEX_BUILD_COMMAND}" STREQUAL execute_latex) + latex_execute_latex() + set(command_handled TRUE) + endif() + + if("${LATEX_BUILD_COMMAND}" STREQUAL makeglossaries) + latex_makeglossaries() + set(command_handled TRUE) + endif() + + if("${LATEX_BUILD_COMMAND}" STREQUAL makenomenclature) + latex_makenomenclature() + set(command_handled TRUE) + endif() + + if("${LATEX_BUILD_COMMAND}" STREQUAL correct_synctex) + latex_correct_synctex() + set(command_handled TRUE) + endif() + + if("${LATEX_BUILD_COMMAND}" STREQUAL check_important_warnings) + latex_check_important_warnings() + set(command_handled TRUE) + endif() + + if(NOT command_handled) + message(SEND_ERROR "Unknown command: ${LATEX_BUILD_COMMAND}") + endif() + +else() + # Must be part of the actual configure (included from CMakeLists.txt). + latex_setup_variables() + latex_setup_targets() +endif() diff --git a/img/exec/rt_graspels_qa194_12_20_20_speedup.pdf b/img/exec/rt_graspels_qa194_12_20_20_speedup.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f765e316592e36df7c259676fc5cab57bd9ee6ae GIT binary patch literal 8351 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 N@nSJD%D+><`Y&rupZNd) literal 0 HcmV?d00001 diff --git a/img/exec/rt_graspels_qa194_16_20_20_speedup.pdf b/img/exec/rt_graspels_qa194_16_20_20_speedup.pdf new file mode 100644 index 0000000000000000000000000000000000000000..68f0628d4c57ee6f0bd96b063326802a7bb41185 GIT binary patch literal 8345 zcma)>Wl$Z;x~6dm4q@T$E(=?@ySoQ>hlRU)a18_t?(Xg$2<~pdf;+SK)J&ay>)bhW z|8#Y=R)1afyzkddr7SMV#Kz2tNVR`;{)os!%1Y{JVuQ%f&mw7U2R3(Mk+d@gn~R&9 zI+~fY$eTM@f~`n_tUw+?K}1)ui@C8qqUY*{zCt`9CwkWngKy{nzSdLWIA$~{LP9H3 zY>a0A^tAUs zGc_baZ?Eiq6Y*YewpxV=l$Th^f6T^c49kZ%ftEiIiFMKU)q2HscCxy~)^t&+@_dDZ zmW3m^%yCp*HMmu$p@M(7a#21dQnZb}Qf4LEL5#E&WoE}QaysZ}G8Vv&D_46dtOx&6 zF>4$gdr2dg`bGiWh{ce`VWc}EmfQ+kQb;ROn-ExffB>=h@^i!)nr>P8lcjV z@dKCl{m>%DU@7p5~a&u(}H6bp}oFrbB3UP|4Q3#r)J|QzJMt_AsF^WjvnE8%q!|F ze=0BJh~o6188OLFYQ90@%1@jdUHC#hx)-U_;%DCt27m`S!5sq-m4NJlQAL_J|7)Zu z&H)d6B@r2{IyooX*vz(1!$!y-_zdMp7yjLFXb_5Wn&)y#6!vI`E3yYam~o2YNKu?V zE!ZuS^_Dpw@~`G-e`lzIQ-`G`yF4pFu>#h|kZ8q0N97k2$a-z3(Jm`><)O_Xj^|(s z5Jrc{e$2I0OyaBJlNM`39PP%zG#baT_$!>7mOpRo&8XikJp%K}B)%tkc*u8#0n!b)2*GdygamVK4DySno*)_%5Q3MA#|cl; zTHG500x1f+c&>ZFR)2auTPRxw@D9V|?VU1l3#mQ2b6vAES-5JnMqB+`j=^ba4`fLp z=(t^Z(yD9ijvF9XfG^(44uJw98dBMa*-us&Y)yUzq$DPDO>Dw*Z2MBeM`Q&u!=L(>hXz*pJcWV0!xe3Ku+HJ2vHLqQyp#7 zGYl>#{%{*Ansb!P2kghsfRJKmbl7ETwS$CVo~y!yE*VXcH>RK>x5t{cMF&GMY? z{(oI41y5_B2}+VgtiTAsGzw32w9CM1_DLF*SXc&gney~!LuHqC9h@_mujXg}%`72d;9QF0=jazT@$utR1Zyd zHn-FBMMML%AMbJRetItXJ&v8oPzz~s(UyZ*W zt@e}M!Tm|M3=g6CG{TDGX1^1ugCmzsfa;VyXqv&%(d_BeDD3ObPn~$}>~J~08|0F@ z_p||!FF4%8+HV>fn7}=Hy|BULBq@=tVIl-xU13JL?m6r5e9Z7UBWqgDGzf&>3gEy_ zNJM2T8Kfv>BcV-8BH5!DouG* ztQ(fzl;tEItPH=QsV?8!L63)^>Noqk_<6*OKHi3lTGC0Hop25bO2r%N^s5hB^n*j< zf2Z=CHjD$(K9BE?+IYgnnmFXpqWsEuNbE7(&Gpj2rHWl(!jwEjn(6q9jYf4hQ{!>Ay|J-tesi9ydP>>~ zqdnTrLC+HLCh>^H%g6lQeaIH1Pr~GHL~{qT|D*eV)&6!0Z0!Fd%fQL?Psd=OT;~wN zinaa*aFo~3z>O?GMW7=WHIe=t_Ct)@RH(GbL~j`R)vwN(9b8-G(cR(E{=-HwE(tZM zVxdz4zDvD-_lM;K1~1_ca%(tI7n~BOn?$@MbxRAu<;aBj+>wc;yC&W()#v-xr4vY) zdxE`g+)&2psWJoV2-8Au6bTWCq%|85Pe<i#7|^4#5@^~k?yWtHyJ!M~Q# zs2|h?k4jJ*KNok#{cQ7n>S|?`)Ag98aVJDBY$iI6>kD9-#VOHu@4pEm=f8re=4Jx+ zax!O8|EpjV`wupZjg5o*pFw3x^pjW9!i~7Jm-E4T-Svi__VQ`5!{82Kl5H$a9xrf+ z1UcP6Gid6rBEmA_$OTF4PxKR%KL&lv)7BGZM2=Km$v~D-xA+-me++INPK;7)W<$Br z?|Q96S`kum+2lSFnDOzaBumDil$l<=D&ulqT71~WOqwq*69s2&duzPcQ$`v}UpXec zl7E_!eqvoA4<^0pq!Y|!ABu1-dHjl?<4;RQA(Nt|T&BttuU=NLTklH96*D$jhhZ(J z-6YxILPt=fYOP(hVAb&Bq+uCGz>-V%F57d|EV>tS;}*K1H=oWdvB;IY_MGQQbkvZq@_kcXjhrT~g|Gwe0r@`-$2( zlB-v<#?2j&8NEl<|23=Wb;)f(hwCd5C}lot=yF4@RBrkAy#F_%e>ZHLI8tfg>6UIx{W;8niAf`4jy-KERE`)V$PhU=mrTK0{++#_ni~%-RNAQ+EoEQrFa`6%jMj zGrXZ+zqgFkym)q%Zuu$AkKlWU^{eYtnxk5b^BHt)KNyB7s@&#@>glW%6XHEE9jXl$ z*&t?OI*Fc;+Xjdcef7p88tv#qv1?nXj~5@_ zb{IBTCa5cnn!SGwfO5cOJ{5SCO(H2&<4nw;rWrL2Q1lsNexa6z-uSa|BxjInf5<15Vf*j>G|j^L~!+tHmak(cHkLpd*Ad9IB@XIOpPq;Rj%T<=r4Qd?tJ6HJrl&k z1TLckV>0RVR?vaaA6y?o#W6V1{|(Q$|HZTacOJ>k$?;Eq8O+JWgs`GRYR3ICp4^wc=6ala}&Yk9%c0n~Esu7Sni1vjX<~BPW>c-zHMOD>k^bAF*ZGJVB02 zovT2W3x`Pt#YZc<+gW0**3n>zovZMvhu8D%mlC?MM$`V?U1vGSk99ca)PsAY-@@6? zk2f64HpAJd8Oml#5SDM3f*YnY;u*edF?>-%&w3MrvGJ{y197rwZEazx=J(+juDgQy z=g8t#d9UO2GuZXtN?%oLfLkODFb!n?%{Bca-T%L`BPJs*>F5CdTYXsnlllO;S^tZq zH);8(f7Zg!MW+tIF9QzC4o}A}=r$rg9@jOyF}13y&(kY6HFb&!-vlO%%CQCtC&~1` z%t8fOk+ae&b3_+Zqcu0RuBbNYwXdme>@^Gcl#f(3c^sQRoKe!Z>vfcToMmV8@pxRk zb#Gn1Ts(9zH;>by+78yzr}%ivoF2Z#gwgzqLOYKxF|h5oLO(* zT5E2n@Ai3cf8+G5a^nPCKp*ynMBWj(n7gduX%oyVT~&~5W*rr+uA3t}GTQvBoiUR- zCe3!fJ+>0I4=k_ijh$1qcvk$>B3Yb3Wih5|l|wI4oZn;(e7;*g#^n{QnwwKO83Ssh z#eV6`C~hzV@+wqJdGb(-S0uw%a9$^<`^#%a?!M<$qR(^=VSM8rV*IMxVsT!4+|;*9 z$dpsQ_>&H3Z_-ZA;2Hdfx=Av#RQS=73y9+d`AH;=ydu$w5-LiZitf?FA{Dg1dCMJNploFF#sx2SPA5psM{wWB*}XC`I4PnpZs+h=jL22M7hwaoR;8Q zh;?nnvO-Ul|6X#&*#3Ss9YL>gz;s^AQC;4NBlLY>HAVuz?^F*F`=T=|?{C_8b*?$}oHHw%bEkH+e6L?KPX)p4-7z46jQSMWp=N?b z{DKt!nj+igAvx!_i7o5!b(;9^^@*OIE<^c)YT|1}9zA*643<=_Ub9)Ztu0CIGx|<( z!KoTQggg`-d-kD7mPN`Lw!iyq(ALK8mb7B$B|!N0+0*K#*0OWw!sHq`eJ9p1%AG$8 zh{69@47&3Twb^n#e@uZ;yV!)nJf&)&Txit+NYUSqx({J`+GM{PIbv)49M;zRLHenI z?eLlU+GHy%D?~g%srZcaK)&8VA?exG@tA1)in|N7FHxoToPewaSw3+dz!q*|>Q$DA ztXZ{{F5B652J*zHe4KNub|0m@EKWi$8W**;kaO>7XllFJTkz`%`XxpRRnmvo5)w#~ z;121$;pgssPmaWV^{O4l5a?m-x(B@2mdDo9Q}xT*y)g0oWjdb+^;?AsWcms8v;wOP z^+!)c7~J+DogShau~P#X<;ZM0f0XFCwKfhifWn~h=+2ceCuT<`PQKR_JUgaYX?{S< zrD-?t+0!l;jAuI(%qz8n-ff+SWFqW8g|l!yWUomdhYFk#e!DNmE5-y&$GL z#$2hAUprsE+y)=x0OK8tgcxCPuP)(537Sx0WQ`IL7)zhWokJhHQ8DSTl+ujbdf~-` zW>^zY_Lf?izn^fS{IV_(=5P-&1_+qB_Ej%34MsmsUHgv1Ttr@763^JPW0zQx%fP}Z zGhA`zF=CflKGUIxZFIT(xmNZ&)5OH)=YqR~XS~Ec=z{9&3j8h9eKt%KxU*5sP;*uY zA`3?oT{ZncYbx>$Jpb(KS83(ZG7Apvw;Xcvpp0l#H0NbO#)Aj)#WyzdJ>K$khKm$O z%nCf@uKPLorc~@Gl$>U`0ugt&-R8~cD(Yn!s(rP!#87kGbXF(*87-6nKpWBSSrg_w ztc)r35|$JToHK?MrGB2DBnOSSn{Q@wPz+a@q;CT5Pf)zT5kL;Z)EL9eA780TE2)UF zWf3py_)ndE*zJG5Z1)}H480)@MC95Tj7Hd=sj)D0y@@0}ZpE%Vp48oZP^i`OpVq({ z-#LpvPKU!36mzIoVI2liJ>7ORvvmK#*CsiWmU2snUIqRoy|H%F{iH&C%f3*FLQQPbYY6VKFx6Ak^N3@bp zo)?m%*p^1rpLV;sI0433hJ~U(^Pa0P(uNGeBr0BjilJ);gSuP==^c5H+j(@Yna=Mz zo-n_58l?T_^2ckVH9 z-%OD}{18cSjnI#BMud|I*=p_=wxk|zMe~%4j}l8#T<>32&-vY~*QcXR+|biKXV<(U9TQg9xcrK#bo*@;Au#84PeYJ8 zs8g{!2}M>LJ(bAGLwgTG75@EmD{8R}94DK0hH4uAnD2%>6!xU~j{Xe2ZZ$@xCjANQ zfj=*@Wz7I8hVSW`pMchCjlO^B2Q(w-J%hUXq1w3S89H!hWalQnfG~(D;N|WLa8Tke zwQJ%;G!Vb>@yuhYE!!8iOizu)*zQ^IR*35IsfXw>9w0VHch!h_BoxEW_ND&x-ifTT zcNl=sChPD$bSPFgRYs1n<=Vnq;ck_XuBR^b_t=pU$}Oycl{JN0pLC9&JkpqnvXL-* z(iApTjjkA=C|VM6G6aIDv_6FsGY-(?2Eg*f_x<9N_td&Zcr27Q?(@0!vMxBSj&(=- z)-QlJRYnTN=k+e*tc~89&XkdXQq0&M{j$2V&#Wwk_|#O_%fl6=RMl-u&oQ~K_G>v~ zm6qmFC&GjU6I7Lz4zy{RCnzoAu*s{queKuy3i3*-F>g+{f1qByOHXD4Qs5)7tF*g+ z&HRo$2d3MKXMoH7Mw$m+zOlu3Xt~XktM?wT`Ej#dTU^W^*Enj%xF$6nK}`$e-q<;< ztwQE@4{ZKGoDPhW@kxh58iCE?{)wBzYXThp(Iq2aT5g(989UWx z7`0e@ItCfyeb66uO#Hl*u@{hzX7HX$h>uGj@r6)=6TPrHavHw=@|1|DI{ zqeTvA4Zl)8w zEYQEZT_D^4C@Eq4XHH^kWVDTru5P5BwcA(QYmb2hO^ejnjT+dVMUj+^F{vkP#9BSrH;B<;BI( zr$zfgJI3-L3{`YV^;q(xPXI;hV?inQ^D-gIR}czo9KS!n=2K-dkrg%f9_i{Za+7k15O+sJz>&t?||Lz`EtD zvlE0bnL32%w(cHd2cDbP#S{JM8Ms+A1%P+0>0fGiSJdIBU*WV(!Tj4MSi3djbvlS$ z847n)IhtYH5n@w+HHpQe?cET*!S|JRfhg3+01S1CAr&|PM-`A3S>4{EXMo~LP{Z;m zCym+-wxcXP%isF$e7bT1@%K@=Cv9`ZZxH)RJM&M~V8JnCLaiG0=V;h9IB=a0M_Mgk z?BRgOOV|_5CcF+ZH`jA7gsM<2U?8J{A-de#@%eC@E+y zn}Ib1ZCBG+<|V)l&JCHYj zq*FtW&*6tiW~kGekwJ^sdyh3I5kfVB8c zEDC?s*3CJ1A)d| z-0VOekhuj1(9E0-WMTeS6SpZl5NOWE&CVtG{~uw%qGs)FjtFFD(b8l4YiXdtf8Y>^ z^`8)=n&`j?B*hY+HMoK;xe+LOEYR%+|J`;;c-ny%Hxa(6}jz4qM;3zHX#G% zLA4B&n=V&L4zJO>2vk`dF4>rPy;ptdg^wwMclq~dxPpycz@9GV7Kk8LP7XvWDhVY? G#Qy~(KaR%$ literal 0 HcmV?d00001 diff --git a/img/exec/rt_graspels_qa194_20_20_20_speedup.pdf b/img/exec/rt_graspels_qa194_20_20_20_speedup.pdf new file mode 100644 index 0000000000000000000000000000000000000000..d85794cfc45536ebe38c8442e512452da2f79955 GIT binary patch literal 9313 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 literal 0 HcmV?d00001 diff --git a/img/exec/rt_graspels_qa194_24_20_20_seq.pdf b/img/exec/rt_graspels_qa194_24_20_20_seq.pdf new file mode 100644 index 0000000000000000000000000000000000000000..b138862262b400ec2e32ca07ae636716c1b55bf4 GIT binary patch literal 7069 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 literal 0 HcmV?d00001 diff --git a/img/exec/rt_graspels_qa194_4_20_20_speedup.pdf b/img/exec/rt_graspels_qa194_4_20_20_speedup.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f987fb97a00fe2f33032995e40fc50cd89fcf56e GIT binary patch literal 9305 zcma)gWmH|u8YID;g9dl^gL`lZ?(Xh(kl-$X1b2rJ++BmayK`_0?moFA>)p5Bn>+KP z_v#r~AuCKnLQWBSB0y1+VQte)xJ|F^FNm)r9O>7Va1Xv`k?Lg)(ERuG{AaikZ zQ%5s%7CCbVOOO>Q8!IobkPxCP$i>{)9?^4UT~9uSunE26S@YtMFxe!Iu@)CsG{1`r zyt;z)K>7eUwZVpFpr}QAd#*H5tkWK^$+U|x{mzk|mEANRvluh(WtLzogvTP7(URrgi{Q|TMIt9yl5L)e5<2xlE>+p-`{5*_HV}gc;n$d=$7)Z z+f)3E;mg7L&gR>t$H2*_>oZIBf>gUJgam};{aDcod>C0Z9|y218YGECjthEop{AAL zXdd(=Ts9dSVEX5_$#Lbe$ip>S9KCC-tq+<)c6kEtsc#1j%m}%ue4_E+sw@D4QU7%92SC$>PIz zYK_sUZ#5!g36M+&EJ#c!qNA7zLRTEXj%1}zF>N`I3U^XU;onpzawE<4C>`D8^ zR#YyK+AVUyQ2>}ct%zr*N+y>+FVx;{s0bFLwov73TU_eS&Tble96l#v2eFHfVoJ?F z3yVo-su}HJYc-kk;10I9U|)}+^Cg;2Y`J37j1bl8KOIg-KA=o@>IC%Q5Pn6)LouUH z8w%ut734$zMK-p$#NtjBuK(Lm!~*hAnji=@Gh!XE8mjNi1*53b0sB>9nFZbPFT^eg zg1x@o{4UW)D5iKt9O;5|UF&}*&WhLsjD{NSG6&}`I6`UDooB}I{k}gGe+dH^?C^Qu z4WCNBqF_aPibN115@Gp;Pb8{+V9F8VNZ6d)W48!8MJEqw`B(3Q8Qz90V|vVP<$@n0P`5h00*r>Y6sBQC zV;||7kmLVih-eykrpeyri-bnvZeaxT0g8aIFJCa|uZ?g6juD%^Mbb)?Dve0^rKMSW3?Okh(* z<+dP9>IB#6(cejbt|##4dLQ7&2^pJ(btYkhoT5;z4sg6YwWc5%_HP^J5yq z#)GU2zx-K#ZQ|$+O=fh7i2$h;_mi-`v|+dJcVfSYylpZ*<_H}J#jVCL((rn>R(p-R z?c)bOrf(kL{G_Z_0Zwx0=`7S{md@GS98a`Ad>-&<pQnC-n*AJ|#Pmctky zlo_&}r65IvLLCLlaFEc*R>`9hdqU%E7ZazT9Qb?DoE0QJx~4rLleExw8esi!Im`Fi z((`db4g9p(ev|g=8LYS6?RLT9D0&ejP`Mf8xEH7!c%b|BrDQ#)wv`Mn z;^-JU=>WE0m{EhciYU`$iLRB<;6#xAc|Yh{lfgQfNbT~Fu^(OLG69!oPA~W8@UY6( zWo{F^)BviJ;ULuQ>(IIMXi+rMu15*$zT!?)IMR1apZAvwZpUy}g78U4*tawPQO`Bs zmp5(?5`T~O2}^GNPu!aoF7FaqllGgHXvXL7!=d(Q#(6?wkpL|&y&vr&wU^m3W;rD-+=7`%O+E_M zW~~;&mCP0qzP!-2G7`k5j_Nwqj9(n)4Mmon49XA65cQ9x*?Lo4HHQ%B_3e3jQS8J;km<2?Q{opn;NhMe5RWY6F&qIxt%6Y7o+;sq7^oxK%(a)!}{ zb~b^6^BTWs9;-Jy!<*GTBibox0;Ocjw5+*D%ah7+?e|TK$*d_+Ie*1*`L45tnyCsN zp&|kB)KmkRw)eT@-4Vkn6Re}#3ekt0e|!>ukgaT9-;FW~H1(Q!;#NDFT*r|hk>L&? z&Z>i9v}2xw)Y$VDqYOjX86{9OjNrF{^Ec9MUSlg`9wU`N&7r$od!y|18ly$uk^+gO|QSPpsoAeF_f+MrXrd(4tWtGn6tS^jl5L8bBvmE9bqt1T^@YyYeh^RK zcSu6WiyFvq+Dj=^8?rn0hSW^mm%i1$AKi&F4+1%yTz38UNbBV;O#cNou7AO%>ShA^ z;$+UE_U8i>`v?05Wa9w-9Y&@&ZzW7ktZ zL_Q%_D>=~~iU2Yo>>=(KJRUJD5n&NBi~*pQc}Ro`dJTPpO}I|I7NdHRD3W~%s+VTU zr`D;r>+v<$gY4(5YYK$82vQjro!;QTyo7ftCtRPEXJ|W2s;t;(S9Wcyt+ZS@#;fPD(9iw8)X6`n334*g8h(I;EdV z^eIg7p+kG0wL_FGKQ9!|ngea>L@d=Z9>vlbg~Srd*;ma(7?3SoEtac)yf=zWhBjU*_kY|WN;Gl=F?^ng0O~Q zWF?@13Gk$}LDU;$7MOv3geG4DND_MZ`(bPviX)p+6ekkd*$K|{w^n?CH zp)h$nqw~;XPf+903s?){cdBYXp}h0e+6t?4nsjG7v=S%}x&@%x{+_1wP|gIR1K#;P zmn;-@i6Yra;GLf{v_Vjb>1nBlRI!M(@+yP($9Cd7gH&FFelQ8?)ItY7uuM#o;LOeN zY_-T9b!tJ(0ufwxO&Q1n(-Fg16-NokDVEygHtb{(d`wOVU>^3hcYJxXkwzf0S@ zvb14(!OG|=50{Xt=**pS6Pm*lC`T8%x2j?Hb&JcHF3_FdKO?jls6j6Djlx%Mo7}W} z0;&b(F(-J>-}|L9T>bj#)VEzoV@8(h$;2DFj$3~1_&0RbJ%0UFzBd(mf6_tWq@*Cy z60~1&Eg>};VeGG*6JkYFxdfx8@O?s)-$q3ba^f!dNN+tS`kr^f!h@R##O>$Y$DD0= zWmdn-2>0NrKe+E5qQE=G&0%LVSwV&ry|ZfR@AK%9GHqo=5iYc!E;QtRn2#g6eVj1q z3_}(6`<~cFUL*1b+=ox(LrYR$;P4O(Q*bI9vFDU2)L9BEZZZm3VsuO9vW`I{Cp*)* zW3r5_`++gFtm7dj*2upnD;7v!e?Y+)uTll{0tV3?{a}CYE(z?$@d&u*T|lkyR`|9f z{F3Sr3uY78c~SrQp*^(HEU_%GuRcsqb3E-U(mMaIw~&nf@jWYtm_)D9dE=Yqb1j}1 zxc7KOysZ#q&Q93)MjcGR-5&AGN%xYz=h_15s}rQ44ZiQhT$lMpU#4_WMKuwIk#6G# zZW%qBVwh=(<@sIQW^;IWh#mFw*UI7`m13zi5#Rw@|2&)`c>+)9>gf&+zb$=dStXy! z9enAdx=r6*CN`n9jIxufDi7V*fo6*5Bby%Ih+a~c+rjNsrC8B-LHo9EZ&An31kK4g zt-Whu1gm32b2*-PW%=rssD3aFhpTNH&mA6(;y^%=d;}+{CiAQ5b&^7Jc$lce(8mx7 zXm%q8`J1!iwM{!0ON!&Yftx8$c+vA;TKr+YVQ>cQP8)tQ2kV+St{kl}OiHt!Pb0I> zE8nV(6~rHK%&q25KfpS0t$&&M{=&q}Rf4BMJs=ly= zfRC>+9v^>|XCn5O<8LHxP^_@xxr|qSJ}>8jcy3O22`UBhz;QsGZjk7qGeDhN$}wPg&gDtMqKyLtW>D{J-lrYj8`*qVu=d(2DV=nHy(eCT*8$s+pGK+ zxOo2s*Z+5MVF&(OZ80@7GB!3cGuw5&yZClOrX}m^>KPhR)|j<7GAg$; zGTO~FRMJjN%T~_MjVmuPva+_WEHE-NGAaS5X6PiQWu_K^GqmF4(lfLmcXw%_4`?iZ zCacj~Etw@IVrd9ed#6qe7ms!G&Vz=TOXBwuV!U}RjJ#E}%-=6%w-As&gJ`5Uo|Fi7HZ zyS;t;&*<-G&|oxZ7yVuZ+Cn?9p0)6q)E~OzcgAlc{22AR@Thy%91wJ zd;OXR4*}t9di|eNu(AD%ivRn|W#{Dlx0gGkYa7gp1p)T(mmubsoc3H74pBd$*7Ybk zMU&o{M&Jx9Mti+y=gmVyqV;LX%%mI~FU!Yxm0NS{W&-Y zOFhg(OU>t`;%JX2GumK|8nM6GOtM`oJL;b{Gi%+caNnM4q2m{DrOdAuK(Cyq3@#u~ zB=TlMJY8a^mpoNcEG9JfpjCpgal}$qi$wf}F-d!;lxi9MOqF`jT7kZgXF3LbttVzH zfy-W_Y?AmbK9}_bdNOutZ2P(7^O%pLxCb@!H%Ql`JNMh$lh&3L6vIRvl4-0II<(jL zjsWl1VdZ1>{b#7)usW3g!qeYu?Em>?#AL)J9UVY_*)rCDvSn=CtXzMmuR+sW4O0_8 z2S6Q+U&1!X6kLd8wfwmM}G>X))PSuK8231cWd--;k#d0OCqF(M6{@BNCB02k-KJ@&bdi(+qwex_tm2FaiXk zl!gd*nc1i>9z&a|&D`?s^lRk`Pg?+7n^b^ zvL)5v3)*rxtp30sF4dm-sWfYR4*8%riC9g!! zACH5@4L!nslkUmYJIE(KxjG&bfiIc_QM=>Nt50>wnxN(4=Wu{wCZ^hvamX4KEOKNU zIxd9m$jQEYe7fvr@gB;NVHoCt90j~(s9_+5R>K11_4=28;iVaP-uiIxPo;#*5GUkNr$ixYET0%DG6w3=}s5um^dfukm zrOYY7eSzF!JD4qZkyUtF_fO#FNfjMC#$`*&gCEQ$Un7WQhy-;$^L91273Qj%HL+DR znRbS&<{1tVb|$^?kQjCSLW8%T;{(tJN|3WwUD*zzZ-?thQ>qGRhwVX<0APfAg}I^) z_xQg2T;-4pkAzfSLJ3m`CCERv=`;dHx4A~IX)&8AdVcu}G|6j~XGfA^;|f=FEe6zT zg=8NU2vfS>UxmtwxdC-$Qs0+w=SZsCO%v}Cq3D{f3DD(smuK|VhwCR8U6vI0cKZtg8M!5CHBn9e=_$1-|6ZXW z{ROP<;edAlT#5(IJqt34U#%M%N#*opd-=^BoXocWti^Vbt z9q!T+65xw0&&hPYy|2y0g{tDjO4Vq&hm0UBwxj=(7rqqN3qxGPr};9GbFgSf!wiso z*F9JtgY~rE+leicj|A~SC3ejhK@K9}d<~N4@pFUtMBm}|kd}U?4IDbjq8D4%Or{aD zyR3JbE1Y614ccuJF_i-0Vn08fr9hp;z~YYf0}c|-Qj0LxCc2X&F2{GUDzVkZ%j%Se zglHyn6vz|}X~#ufhLAIv4|Qe{aY{6!ZbirOD zM2Ny`pifBFve_HINjCf+H3j?jB*qfJYg@dD$X>Eh=%5PiaT z_`8P_u4PxX8H@of9pSK^bkYrd?T%p;GQqjg`inCQ0;R&^&ZcZhQxPV0WtF1x5kI`- z2`vbnsTr>Ul{Y6wv~k;OP=~RHAPgi}(aJB>jRb8}<ZjNvWbNK~;WRziUV>O%^xR|#?oG#c<(wf;sHu<5M3Ps6|81pRQPZw>{M*>> z9Xs;_LBbO;%zg|4hhzRU-)%Yyv|okVD2Ju0-IsN7jIg2C2#2V(uqde2#U^tlz zT?Z<@T>(=EN@7HUE=PB7L_j;(V(sC}c@4NT1PO?%6uqAoO)Y7|hM(s1CJdp3F690^ zFdf6+8dc9^mR}>DMYF!gSWUz;wRCA*&%lVQu!0IhiPcg0z}|kBdI+^e(b5cyV@gwo zh(YHG{?r&M6&?~N2p%toIG6eGzW?s5)@6y?Y$W5V;5uQ@(fK1f#H6{J4vrDx%}QR~ zO}}H#f9_|~32_&KRU0f{ShoSU0jtgpAi9LHDsipmem#pIlKg=XDiO=c%Nb%T`9ukT zmxdE3jxs`_SWcNsOAD_MKI_;4U;PUiMUO`=G^aVgSsG%F6O~mFdVk@2y&I-~75IY= zt)~K2cZLy`_}%XXk#g9+KwPlyi52YIGni{;)0I8F2YtKcf!; z{w;m{hpyz`8bVtmBQOA0ONO@+wvfwKJ1BY=NveExFKEQ%&J zsvvt71yUgQpNP}N6+{XIa{N=+$;!q4cUN7ZZm77!1MuHe+-ic!TQD80$-*qHtjF@2 z3bx;xq8kyDUdJe*RNr=S%6S`5_^j)oU7_%Co+w7}{Url00|-e;8I3>=kNFik#8n0t zg9u$Ah?O*&RyZz}790I%cvRL`F@D_h$<^em^!% zQPIuIyup~A4ayTVTVb$^x<;K_Iv#RAQ}jqr{#ryH$)xMtT>?bb){n)4CiS%O=x;}- zPU7cdWraHjAZu6@UfUs_qub8h!dsV`%H$Z@OdZ?OAk=Z$?6jl)Wd-n}2uUmWlOFC3 zLhi?=?82$})mug?{dET(n2sVa7rv{iYDxw@J16-L)Gu#c0#GN&KZ&kfteMx#IIhAJ z_Pb-jmy}9nqn#f|>OxhfRS8p(X$MEzkNEsV#5K%TJ^8t1;$@$Tp5J0$C zWMKqC-10FeM*NLQ3PM5%|6EF80CH!IELKwD7ICmf6q6)$=Mt|ZUW9+3UxW)G+p;i#y5j2f3Bt=Mu`Z4hV z9boU}xbXAPl6ixg3Y56oM`NclfznYmK0Z)+1$li?*F4@hc|zK7RH~O>i0d1Fx-@<# zc}2DV+0E_B0K1a&(C*rbXh#FLgW)_%Kx}ZyePdiqs7bNmWQn@5v@y7-o?LYHq&_P= zKD)5ta^InI{oUQ)jV)CU&l65e)l$840K>5U|lHN!q@t0FM&!0uHMkHve}%n zIKlZERm>tbmE3Aqe3bB9%Fl=DcH5@d64UBq%;!s9XA+{xS{4~Px6p)8r7 zZC}}3oWAUOu`%V$28meOBxk7W@Ln$KeuIyRk~lhlFgI8|J}v&lLNX5QDA|YCtr5VV z1WL8|@=Ge7+>QveCAJLin&NS!^jv({)X7CVTYoXut`E%>A;#(P=080i7``z~?zEAi z&3{Ej(uFa@{%fZ1|nM|Q3^a}D{7Gb?<*fZx1N7pBxYsKI%DSUJk;SnvRsVE>)@KXr)h zZ_(lZ)FCYua|;#~N5?<<^Cy~7VUcmLa3uXpto}^Jbp?3X*iB7&O}JUjj7>~=%{Wbf zX2zVRtj0hSPEIxpb2Fj;_X>R$RckMEL^d84OEwiK=Z9xfO1&B}M zo%P~UsECV-V$KQcCW=VnsfnWu6v$`4Sv5eIjDeLRRd&fSu_`XeBeHQnU^j1Qz+{Y; zT0H*@ez)U7j#8%~EE?P&daTE9CO$G<4J2`LhmZPCY+OOcE+9`Aa|=XXR#sL-Dk=#@ HNyPsFRS946 literal 0 HcmV?d00001 diff --git a/img/exec/rt_graspels_qa194_8_20_20_speedup.pdf b/img/exec/rt_graspels_qa194_8_20_20_speedup.pdf new file mode 100644 index 0000000000000000000000000000000000000000..3fcd73b4c18f624adfb6465f96379b638eae565a GIT binary patch literal 9313 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 RIe?d)od-ZeBdII}_%Ew6Y)=3H literal 0 HcmV?d00001 diff --git a/img/pfor/ct.pdf b/img/pfor/ct.pdf new file mode 100644 index 0000000000000000000000000000000000000000..ae79f8647e7d78e3ef3d61ce3055f0f7222338a8 GIT binary patch literal 6941 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 literal 0 HcmV?d00001 diff --git a/img/pfor/rt_par_10.pdf b/img/pfor/rt_par_10.pdf new file mode 100644 index 0000000000000000000000000000000000000000..dcf1742df31b397d012217807be9e2c70f884f64 GIT binary patch literal 9583 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 EFNSItDF6Tf literal 0 HcmV?d00001 diff --git a/img/pfor/rt_par_14.pdf b/img/pfor/rt_par_14.pdf new file mode 100644 index 0000000000000000000000000000000000000000..b1e77278d43a97506d5ade13f0c9dee7316ec7fb GIT binary patch literal 9588 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 F{ug7|1Zn^P literal 0 HcmV?d00001 diff --git a/img/pfor/rt_par_16.pdf b/img/pfor/rt_par_16.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f8fac2d67a558833979060a32b0a8db71321ef02 GIT binary patch literal 9591 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 DmkkLb literal 0 HcmV?d00001 diff --git a/img/pfor/rt_par_4.pdf b/img/pfor/rt_par_4.pdf new file mode 100644 index 0000000000000000000000000000000000000000..e4a980d4f2c3a8d515b92feb605ace71a9eb70ff GIT binary patch literal 9583 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 literal 0 HcmV?d00001 diff --git a/img/pfor/rt_par_6.pdf b/img/pfor/rt_par_6.pdf new file mode 100644 index 0000000000000000000000000000000000000000..bbcc718de1606cef6b1be49e9cb22733e9a1dc14 GIT binary patch literal 9577 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�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 literal 0 HcmV?d00001 diff --git a/img/pfor/rt_seq.pdf b/img/pfor/rt_seq.pdf new file mode 100644 index 0000000000000000000000000000000000000000..a8c84c0f150a54bd789fe7976a9417d7ab3630f6 GIT binary patch literal 9656 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 literal 0 HcmV?d00001 diff --git a/img/repeat/exp_1.pdf b/img/repeat/exp_1.pdf new file mode 100644 index 0000000000000000000000000000000000000000..c864d9d2e49ea9a67fd4886dd76f6a3d87fdcd34 GIT binary patch literal 19173 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.pdf_tex} +%% instead of +%% \includegraphics{.pdf} +%% To scale the image, write +%% \def\svgwidth{} +%% \input{.pdf_tex} +%% instead of +%% \includegraphics[width=]{.pdf} +%% +%% Images with a different path to the parent latex file can +%% be accessed with the `import' package (which may need to be +%% installed) using +%% \usepackage{import} +%% in the preamble, and then including the image with +%% \import{}{.pdf_tex} +%% Alternatively, one can specify +%% \graphicspath{{/}} +%% +%% For more information, please see info/svg-inkscape on CTAN: +%% http://tug.ctan.org/tex-archive/info/svg-inkscape +%% +\begingroup% + \makeatletter% + \providecommand\color[2][]{% + \errmessage{(Inkscape) Color is used for the text in Inkscape, but the package 'color.sty' is not loaded}% + \renewcommand\color[2][]{}% + }% + \providecommand\transparent[1]{% + \errmessage{(Inkscape) Transparency is used (non-zero) for the text in Inkscape, but the package 'transparent.sty' is not loaded}% + \renewcommand\transparent[1]{}% + }% + \providecommand\rotatebox[2]{#2}% + \newcommand*\fsize{\dimexpr\f@size pt\relax}% + \newcommand*\lineheight[1]{\fontsize{\fsize}{#1\fsize}\selectfont}% + \ifx\svgwidth\undefined% + \setlength{\unitlength}{229.5bp}% + \ifx\svgscale\undefined% + \relax% + \else% + \setlength{\unitlength}{\unitlength * \real{\svgscale}}% + \fi% + \else% + \setlength{\unitlength}{\svgwidth}% + \fi% + \global\let\svgwidth\undefined% + \global\let\svgscale\undefined% + \makeatother% + \begin{picture}(1,1.12532353)% + \lineheight{1}% + \setlength\tabcolsep{0pt}% + \put(0,0){\includegraphics[width=\unitlength,page=1]{raw/cpplogo.pdf}}% + \end{picture}% +\endgroup% diff --git a/src/acronyms.tex b/src/acronyms.tex new file mode 100644 index 0000000..6ee048a --- /dev/null +++ b/src/acronyms.tex @@ -0,0 +1,80 @@ +\newacronym{ABI}{ABI}{\en{Application Binary Interface}} +\newacronym{API}{API}{\en{Application Programming Interface}} +\newacronym{ASA}{ASA}{arbre syntaxique abstrait} +\newacronym{AST}{AST}{\en{Abstract Syntax Tree}} +\newacronym{AVX}{AVX}{\en{Advanced Vector eXtensions}} + +\newacronym{BLP}{BLP}{\en{Bit-Level Parallelism}} + +\newacronym{C++ AMP}{C++ AMP}{C++ {\en{Accelerated Massive Parallelism}}} +\newacronym{CPP}{CPP}{\en{C PreProcessor}} +\newacronym{CPU}{CPU}{\en{Central Processing Unit}} +\newacronym{CTAD}{CTAD}{\en{Class Template Argument Deduction}} +\newacronym{CUDA}{CUDA}{\en{Compute Unified Device Architecture}} + +\newacronym{DSL}{DSL}{\en{Domain Specific Language}} +\newacronym{DSP}{DSP}{\en{Digital Signal Processor}} + +\newacronym{EBO}{EBO}{\en{Empty Base Optimization}} +\newacronym{EDSL}{EDSL}{\en{Embedded Domain Specific Language}} +\newacronym{ELS}{ELS}{\en{Evolutionary Local Search}} +\newacronym{ET}{ET}{\en{Expression Templates}} + +\newacronym{FIFO}{FIFO}{\en{First In, First Out}} +\newacronym{FPGA}{FPGA}{\en{Field-Programmable Gate Array}} + +\newacronym{GPGPU}{GPGPU}{\en{General-Purpose computing on \gls{GPU}}} +\newacronym{GPPL}{GPPL}{\en{General Purpose Programming Language}} +\newacronym{GPU}{GPU}{\en{Graphics Processing Unit}} +\newacronym{GRASP}{GRASP}{\en{Greedy Randomized Adaptive Search Procedure}} + +\newacronym{HPC}{HPC}{\en{High Performance Computing}} + +\newacronym{ID}{ID}{\en{Instruction Decode}} +\newacronym{IEEE}{IEEE}{\en{Institute of Electrical and Electronics Engineers}} +\newacronym{IF}{IF}{\en{Instruction Fetch}} +\newacronym{ILP}{ILP}{\en{Instruction-Level Parallelism}} +\newacronym{ILS}{ILS}{\en{Iterative Local Search}} +\newacronym{IPC}{IPC}{\en{Inter-Process Communication}} + +\newacronym{MA}{MA}{\en{Memory Access}} +\newacronym{MIMD}{MIMD}{\en{Multiple-Instruction stream -- Multiple-Data stream}} +\newacronym{MISD}{MISD}{\en{Multiple-Instruction stream -- Single-Data stream}} +\newacronym{MMX}{MMX}{\en{multimedia extensions}} +\newacronym{MPI}{MPI}{\en{Message Passing Interface}} +\newacronym{MPT}{MPT}{métaprogrammation template} + +\newacronym{NUMA}{NUMA}{\en{Non-Uniform Memory Access}} + +\newacronym{OpenCL}{OpenCL}{\en{Open Computing Language}} +\newacronym{OpenMP}{OpenMP}{\en{Open Multi-Processing}} + +\newacronym{PEPS}{PEPS}{Premier Entré, Premier Sorti} +\newacronym{PGCD}{PGCD}{plus grand commun diviseur} +\newacronym{POO}{POO}{Programmation Orientée Objet} +\newacronym{POSIX}{POSIX}{\en{Portable Operating System Interface}} +\newacronym{PRNG}{PRNG}{\en{Pseudorandom Number Generator}} + +\newacronym{RAII}{RAII}{\en{Resource Acquisition Is Initialisation}} +\newacronym{RAW}{RAW}{\en{Read After Write}} +\newacronym{RO}{RO}{Recherche Opérationnelle} +\newacronym{RRID}{RRID}{\en{Resource Release Is Destruction}} + +\newacronym{SFINAE}{SFINAE}{\en{Substitution Failure Is Not An Error}} +\newacronym{SIMD}{SIMD}{\en{Single-Instruction stream -- Multiple-Data stream}} +\newacronym{SISD}{SISD}{\en{Single-Instruction stream -- Single-Data stream}} +\newacronym{SMP}{SMP}{\en{Symmetric MultiProcessing}} +\newacronym{SSE}{SSE}{\en{Streaming \gls{SIMD} Extension}} + +\newacronym{TAD}{TAD}{\en{Template Argument Deduction}} +\newacronym{TBB}{TBB}{\en{Threading Building Blocks}} +\newacronym{TMP}{TMP}{\en{template metaprogramming}} +\newacronym{TSP}{TSP}{\en{Travelling Salesman Problem}} + +\newacronym{UAL}{UAL}{Unité Arithmétique et Logique} +\newacronym{UMA}{UMA}{\en{Uniform Memory Access}} +\newacronym{UVF}{UVF}{Unité de calcul en Virgule Flottante} + +\newacronym{WAR}{WAR}{\en{Write After Read}} +\newacronym{WAW}{WAW}{\en{Write After Write}} +\newacronym{WB}{WB}{\en{WriteBack}} diff --git a/src/alg/alsk/grasp.tex b/src/alg/alsk/grasp.tex new file mode 100644 index 0000000..69fe8d4 --- /dev/null +++ b/src/alg/alsk/grasp.tex @@ -0,0 +1,10 @@ +\begin{algorithmic} + \Function{GRASP}{$\textcolor<4>{colLinkIn}{N}, \textcolor<4>{colLinkIn}{P}$} + \For{$i = 1..N$} + \State $\textcolor<4>{colLinkOut}{S_i} \gets \Call{\textcolor<2>{colMuscle!80!black}{heuristiqueConstructive}}{\textcolor<4>{colLinkIn}{P}}$ + \State $\textcolor<4>{colLinkOut}{S_i} \gets \Call{\textcolor<2>{colMuscle!80!black}{rechercheLocale}}{\textcolor<4>{colLinkIn}{P}, \textcolor<4>{colLinkIn}{S_i}}$ + \EndFor + \State $\textcolor<4>{colLinkOut}{S^*} \gets \Call{\textcolor<2>{colMuscle!80!black}{sélection}}{\{\textcolor<4>{colLinkIn}{S_1}, \textcolor<4>{colLinkIn}{S_2}, \dots, \textcolor<4>{colLinkIn}{S_{N}}\}}$ + \State \Return $\textcolor<4>{colLinkOut}{S^*}$ + \EndFunction +\end{algorithmic} diff --git a/src/alg/app/els.tex b/src/alg/app/els.tex new file mode 100644 index 0000000..a1d02ba --- /dev/null +++ b/src/alg/app/els.tex @@ -0,0 +1,20 @@ +\begin{algorithmic} + \Function{ELS}{$P, S, N, M$} + \State $S \gets \Call{rechercheLocaleInitiale}{P, S}$ + \State $S^* \gets S$ + + \For{$i = 1..N$} + \For{$j = 1..M$} + \State $S_j \gets \Call{mutation}{S}$ + \State $S_j \gets \Call{rechercheLocale}{P, S_j}$ + \EndFor + \State $S' \gets \Call{sélection1}{\{S_1, S_2, \dots, S_{M}\}}$ + \State $S^* \gets \Call{sélection2}{S^*, S'}$ + + \If{\Call{critèreAcceptation}{$S'$}} + \State $S \gets S'$ + \EndIf + \EndFor + \State \Return $S^*$ + \EndFunction +\end{algorithmic} diff --git a/src/alg/app/grasp.tex b/src/alg/app/grasp.tex new file mode 100644 index 0000000..6f7ce85 --- /dev/null +++ b/src/alg/app/grasp.tex @@ -0,0 +1,10 @@ +\begin{algorithmic} + \Function{GRASP}{$N, P$} + \For{$i = 1..N$} + \State $S_i \gets \Call{heuristiqueConstructive}{P}$ + \State $S_i \gets \Call{rechercheLocale}{P, S_i}$ + \EndFor + \State $S^* \gets \Call{sélection}{\{S_1, S_2, \dots, S_{N}\}}$ + \State \Return $S^*$ + \EndFunction +\end{algorithmic} diff --git a/src/alg/app/graspels.tex b/src/alg/app/graspels.tex new file mode 100644 index 0000000..8774fc7 --- /dev/null +++ b/src/alg/app/graspels.tex @@ -0,0 +1,10 @@ +\begin{algorithmic} + \Function{GRASP\textcolor{red}{$\times$ELS}}{$N, P$} + \For{$i = 1..N$} + \State $S_i \gets \Call{heuristiqueConstructive}{P}$ + \State $S_i \gets \Call{\textcolor{red}{ELS}}{P, S_i}$ + \EndFor + \State $S^* \gets \Call{sélection}{\{S_1, S_2, \dots, S_{N}\}}$ + \State \Return $S^*$ + \EndFunction +\end{algorithmic} diff --git a/src/alg/app/greedy.tex b/src/alg/app/greedy.tex new file mode 100644 index 0000000..20a798c --- /dev/null +++ b/src/alg/app/greedy.tex @@ -0,0 +1,12 @@ +\begin{algorithmic} + \Function{glouton}{$P$} + \State $S \gets \emptyset$ + \State Construire la liste $L$ des éléments insérables dans $S$ à partir de $P$ + \While{$L \neq \emptyset$} + \State Évaluer le coût d'insertion de chaque élément de $L$ + \State Retirer de $L$ l'élément de coût minimal + \State Insérer cet élément dans $S$ + \EndWhile + \State \Return $S$ + \EndFunction +\end{algorithmic} diff --git a/src/commands.tex b/src/commands.tex new file mode 100644 index 0000000..813ae8b --- /dev/null +++ b/src/commands.tex @@ -0,0 +1,4 @@ +%{{{ alsk " +\newcommand*{\graspils}{GRASP\raisebox{.175ex}{\texttimes}ILS} +\newcommand*{\graspels}{GRASP\raisebox{.175ex}{\texttimes}ELS} +%}}} diff --git a/src/defense/0_intro.tex b/src/defense/0_intro.tex new file mode 100644 index 0000000..94d414c --- /dev/null +++ b/src/defense/0_intro.tex @@ -0,0 +1,25 @@ +\section*{Introduction} + +\begin{frame}{Introduction} + %{{{ frame " + \begin{itemize} + \item[] Performances $\propto$ nombre de cœurs + \item[$\implies$] besoin de bénéficier du parallélisme des cœurs + \item[mais] difficile donc sous-exploité + \end{itemize} + + \vspace{5ex} + + Problématique : + \begin{itemize} + \item[] expertise parallélisation $\neq$ expertise métier + \item[$\implies$] besoin d'outils pour assister la parallélisation + \end{itemize} + %}}} +\end{frame} + +\begin{frame}{Plan} + %{{{ frame " + \tableofcontents[sectionstyle=show,subsectionstyle=show] + %}}} +\end{frame} diff --git a/src/defense/1_context.tex b/src/defense/1_context.tex new file mode 100644 index 0000000..9c8afa6 --- /dev/null +++ b/src/defense/1_context.tex @@ -0,0 +1,5 @@ +\section{Contexte} + +\input{src/defense/1_context/0_par} +\input{src/defense/1_context/1_app} +\input{src/defense/1_context/2_mp} diff --git a/src/defense/1_context/0_par.tex b/src/defense/1_context/0_par.tex new file mode 100644 index 0000000..71251e0 --- /dev/null +++ b/src/defense/1_context/0_par.tex @@ -0,0 +1,56 @@ +\subsection{Parallélisation} + +%{{{ +\begin{frame}{Idée générale} + %{{{ frame " + \framesubtitle<1-2>{Exécution séquentielle} + \framesubtitle<3>{Exécution parallèle idéale} + + \begin{columns} + \begin{column}{.1\paperwidth}\end{column} + \begin{column}{.4\paperwidth} + \fig{context/seq} + \end{column} + \begin{column}<2>{.5\paperwidth} + \begin{itemize} + \item matériel multicœur + \item tâches m\textsubscript{\{0..N-1\}} indépendantes + \end{itemize} + \end{column} + \end{columns} + \figonly<3>{context/par} + %}}} +\end{frame} +%}}} + +%{{{ +\begin{frame}{Difficultés de la parallélisation} + %{{{ frame " + \begin{alertblock}{Difficultés et inconvénients} + \begin{itemize} + \item<+-> déterminer les parties parallélisables + \begin{itemize} + \item[$\to$] analyse de dépendances + \end{itemize} + \vspace{.5ex} + \item<+-> parallélisation correcte et maintenable + \begin{itemize} + \item[$\to$] composition de fonctions parallèles + \item[$\to$] séparation des domaines d'expertise + \end{itemize} + \vspace{.5ex} + \item<+-> besoin de synchronisation + \begin{itemize} + \item[$\to$] attente de la fin de tâches + \item[$\to$] partage de ressources + \end{itemize} + \vspace{.5ex} + \item<+-> non répétabilité des exécutions + \begin{itemize} + \item[$\to$] cas des nombres pseudo-aléatoires + \end{itemize} + \end{itemize} + \end{alertblock} + %}}} +\end{frame} +%}}} diff --git a/src/defense/1_context/1_app.tex b/src/defense/1_context/1_app.tex new file mode 100644 index 0000000..b5da19f --- /dev/null +++ b/src/defense/1_context/1_app.tex @@ -0,0 +1,106 @@ +\subsection{Application : \graspels} + +%{{{ +\begin{frame}{Problème du voyageur de commerce} + \framesubtitle<1>{Instance} + \framesubtitle<2>{Solution quelconque} + \framesubtitle<3>{Solution optimale} + + %{{{ frame " + \begin{columns} + \begin{column}{.4\paperwidth} + \figonly<1>{app/tspinstance} + \figonly<2>{app/tspsolution} + \figonly<3>{app/tspopti} + \end{column} + \begin{column}{.5\paperwidth} + \begin{itemize} + \item<1-> Graphe $G = (V, A, c)$ + \item<2-> coût $c_s = \displaystyle\sum_{i=2}^{\vert V \vert}{c((s[i-1], s[i]))}$ + \item<3-> Problème d'optimisation + \item<3-> NP-difficile + \end{itemize} + \end{column} + \end{columns} + %}}} +\end{frame} +%}}} + +%{{{ +\begin{frame}{Algorithme stochastique glouton} + %{{{ frame " + \begin{columns} + \begin{column}{.5\paperwidth} + \alg{app/greedy} + \end{column} + \begin{column}{.5\paperwidth} + \def\tspstart{0} + \def\istep{9} + \only<1>{\def\istep{0}} + \only<2>{\def\istep{1}} + \only<3>{\def\istep{2}} + \only<4>{\def\istep{3}} + \only<5>{\def\istep{4}} + \only<6>{\def\istep{5}} + \only<7>{\def\istep{6}} + \only<8>{\def\istep{7}} + \only<9>{\def\istep{8}} + \only<10>{\def\istep{9}} + \only<11>{\def\tspstart{1}} + \only<12>{\def\tspstart{2}} + \only<13>{\def\tspstart{3}} + \fig{app/tspgreedysolution} + \end{column} + \end{columns} + %}}} +\end{frame} +%}}} + +%{{{ +\begin{frame}{Métaheuristique \graspels} + \setbeamercovered{still covered={\opaqueness<1->{15}},again covered={\opaqueness<1->{50}}} + + %{{{ frame " + \begin{columns} + \begin{column}{.5\paperwidth} + \begin{overprint} + \onslide+<1> + \vspace*{7ex} + \scriptsize + \alg{app/grasp} + + \onslide+<2-7> + \fig{app/tspels} + + \onslide+<8> + \vspace*{7ex} + \scriptsize + \alg{app/graspels} + \end{overprint} + \end{column} + \begin{column}{.5\paperwidth} + \uncover<2->{ + \scriptsize + \alg{app/els} + } + \end{column} + \end{columns} + %}}} +\end{frame} +%}}} + +%{{{ +\begin{frame}{Points clés} + %{{{ frame " + \begin{block}{Intérêt de cette application} + \begin{itemize} + \item Plusieurs niveaux de parallélisation possible + \vspace{1ex} + \item Stochastique $\implies$ répétabilité difficile + \vspace{1ex} + \item Composabilité (exemple : \graspils) + \end{itemize} + \end{block} + %}}} +\end{frame} +%}}} diff --git a/src/defense/1_context/2_mp.tex b/src/defense/1_context/2_mp.tex new file mode 100644 index 0000000..d6b1b5d --- /dev/null +++ b/src/defense/1_context/2_mp.tex @@ -0,0 +1,249 @@ +\subsection{Métaprogrammation template} + +%{{{ +\begin{frame}{Métaprogrammation} + %{{{ frame " + \begin{block}{Définition de métaprogramme} + programme dont les données traitées sont des programmes + \end{block} + + En C++ : + \begin{itemize} + \item notamment basé sur les templates + \item exécution du métaprogramme durant la compilation + \item génération d'un programme C++ + \end{itemize} + + \fig{mp/metaprogram} + %}}} +\end{frame} +%}}} + +%{{{ +\begin{frame}{Métaprogrammation template} + \framesubtitle{Généricité} + + %{{{ frame " + \begin{block}{Résultats d'un template} + \begin{itemize} + \item structure / classe / union + \item fonction + \item variable + \end{itemize} + \end{block} + + \lstvisible<2->{mp/tmptype} + + \visible<3->{ + \begin{columns} + \begin{column}{.33\paperwidth} + \lst{mp/tmptype_int_5} + \end{column} + \begin{column}{.33\paperwidth} + \lst{mp/tmptype_float_3} + \end{column} + \begin{column}{.33\paperwidth} + \lst{mp/tmptype_Foo_256} + \end{column} + \end{columns} + + + \tikz[remember picture,overlay]\draw[->,>=stealth] + (mp tmptype) -- node[midway,left]{\cppinline{Array}} (mp tmptype int 5); + \tikz[remember picture,overlay]\draw[->,>=stealth] + (mp tmptype) -- node[midway]{\cppinline{Array}} (mp tmptype float 3); + \tikz[remember picture,overlay]\draw[->,>=stealth] + (mp tmptype) -- node[midway,right]{\cppinline{Array}} (mp tmptype Foo 256); + } + %}}} +\end{frame} +%}}} + +%{{{ +\begin{frame}{Puissance avec exposant connu} + %{{{ frame " + \vspace*{-3ex} + \begin{columns} + \begin{column}{.25\paperwidth}\end{column} + \begin{column}{.5\paperwidth} + \only<-9>{\center Fonction puissance\vspace{-2ex}} + \lstonly<-9>{mp/pow.rt} + \only<10-12>{\setminted{highlightcolor=yellow!80!black!30,highlightlines={1-4}}} + \only<13>{\setminted{highlightcolor=yellow!80!black!30,highlightlines={6-9}}} + \only<9->{\center Métafonction puissance\vspace{-2ex}} + \lstonly<9->{mp/pow.ct} + \end{column} + \begin{column}{.25\paperwidth}\end{column} + \end{columns} + \vspace{-2ex} + \begin{columns}[t] + \begin{column}{.066\paperwidth}\end{column} + \begin{column}{.4\paperwidth} + \only<2-8,10->{\center Exemple d'appel\vspace{-2ex}} + \only<-8>{\lstvisible<2-8>{mp/pow.rt.call}} + \only<8>{ + \vspace{2ex} + \begin{itemize} + \item $n$ multiplications + \item $n$ soustractions + \item structures de contrôle + \end{itemize} + } + \lstvisible<10->{mp/pow.ct.call} + \end{column} + \begin{column}{.066\paperwidth}\end{column} + \begin{column}{.4\paperwidth} + \visible<3-8,15->{\center Assembleur produit\vspace{-2ex}} + \only<-8>{\lstvisible<3-8>{mp/pow.rt.asm}} + \lstonly<15>{mp/pow.ct.asm} + \only<15->{\vspace{7pt}} + \end{column} + \begin{column}{.066\paperwidth}\end{column} + \end{columns} + + \only<10-14>{\center C++ généré\\\vspace{-1pt}} + \only<10>{\small\center\texttt{\hlbox{yellow!80!black!30}{pow<24>(x)}}} + \only<11>{\small\center\texttt{x*\hlbox{yellow!80!black!30}{pow<23>(x)}}} + \only<12>{\small\center\texttt{x*x*\hlbox{yellow!80!black!30}{pow<22>(x)}}} + \only<13>{\small\center\texttt{x*\dots*x*\hlbox{yellow!80!black!30}{pow<0>(x)}}} + \only<14>{% + \small\center\texttt{\phantom{p}\tikzmark{powx0}x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x\tikzmark{powxn}*1\phantom{p}}% + \tikz[remember picture,overlay]{% + \draw[decorate,decoration={brace,amplitude=4pt,raise=2pt,mirror}] + (pic cs:powx0) -- node[below=4pt]{\num{24} occurrences de \texttt{x}} (pic cs:powxn); + }% + } + \only<10-14>{\vspace{11pt}} + + \only<15>{\vspace{-3ex}\center $\implies$ exponentiation rapide par le compilateur} + + \tikz[remember picture,overlay,->,>=stealth,rounded corners,thick]{% + \only<4>{ + \draw[<-] ([shift={(-.1em,.5ex)}]pic cs:powimul) -- +(-10mm,0) node[left]{\texttt{r *= x}}; + } + \only<5>{ + \draw[<-] ([shift={(-.1em,.5ex)}]pic cs:powsub) -- +(-10mm,0) node[left]{\texttt{n-{}-}}; + } + \only<6>{ + \draw ([shift={(-.1em,.5ex)}]pic cs:powjend) -- ++(-12mm,0) + |- node[pos=.25,left]{si \textcolor[rgb]{.53,0,0}{\texttt{esi}} $\leqslant 0$} ([shift={(-.1em,.5ex)}]pic cs:powlend); + \draw ([shift={(-.1em,.5ex)}]pic cs:powjloop) -- ++(-8mm,0) |- ([shift={(-.1em,.5ex)}]pic cs:powlloop); + } + \only<7>{ + \draw ([shift={(-.1em,.5ex)}]pic cs:powjloop) -- ++(-8mm,0) + |- node[pos=.25,left]{tant que \textcolor[rgb]{.53,0,0}{\texttt{eax}} $>0$} ([shift={(-.1em,.5ex)}]pic cs:powlloop); + } + }% + %}}} +\end{frame} +%}}} + +%{{{ +\begin{frame}{Patrons d'expression} + %{{{ frame " + \framesubtitle{Concept} + + \begin{itemize} + \item traitement d'arbre syntaxiques abstraits + \item acquisition avec un langage embarqué + \end{itemize} + + \begin{columns} + \begin{column}{.32\paperwidth} + \vspace{1mm} + \lstvisible<2->{mp/edsl_basic} + \lstvisible<4->{mp/et_basic} + \end{column} + \begin{column}{.56\paperwidth} + \figonly<3-4>{mp/et_basic} + \only<5>{\vspace{1mm}} + \lstonly<5>{mp/opmul} + \lstonly<5>{mp/opadd} + \end{column} + \end{columns} + + \only<6->{\vspace{15.75mm}}% fix v pos + \begin{exampleblock}{Applications} + \begin{itemize} + \item Eigen : optimisation de calculs matriciels + \item Adept : optimisation de dérivées de fonctions + \item Parallélisation assistée/automatique + \end{itemize} + \end{exampleblock} + %}}} +\end{frame} +%}}} + +%{{{ +\begin{frame}{Patrons d'expression} + %{{{ frame " + \framesubtitle{Exemple d'optimisation} + + \only<-3>{\vspace{-2ex}} + + \begin{columns} + \begin{column}{.4\paperwidth} + \lst{mp/edsl_linexpr} + \lstvisible<2->{mp/et} + \end{column} + \begin{column}{.55\paperwidth} + % \vspace{-39mm} + \visible<3>{ + \center Motif \og affine \fg\vspace{-1ex} + \lst{mp/et_pattern_lin} + + \center Motif \og constante \texttimes{} affine \fg\vspace{-1ex} + \lst{mp/et_pattern_mulcstlin} + + \center Motif \og affine $-$ affine \fg\vspace{-1ex} + \lst{mp/et_pattern_sublinlin} + } + \end{column} + \end{columns} + + \begin{columns} + \begin{column}{.3995\paperwidth} + \lst{mp/edsl_linexpr} + \end{column} + \end{columns} + \begin{columns} + \begin{column}{.3275\paperwidth} + \lst{mp/edsl_linexpr_opti0} + \end{column} + \end{columns} + \begin{columns} + \begin{column}{.17\paperwidth} + \lst{mp/edsl_linexpr_opti} + \end{column} + \end{columns} + \begin{overprint} + \onslide+<4> + \fig{mp/et_linexpr} + \onslide+<5> + \fig{mp/et_linexpr_opti0} + \onslide+<6-> + \fig{mp/et_linexpr_opti1} + \only<7>{ + \begin{itemize} + \item code effectif produit + \item analyse durant la compilation + \end{itemize} + } + \end{overprint} + %}}} +\end{frame} +%}}} + +%{{{ +\begin{frame}{Atouts de la métaprogrammation template} + %{{{ frame " + \begin{itemize} + \item Analyse et génération de code durant la compilation + \vspace{1ex} + \item Possibilité de le faire sans surcoût + \vspace{1ex} + \item C++ standard + \end{itemize} + %}}} +\end{frame} +%}}} diff --git a/src/defense/2_alsk.tex b/src/defense/2_alsk.tex new file mode 100644 index 0000000..1bfb245 --- /dev/null +++ b/src/defense/2_alsk.tex @@ -0,0 +1,6 @@ +\section{Parallélisation assistée} + +\input{src/defense/2_alsk/0_alsk} +\input{src/defense/2_alsk/1_exec} +\input{src/defense/2_alsk/2_repeat} +\input{src/defense/2_alsk/3_conclusion} diff --git a/src/defense/2_alsk/0_alsk.tex b/src/defense/2_alsk/0_alsk.tex new file mode 100644 index 0000000..1dfc896 --- /dev/null +++ b/src/defense/2_alsk/0_alsk.tex @@ -0,0 +1,154 @@ +\subsection{Squelettes algorithmiques} + +%{{{ +\begin{frame}{Concept} + %{{{ frame " + \begin{itemize} + \item Motifs d'exécution parallèle + \item Composition + \item<3>[$\to$] \graspels + \end{itemize} + + \vspace{-4ex} + \begin{overprint} + \onslide+<2> + \fig{alsk/forkjoin} + \onslide+<3> + \vspace{-4ex} + \begin{columns} + \begin{column}{.2\paperwidth} + \vspace*{2ex} + \center Serial\vspace{-6ex} + \fig{alsk/seq} + \end{column} + \begin{column}{.5\paperwidth} + \vspace*{2ex} + \center FarmSel\vspace{-6ex} + \fig{alsk/farmsel} + \end{column} + \end{columns} + \end{overprint} + %}}} +\end{frame} +%}}} + +%{{{ +\begin{frame}{\graspels} + %{{{ frame " + \fig{alsk/graspels} + %}}} +\end{frame} +%}}} + +%{{{ +\begin{frame}{Composition} + %{{{ frame " + \begin{columns} + \begin{column}{.33\paperwidth} + \fig{alsk/grasp} + \end{column} + \begin{column}{.66\paperwidth} + \only<1-4>{ + \begin{itemize}[] + \item Muscles\visible<2->{~: fonctions \og domaine \fg{}} + \item Structure\visible<3->{~: motifs d'exécution} + \item Liens\visible<4->{~: flux de données} + \end{itemize} + \vspace{1cm} + \alg{alsk/grasp}% + \visible<3>{% + \tikz[overlay,colStruct]{% + \fill[rounded corners,opacity=.2] (9mm,23.5mm) rectangle +(33mm,4.25mm);% + \draw[decorate,decoration={brace,amplitude=4pt}] (3mm,5mm) -- +(0mm,27mm);% + \draw[decorate,decoration={brace,amplitude=3pt}] (9mm,9.5mm) -- +(0mm,18mm);% + \draw[decorate,decoration={brace,amplitude=2pt}] (15mm,14.75mm) -- +(0mm,8mm);% + }% + }% + } + \end{column} + \end{columns} + %}}} +\end{frame} +%}}} + +%{{{ +\begin{frame}{Structure} + %{{{ frame " + \begin{columns} + \begin{column}{.33\paperwidth} + \fig{alsk/grasp_struct} + \end{column} + \begin{column}{.62\paperwidth} + \only<2>{\setminted{highlightcolor=colStruct!30,highlightlines={5,10}}} + \only<3>{\setminted{highlightcolor=colMuscle!30,highlightlines={6-8,9}}} + \only<4>{\setminted{highlightcolor=colStruct!30,highlightlines={6,8}}} + \only<5>{\setminted{highlightcolor=colMuscle!30,highlightlines={7}}} + \lst{alsk/grasp_struct} + \end{column} + \begin{column}{.04\paperwidth}\end{column} + \end{columns} + %}}} +\end{frame} +%}}} + +%{{{ +\begin{frame}{Liens} + %{{{ frame " + \begin{columns} + \begin{column}{.33\paperwidth} + \fig{alsk/grasp_links} + \end{column} + \begin{column}{.62\paperwidth} + \colorletonly<2>{colFSr}{colLinkOut} \colorletonly<2>{colFSp0}{colLinkIn} + \colorletonly<3>{colFSp0}{colLinkIn} \colorletonly<3>{colSp0}{colLinkIn} + \colorletonly<4>{colSp0}{colLinkIn} \colorletonly<4>{colCHp0}{colLinkIn} + \colorletonly<5>{colCHr}{colLinkOut} \colorletonly<5>{colLSp0}{colLinkIn} + \colorletonly<6>{colSr}{colLinkOut} \colorletonly<6>{colLSr}{colLinkOut} + \colorletonly<7>{colSr}{colLinkOut} \colorletonly<7>{colSelp}{colLinkIn} + \colorletonly<8>{colFSr}{colLinkOut} \colorletonly<8>{colSelr}{colLinkOut} + \colorletonly<9>{colCHp1}{colLinkCtx} \colorletonly<9>{colLSp1}{colLinkCtx} + + \begin{itemize} + \item[\texttt{P}] paramètre d'indice \texttt{i} + \item[\texttt{R}] résultat d'indice \texttt{i} + \item[\texttt{RNG}] générateur de nombres pseudo-aléatoires + \end{itemize} + + \lst{alsk/grasp_links} + \end{column} + \begin{column}{.04\paperwidth}\end{column} + \end{columns} + %}}} +\end{frame} +%}}} + +%{{{ +\begin{frame}{Corps : instanciation d'un squelette} + %{{{ frame " + \texttt{SkelEls} $=$ \texttt{SkelElsStruct} $+$ \texttt{SkelElsLinks} + + \bigskip + + \only<2>{\setminted{highlightlines={2},highlightcolor=colStruct!30}} + \only<3>{\setminted{highlightlines={3},highlightcolor=colStruct!30}} + + \lstvisible<1->{alsk/elsbody} + \lstvisible<4->{alsk/graspbody} + %}}} +\end{frame} +%}}} + +%{{{ +\begin{frame}{Exécution} + %{{{ frame " + \only<1>{\setminted{lastline={1}}} + \only<2>{\setminted{lastline={5}}} + \only<3>{\setminted{lastline={7}}} + \only<4>{\setminted{lastline={9}}} + + \vbox to 4cm { + \lst{alsk/graspexec} + } + %}}} +\end{frame} +%}}} diff --git a/src/defense/2_alsk/1_exec.tex b/src/defense/2_alsk/1_exec.tex new file mode 100644 index 0000000..ea6b03c --- /dev/null +++ b/src/defense/2_alsk/1_exec.tex @@ -0,0 +1,121 @@ +\subsection{Politiques d'exécution} + +%{{{ +\begin{frame}{\texttt{DynamicPool} : \en{Thread pool}} + %{{{ frame " + \fig{exec/threadpool} + %}}} +\end{frame} +%}}} + +%{{{ +\begin{frame}{Répartition équilibrée} + %{{{ frame " + \only<1>{\def\N{12}\def\T{4}} + \only<2>{\def\N{10}\def\T{4}} + \fig{exec/firstlevel} + \only<1>{ + \vspace{-1ex} + \[ + 12\text{ tâches} = 3\text{ tâches/\en{thread}} \times 4\text{ \en{threads}} + 0\text{ tâche} + \] + \[ + \implies \text{accélération idéale : }4 + \] + } + \only<2>{ + \vspace{-1ex} + \[ + 10\text{ tâches} = 2\text{ tâches/\en{thread}} \times 4\text{ \en{threads}} + 2\text{ tâches} + \] + \[ + \implies \text{accélération idéale : }3.\overline{3} + \] + } + %}}} +\end{frame} +%}}} + +%{{{ +\begin{frame}{Répartition équilibrée multi-niveaux} + %{{{ frame " + \def\N{10}\def\T{4} + \figonly<1>{exec/firstleveldetails} + \only<2>{ + \fig{exec/multilevel} + \vspace{6.5mm} + } + \only<1>{ + \vspace{-1ex} + \[ + 10 \times 2\text{ tâches} = 2 \times 2\text{ tâches/\en{thread}} \times 4\text{ \en{threads}} + + 2 \times 2\text{ tâches} + \] + \[ + \implies \text{accélération idéale : }3.\overline{3} + \] + } + \only<2>{ + \vspace{-1ex} + \[ + 10 \times 2\text{ tâches} = (2 \times 2 + 1)\text{ tâches/\en{thread}} \times 4\text{ \en{threads}} + \] + \[ + \implies \text{accélération idéale : }4 + \] + } + %}}} +\end{frame} +%}}} + +%{{{ +\begin{frame}{Performances} + %{{{ frame " + \framesubtitle<2>{Temps moyen (exécutions séquentielles)} + \framesubtitle<3>{Temps moyen (exécutions parallèles)} + \framesubtitle<4>{Accélération (exécutions parallèles)} + + \only<1>{ + Contexte matériel et logiciel : + \vspace{1ex} + \begin{itemize} + \item Intel Xeon E7-8890 v3 -- \SI{2.5}{\GHz} + \vspace{1ex} + \item \num{18} cœurs + \vspace{1ex} + \item GCC 8.2.0 -- \texttt{-O2} + \vspace{1ex} + \item Résolution de \graspels{} (194 sommets) + \vspace{1ex} + \item moyennes sur \num{20} exécutions + \vspace{1ex} + \item exécutions répétables + \end{itemize} + } + + \only<2>{ + \begin{columns} + \begin{column}{.7\paperwidth} + \includegraphics{img/exec/rt_graspels_qa194_24_20_20_seq.pdf} + \end{column} + \begin{column}{.25\paperwidth} + \begin{itemize} + \item[hw\_\ldots] \og à la main \fg + \item[sk\_\ldots] avec squelettes + \end{itemize} + \end{column} + \end{columns} + } + \only<3>{ + \includegraphics{img/exec/rt_graspels_qa194_20_20_20_speedup.pdf} + \vspace{-2ex} + \center Nombre d'itérations du GRASP : \num{20} + } + \only<4>{ + \includegraphics{img/exec/rt_graspels_qa194_4_20_20_speedup.pdf} + \vspace{-2.5ex} + \center Nombre d'itérations du GRASP : \num{4} + } + %}}} +\end{frame} +%}}} diff --git a/src/defense/2_alsk/2_repeat.tex b/src/defense/2_alsk/2_repeat.tex new file mode 100644 index 0000000..3fa1621 --- /dev/null +++ b/src/defense/2_alsk/2_repeat.tex @@ -0,0 +1,314 @@ +\subsection{Répétabilité} + +%{{{ +\begin{frame}{Problème} + %{{{ frame " + \framesubtitle{Exécution séquentielle} + + \colorlet{a}{colThread0} + \colorlet{b}{colThread1} + + \begin{columns} + \begin{column}{\paperwidth} + \fig{repeat/prng/seq} + \end{column} + \end{columns} + + \vfill + + \begin{columns} + \begin{column}{.47\paperwidth} + \begin{itemize} + \item \textcolor{a}{$\frac{\text{tâche }0}{\text{\en{thread }0}} \to $ \visible<2->{12}% + \foreach[count=\i from 3] \n in {2,34,85,4,91} {\visible<\i->{, \n}}} + \vspace{1em} + \item<8-> \textcolor{b}{$\frac{\text{tâche }1}{\text{\en{thread }0}} \to $ \visible<8->{29}% + \foreach[count=\i from 9] \n in {85,98,3,35,65} {\visible<\i->{, \n}}} + \end{itemize} + \end{column} + \begin{column}{.37\paperwidth}% fix alignment with next frame + \end{column} + \begin{column}{.12\paperwidth} + \end{column} + \end{columns} + \only<14>{}% create overlay + %}}} +\end{frame} +%}}} + +%{{{ +\begin{frame}{Problème} + %{{{ frame " + \framesubtitle{Exécution parallèle} + + \colorlet{a}{colThread0} + \colorlet{b}{colThread1} + + \begin{columns} + \begin{column}{\paperwidth} + \fig{repeat/prng/par} + \end{column} + \end{columns} + + \vfill + + \begin{columns} + \begin{column}{.47\paperwidth} + \begin{itemize} + \item \textcolor{a}{$\frac{\text{tâche }0}{\text{\en{thread }0}} \to $ \visible<2->{12}% + \foreach \n/\os in {34/4,4/6,29/8,98/10,65/13} {\visible<\os->{, \n}}} + \vspace{1em} + \item<3-> \textcolor{b}{$\frac{\text{tâche }1}{\text{\en{thread }0}} \to $ \visible<3->{2}% + \foreach[count=\i from 9] \n/\os in {85/5,91/7,85/9,3/11,35/12} {\visible<\os->{, \n}}} + \end{itemize} + \end{column} + \begin{column}{.37\paperwidth} + \only<14->{ + \begin{itemize} + \setbeamertemplate{itemize items}{\raisebox{.4ex}{\textit{ou}}} + \item \raisebox{.4ex}{\textcolor{a}{34, 85, 91, 29, 98, 35}} + \vspace{1em} + \setbeamertemplate{itemize items}{\raisebox{.1ex}{\textit{ou}}} + \item \raisebox{.1ex}{\textcolor{b}{12, 2, 4, 85, 3, 65}} + \end{itemize} + } + \end{column} + \begin{column}{.12\paperwidth} + \only<15->{ + \begin{itemize} + \setbeamertemplate{itemize items}{\raisebox{.4ex}{\textit{ou}}} + \item \raisebox{.4ex}{\dots} + \vspace{1em} + \setbeamertemplate{itemize items}{\raisebox{.1ex}{\textit{ou}}} + \item \raisebox{.1ex}{\dots} + \end{itemize} + } + \end{column} + \end{columns} + %}}} +\end{frame} +%}}} + +%{{{ +\begin{frame}{Solutions possibles} + %{{{ frame " + \begin{itemize} + \item un PRNG global $\implies$ aucune répétabilité + \vspace{1em} + \item un PRNG par \en{thread} $\implies$ répétabilité partielle + \vspace{1em} + \item un PRNG par tâche parallèle $\implies$ répétabilité totale + \end{itemize} + %}}} +\end{frame} +%}}} + +%{{{ +\begin{frame}{Solutions possibles} + %{{{ frame " + \framesubtitle{$\to$ Un PRNG par \en{thread}} + + \colorlet{a}{colThread0} + \colorlet{b}{colThread1} + \colorlet{c}{b} + \only<1>{\colorlet{c}{black}} + + \begin{columns} + \begin{column}{\paperwidth} + \fig{repeat/prng/parthread} + \end{column} + \end{columns} + + \vfill + + \begin{columns} + \begin{column}{.47\paperwidth} + \begin{itemize} + \item \textcolor{a}{$\frac{\text{tâche }0}{\text{\en{thread }0}} \to $ 12, 2, 34, 85, 4, 91} + \vspace{1em} + \item \textcolor{b}{$\frac{\text{tâche }1}{\text{\en{thread }1}} \to $ 42, 8, 9, 54, 95, 80} + \end{itemize} + \end{column} + \begin{column}{.47\paperwidth} + \only<2>{ + \begin{itemize} + \setbeamertemplate{itemize items}{{$=$}} + \item \hspace{.5em}{\textcolor{a}{$\frac{\text{tâche }0}{\text{\en{thread }0}} \to $ 12, 2, 34, 85, 4, 91}} + \vspace{1em} + \setbeamertemplate{itemize items}{{$\neq$}} + \item \hspace{.5em}{\textcolor{b}{$\frac{\text{tâche }1}{\text{\en{thread }0}} \to $ 29, 85, 98, 3, 35, 65}} + \end{itemize} + } + \end{column} + \begin{column}{.02\paperwidth} + \end{column} + \end{columns} + %}}} +\end{frame} +%}}} + +%{{{ +\begin{frame}{Solutions possibles} + %{{{ frame " + \framesubtitle{$\to$ Un PRNG par tâche parallèle} + + \begin{block}{Pré-requis} + \begin{itemize} + \item Système de liens (\texttt{RNG}) + \item Identifier les tâches parallèles + \begin{itemize} + \item parcours de l'arbre du squelette algorithmique + \item connaissance de la nature des motifs d'exécution + \end{itemize} + \end{itemize} + \end{block} + + \begin{alertblock}{Inconvénient} + \begin{itemize} + \item Beaucoup de PRNG créés + \begin{itemize} + \item[$\to$] réduction grâce à la connaissance des politiques d'exécution + \end{itemize} + \end{itemize} + \end{alertblock} + %}}} +\end{frame} +%}}} + +%{{{ +\begin{frame}<0>[noframenumbering]{Identification des tâches} + %{{{ frame " + \vspace*{-1.5ex} + \begin{columns} + \begin{column}{\paperwidth} + \fig{repeat/identify} + \end{column} + \end{columns} + %}}} +\end{frame} +%}}} + +%{{{ +\begin{frame}{Optimiser le nombre de PRNG} + %{{{ frame " + \def\N{9} + \begin{columns} + \begin{column}{.3\paperwidth} + \figonly<1>{repeat/seq} + \only<2>{\vspace*{-2.8ex}\def\T{2}\fig{repeat/par}} + \end{column} + \begin{column}{.6\paperwidth} + \only<1>{ + \vspace*{-5ex} + Contraintes \#\en{threads} $\implies$ moins de PRNG + \vspace{4ex} + } + + \only<2>{\vspace*{-3.25ex}} + \[ + \only<1>{S_1 = \{\{m_0, m_1, m_2, m_3, m_4, m_5, m_6, m_7, m_8\}\}} + \only<2>{S_2 = \{\{m_0, m_1, m_2, m_3, m_4\}, \{m_5, m_6, m_7, m_8\}\}} + \] + \end{column} + \end{columns} + \only<3>{ + \def\T{3}\fig{repeat/par} + \[ + S_3 = \{\{m_0, m_1, m_2\},\{m_3, m_4, m_5\}, \{m_6, m_7, m_8\}\} + \] + } + \only<4>{ + \def\T{4}\fig{repeat/par} + \[ + S_4 = \{\{m_0, m_1, m_2\},\{m_3, m_4\},\{m_5, m_6\}, \{m_7, m_8\}\} + \] + } + \only<5>{ + \def\T{5}\fig{repeat/par} + \vspace{13mm} + \[ + S_5 = \{\{m_0, m_1\},\{m_2, m_3\},\{m_4, m_5\},\{m_6, m_7\},\{m_8\}\} + \] + } + \only<6>{ + \def\T{6}\fig{repeat/par} + \vspace{13mm} + \[ + S_6 = \{\{m_0, m_1\},\{m_2, m_3\},\{m_4, m_5\},\{m_6\},\{m_7\},\{m_8\}\} + \] + } + \only<7>{ + \def\T{7}\fig{repeat/par} + \vspace{13mm} + \[ + S_7 = \{\{m_0, m_1\},\{m_2,m_3\},\{m_4\},\{m_5\},\{m_6\},\{m_7\},\{m_8\}\} + \] + } + \only<8>{ + \def\T{8}\fig{repeat/par} + \vspace{13mm} + \[ + S_8 = \{\{m_0, m_1\},\{m_2\},\{m_3\},\{m_4\},\{m_5\},\{m_6\},\{m_7\},\{m_8\}\} + \] + } + \only<9>{ + \begin{columns} + \begin{column}{\paperwidth} + \def\T{9}\fig{repeat/par} + \end{column} + \end{columns} + \vspace{25.8mm} + \[ + S_9 = \{\{m_0\},\{m_1\},\{m_2\},\{m_3\},\{m_4\},\{m_5\},\{m_6\},\{m_7\},\{m_8\}\} + \] + } + % \begin{align*} + % \visible<1->{S_1 &= \{\{m_0, m_1, m_2, m_3, m_4, m_5, m_6, m_7, m_8\}\}} + % \visible<2->{\\S_2 &= \{\{m_0, m_1, m_2, m_3, m_4\}, \{m_5, m_6, m_7, m_8\}\}} + % \visible<3->{\\S_3 &= \{\{m_0, m_1, m_2\},\{m_3, m_4, m_5\}, \{m_6, m_7, m_8\}\}} + % \visible<4->{\\S_4 &= \{\{m_0, m_1, m_2\},\{m_3, m_4\},\{m_5, m_6\}, \{m_7, m_8\}\}} + % \end{align*} + %}}} +\end{frame} +%}}} + +%{{{ +\begin{frame}{Optimiser le nombre de PRNG} + %{{{ frame " + \begin{align*} + S_1 &= \{\{\tikzmark{s1e0b}m_0, m_1, m_2\tikzmark{s1e0e}, \tikzmark{s1e1b}m_3, m_4\tikzmark{s1e1e}, \tikzmark{s1e2b}m_5\tikzmark{s1e2e}, \tikzmark{s1e3b}m_6\tikzmark{s1e3e}, \tikzmark{s1e4b}m_7, m_8\tikzmark{s1e4e}\}\}\\ + S_2 &= \{\{\tikzmark{s2e0b}m_0, m_1, m_2\tikzmark{s2e0e}, \tikzmark{s2e1b}m_3, m_4\tikzmark{s2e1e}\},\{\tikzmark{s2e2b}m_5\tikzmark{s2e2e}, \tikzmark{s2e3b}m_6\tikzmark{s2e3e}, \tikzmark{s2e4b}m_7, m_8\tikzmark{s2e4e}\}\}\\ + S_3 &= \{\{\tikzmark{s3e0b}m_0, m_1, m_2\tikzmark{s3e0e}\},\{\tikzmark{s3e1b}m_3, m_4\tikzmark{s3e1e}, \tikzmark{s3e2b}m_5\tikzmark{s3e2e}\},\{\tikzmark{s3e3b}m_6\tikzmark{s3e3e}, \tikzmark{s3e4b}m_7, m_8\tikzmark{s3e4e}\}\}\\ + S_4 &= \{\{\tikzmark{s4e0b}m_0, m_1, m_2\tikzmark{s4e0e}\},\{\tikzmark{s4e1b}m_3, m_4\tikzmark{s4e1e}\},\{\tikzmark{s4e2b}m_5\tikzmark{s4e2e}, \tikzmark{s4e3b}m_6\tikzmark{s4e3e}\},\{\tikzmark{s4e4b}m_7, m_8\tikzmark{s4e4e}\}\} + \end{align*} + + \visible<2->{ + \[ + S = \{\{\tikzmark{se0b}m_0, m_1, m_2\tikzmark{se0e}\},\{\tikzmark{se1b}m_3, m_4\tikzmark{se1e}\},\{\tikzmark{se2b}m_5\tikzmark{se2e}\},\{\tikzmark{se3b}m_6\tikzmark{se3e}\},\{\tikzmark{se4b}m_7, m_8\tikzmark{se4e}\}\} + \] + } + + \foreach[count=\s from 0] \col in + {red!90!black,yellow!80!black,green!90!black,cyan!80!black,blue!90!black} {% + \visible<+(2),8>{% + \tikz[remember picture,overlay,every node/.append style={common/rhl=\col}]{% + \foreach \i in {1,...,4} {% + \node[fit=(pic cs:s\i e\s b)(pic cs:s\i e\s e)]{}; + }% + \node[fit=(pic cs:se\s b)(pic cs:se\s e)]{}; + }% + }% + }% + %}}} +\end{frame} +%}}} + +%{{{ +\begin{frame}{Nombre de PRNG nécessaires} + %{{{ frame " + \only<1>{\includegraphics{img/repeat/exp_0.pdf}} + \only<2>{\includegraphics{img/repeat/exp_1.pdf}} + \only<3>{\includegraphics{img/repeat/exp_2.pdf}} + %}}} +\end{frame} +%}}} diff --git a/src/defense/2_alsk/3_conclusion.tex b/src/defense/2_alsk/3_conclusion.tex new file mode 100644 index 0000000..241ed89 --- /dev/null +++ b/src/defense/2_alsk/3_conclusion.tex @@ -0,0 +1,26 @@ +\subsection*{Résumé} + +%{{{ +\begin{frame} + %{{{ frame " + Plusieurs niveaux d'utilisation : + \begin{itemize} + \item conception de motifs d'exécution + \vspace{1ex} + \item implémentation de politiques d'exécution + \vspace{1ex} + \item définition de squelettes (bibliothèques spécialisées) + \vspace{1ex} + \item utilisation finale d'un squelette existant + \end{itemize} + + \bigskip + + Répétabilité : + \begin{itemize} + \item indépendante du nombre de \en{threads} + \item optimisée en fonction de la politique d'exécution + \end{itemize} + %}}} +\end{frame} +%}}} diff --git a/src/defense/3_pfor.tex b/src/defense/3_pfor.tex new file mode 100644 index 0000000..88e35a7 --- /dev/null +++ b/src/defense/3_pfor.tex @@ -0,0 +1,5 @@ +\section{Parallélisation automatique de boucles} + +\input{src/defense/3_pfor/0_ctanalysis} +\input{src/defense/3_pfor/1_edsl} +\input{src/defense/3_pfor/2_results} diff --git a/src/defense/3_pfor/0_ctanalysis.tex b/src/defense/3_pfor/0_ctanalysis.tex new file mode 100644 index 0000000..3659d2d --- /dev/null +++ b/src/defense/3_pfor/0_ctanalysis.tex @@ -0,0 +1,98 @@ +\subsection{Analyse durant la compilation} + +\tikzset{local/rhl/.style={common/rhl=#1,minimum height=2.3ex,rounded corners=.5mm}} + +%{{{ +\begin{frame}{Besoin} + %{{{ frame " + Temps d'exécution concentré dans les boucles + + $\implies$ parallélisation des boucles + + \bigskip + + \begin{columns} + \begin{column}{.5\paperwidth} + \lstvisible<2->{intro/loop_par} + \lstvisible<3->{intro/loop_seq} + \lstvisible<4->{intro/loop_par_hard} + \end{column} + \end{columns} + + \bigskip + + \visible<5>{ + Objectif de la bibliothèque : + \begin{itemize} + \item analyse automatique durant la compilation + \item génération automatique + \end{itemize} + } + %}}} +\end{frame} +%}}} + +%{{{ +\begin{frame}{Analyse} + %{{{ frame " + \framesubtitle<-5>{Conditions de Bernstein} + \framesubtitle<6-7>{Identification des boucles parallélisables} + \framesubtitle<8>{Résultat} + + \begin{columns} + \begin{column}{.5\paperwidth} + \begin{overprint} + \onslide+<1-5> + \lst{pfor/loop} + \def\x{x}\def\y{y} + \only<4>{\def\x{2}\def\y{4}} + \only<5>{\def\x{3}\def\y{5}} + \begin{exampleblock}<2-4>{Indépendance de deux instructions x et y selon Bernstein} + \vspace{-3ex} + \begin{align*} + \only<3-4>{\color{red!80!black}}W_\y \cap R_\x &\only<3-4>{\color{red!80!black}}= \alt<3-4>{\{\alt<3>{b}{d}\}}{\emptyset}\\ + \only<4>{\color{red!80!black}}R_\y \cap W_\x &\only<4>{\color{red!80!black}}= \alt<4>{\{c\}}{\emptyset}\\ + W_\x \cap W_\y &= \emptyset + \end{align*} + \end{exampleblock} + \foreach \l/\os/\col in {b/3/red,c/4/green!60!red,d/4/green!60!blue} { + \visible<\os>{ + \tikz[remember picture,overlay,every node/.append style={local/rhl=\col}]{ + \node[fit=(pic cs:pforloop\l rb)(pic cs:pforloop\l re)]{}; + \node[fit=(pic cs:pforloop\l wb)(pic cs:pforloop\l we)]{}; + } + } + } + \visible<5>{ + \tikz[remember picture,overlay]{ + \foreach \l/\col in {2/red,3/green,4/red,5/green,6/blue} { + \node[fit=(pic cs:pforloopl\l b)(pic cs:pforloopl\l e),local/rhl=\col]{}; + \node[fit=(pic cs:pforloopl\l b)(pic cs:pforloopl\l e),local/rhl=\col]{}; + } + } + + \vspace{-39pt} + \begin{itemize} + \item[$\to$] analyse des variables + \end{itemize} + } + \onslide+<6-7> + \lst{pfor/loop_split} + \visible<7>{ + \tikz[remember picture,overlay,every node/.append style={local/rhl=red}]{ + \node[fit=(pic cs:pforloopsplitcrb)(pic cs:pforloopsplitcre)]{}; + \node[fit=(pic cs:pforloopsplitcwb)(pic cs:pforloopsplitcwe)]{}; + } + + \begin{itemize} + \item[$\to$] analyse des fonctions d'indice + \end{itemize} + } + \onslide+<8> + \lst{pfor/loop_par} + \end{overprint} + \end{column} + \end{columns} + %}}} +\end{frame} +%}}} diff --git a/src/defense/3_pfor/1_edsl.tex b/src/defense/3_pfor/1_edsl.tex new file mode 100644 index 0000000..0705527 --- /dev/null +++ b/src/defense/3_pfor/1_edsl.tex @@ -0,0 +1,18 @@ +\subsection{Syntaxe du langage embarqué} + +%{{{ +\begin{frame}{Utilisation} + %{{{ frame " + \begin{columns} + \begin{column}{.49\paperwidth} + \center Boucle originale + \lst{pfor/loop_noanim} + \end{column} + \begin{column}{.49\paperwidth} + \center Boucle active + \lst{pfor/loop_pfor} + \end{column} + \end{columns} + %}}} +\end{frame} +%}}} diff --git a/src/defense/3_pfor/2_results.tex b/src/defense/3_pfor/2_results.tex new file mode 100644 index 0000000..5638a46 --- /dev/null +++ b/src/defense/3_pfor/2_results.tex @@ -0,0 +1,37 @@ +\subsection*{Performances} + +%{{{ +\begin{frame}{Performances} + %{{{ frame " + \framesubtitle<2>{Exécutions séquentielles} + \framesubtitle<3>{Exécutions parallèles} + + \only<1>{ + Contexte matériel et logiciel : + \vspace{1ex} + \begin{itemize} + \item Intel Xeon E7-8890 v3 -- \SI{2.5}{\GHz} + \vspace{1ex} + \item \num{18} cœurs + \vspace{1ex} + \item GCC 8.2.0 -- \texttt{-O2} + \vspace{1ex} + \item moyennes sur \num{20} exécutions + \vspace{1ex} + \item exécutions répétables + \end{itemize} + } + + \only<2>{\includegraphics{img/pfor/rt_seq.pdf}} + \only<3>{\includegraphics{img/pfor/rt_par_18.pdf}} + %}}} +\end{frame} +%}}} + +%{{{ +\begin{frame}{Performances -- compilation} + %{{{ frame " + \includegraphics{img/pfor/ct.pdf} + %}}} +\end{frame} +%}}} diff --git a/src/defense/4_conclusion.tex b/src/defense/4_conclusion.tex new file mode 100644 index 0000000..484077b --- /dev/null +++ b/src/defense/4_conclusion.tex @@ -0,0 +1,59 @@ +\section*{Conclusion} + +%{{{ +\begin{frame}{Bilan} + %{{{ frame " + \num{2} bibliothèques actives de parallélisation : + \begin{itemize} + \item abstraction sans surcoût à l'exécution + \item parallélisation assistée ou automatique + \end{itemize} + + \bigskip + + \begin{itemize} + \item Bibliothèque active de parallélisation assistée : + \begin{itemize} + \item squelettes algorithmiques + \item choix de la politique d'exécution + \item répétabilité garantie automatiquement + \item quelques squelettes pour la recherche opérationnelle + \end{itemize} + \vspace{1ex} + \item Bibliothèque active de parallélisation automatique de boucles : + \begin{itemize} + \item analyse à la compilation de l'AST + \begin{itemize} + \item \dots des variables pour les dépendances + \item \dots des fonctions d'indice pour la parallélisabilité + \end{itemize} + \end{itemize} + \end{itemize} + %}}} +\end{frame} +%}}} + +%{{{ +\begin{frame}{Limites et perspectives} + %{{{ frame " + Bibliothèque de parallélisation assistée : + \begin{itemize} + \item nouveaux motifs : + \begin{itemize} + \item \en{pipeline} + \item \en{divide and conquer} + \item \dots + \end{itemize} + \item politique d'exécution équilibrée pondérée + \end{itemize} + + \bigskip + + Bibliothèque de parallélisation automatique de boucles : + \begin{itemize} + \item généralisation de l'analyse des fonctions d'indice + \item transformation d'un code non parallélisable + \end{itemize} + %}}} +\end{frame} +%}}} diff --git a/src/document.tex b/src/document.tex new file mode 100644 index 0000000..c80d9c1 --- /dev/null +++ b/src/document.tex @@ -0,0 +1,23 @@ +\begin{document} + \begin{frame}[plain] + \titlepage + \end{frame} + + { + \input{src/defense/0_intro} + + { + \AtBeginSection{ + \begin{frame} + \frametitle{Plan} + \tableofcontents[currentsection] + \end{frame} + } + + \input{src/defense/1_context} + \input{src/defense/2_alsk} + \input{src/defense/3_pfor} + } + \input{src/defense/4_conclusion} + } +\end{document} diff --git a/src/fig/alsk/farmsel.tex b/src/fig/alsk/farmsel.tex new file mode 100644 index 0000000..3f944a8 --- /dev/null +++ b/src/fig/alsk/farmsel.tex @@ -0,0 +1,26 @@ +\begin{tikzpicture} + \input{src/tikz/parallel} + + \begin{scope}[node distance=6mm] + \begin{scope}[start chain=going below,every node/.style={on chain,join},parallel/arrow] + \node[parallel/block] (input) {}; + \node[parallel/point] (fork) {}; + \node[parallel/task] (main) {\dots}; + \node[parallel/point] (join) {}; + \node[parallel/task] (select) {T\textsubscript{S}}; + \node[parallel/block] (output) {}; + \end{scope} + + \node[parallel/task,left=of main] (thread 0) {T\textsubscript{0}}; + \node[parallel/task,right=of main] (thread n) {T\textsubscript{n-1}}; + \end{scope} + + \begin{scope}[on background layer] + \node[parallel/region=(thread 0)(main)(thread n)] {}; + \end{scope} + + \begin{scope}[parallel/arrow] + \draw (fork) -| (thread 0) |- (join); + \draw (fork) -| (thread n) |- (join); + \end{scope} +\end{tikzpicture} diff --git a/src/fig/alsk/forkjoin.tex b/src/fig/alsk/forkjoin.tex new file mode 100644 index 0000000..a5924ec --- /dev/null +++ b/src/fig/alsk/forkjoin.tex @@ -0,0 +1,23 @@ +\begin{tikzpicture} + \input{src/tikz/parallel} + + \begin{scope}[node distance=8mm] + \begin{scope}[start chain=going below,every node/.style={on chain,join},parallel/arrow] + \node[parallel/block] (input) {}; + \node[parallel/point] (fork) {}; + \node[parallel/task] (main) {T\textsubscript{0}}; + \node[parallel/point] (join) {}; + \node[parallel/block] (output) {}; + \end{scope} + + \node[parallel/task,right=of main] (thread) {T\textsubscript{1}}; + \end{scope} + + \begin{scope}[on background layer] + \node[parallel/region=(main)(thread)] {}; + \end{scope} + + \begin{scope}[parallel/arrow] + \draw (fork) -| node[above,pos=.2]{\en{fork}} (thread) |- node[below,pos=.8]{\en{join}} (join); + \end{scope} +\end{tikzpicture} diff --git a/src/fig/alsk/grasp.tex b/src/fig/alsk/grasp.tex new file mode 100644 index 0000000..5075b22 --- /dev/null +++ b/src/fig/alsk/grasp.tex @@ -0,0 +1,72 @@ +\begin{tikzpicture} + \input{src/tikz/alsk} + + %{{{ GRASP " + % Nodes + \matrix[row sep=3mm, column sep=-1mm] { + & \node[alsk/scheme/split] (split) {}; \\ + \\ + \node[alsk/scheme/task] (ch0) {CH}; & \node[alsk/label] (chi) {\bf\scriptsize\dots}; & + \node[alsk/scheme/task] (chn) {CH}; \\ + \node[alsk/scheme/task] (ls0) {LS}; & \node[alsk/label] (lsi) {\bf\scriptsize\dots}; & + \node[alsk/scheme/task] (lsn) {LS}; \\ + \\ + & \node[alsk/scheme/join] (merge) {}; \\ + & \node[alsk/scheme/task] (select) {S}; \\ + }; + + \node[above=3mm of split] (entry) {}; + \node[below=3mm of select] (return) {}; + + % Frames + \node[alsk/scheme/frame=colStruct,fit margins={top=1.5mm,bottom=1.5mm}, + fit=(ch0)(ls0),only on=<3>{ultra thick}] (serial0) {}; + \node[alsk/scheme/frame=colStruct,fit margins={top=1.5mm,bottom=1.5mm}, + fit=(chn)(lsn),only on=<3>{ultra thick}] (serialn) {}; + + \node[alsk/scheme/frame=colStruct,fit margins={top=1.5mm,bottom=1.5mm}, + fit=(split)(select)(serial0)(serialn),only on=<3>{ultra thick}] (grasp) {}; + + % Links + \begin{scope}[alsk/scheme/link,only on=<4>{ultra thick}] + \draw[only on=<4>{colLinkIn}] (entry) -- (split); + + \draw[only on=<4>{colLinkIn}] (split.210) -- (serial0.north); + \draw[only on=<4>{colLinkIn}] (split.330) -- (serialn.north); + + \draw[only on=<4>{colLinkIn}] (serial0.north) -- (ch0); + \draw[only on=<4>{colLinkIn}] (serialn.north) -- (chn); + + \draw[only on=<4>{colLinkOut!50!colLinkIn}] (ch0) -- (ls0); + \draw[only on=<4>{colLinkOut!50!colLinkIn}] (chn) -- (lsn); + + \draw[only on=<4>{colLinkOut}] (ls0) -- (serial0.south); + \draw[only on=<4>{colLinkOut}] (lsn) -- (serialn.south); + + \draw[only on=<4>{colLinkOut}] (serial0.south) -- (merge.150); + \draw[only on=<4>{colLinkOut}] (serialn.south) -- (merge.30); + + \draw[only on=<4>{colLinkIn}] (merge) -- (select); + + \draw[only on=<4>{colLinkOut}] (select) -- (return); + \end{scope} + %}}} + + %{{{ animations " + %{{{ Muscles " + \visible<2>{ + \node[alsk/scheme/task,ultra thick] at (ch0) {CH}; + \node[alsk/scheme/task,ultra thick] at (chn) {CH}; + \node[alsk/scheme/task,ultra thick] at (ls0) {LS}; + \node[alsk/scheme/task,ultra thick] at (lsn) {LS}; + \node[alsk/scheme/task,ultra thick] at (select) {S}; + } + %}}} + %{{{ Structure " + \visible<3>{ + \node[alsk/scheme/split,ultra thick] at (split) {}; + \node[alsk/scheme/join,ultra thick] at (merge) {}; + } + %}}} + %}}} +\end{tikzpicture} diff --git a/src/fig/alsk/grasp_links.tex b/src/fig/alsk/grasp_links.tex new file mode 100644 index 0000000..8695383 --- /dev/null +++ b/src/fig/alsk/grasp_links.tex @@ -0,0 +1,54 @@ +\begin{tikzpicture} + \input{src/tikz/alsk} + + %{{{ GRASP " + % Nodes + \matrix[row sep=3mm, column sep=-1mm] { + & \node[alsk/scheme/split] (split) {}; \\ + \\ + \node[alsk/scheme/task] (ch0) {CH}; & \node[alsk/label] (chi) {\bf\scriptsize\dots}; & + \node[alsk/scheme/task] (chn) {CH}; \\ + \node[alsk/scheme/task] (ls0) {LS}; & \node[alsk/label] (lsi) {\bf\scriptsize\dots}; & + \node[alsk/scheme/task] (lsn) {LS}; \\ + \\ + & \node[alsk/scheme/join] (merge) {}; \\ + & \node[alsk/scheme/task] (select) {S}; \\ + }; + + \node[above=3mm of split] (entry) {}; + \node[below=3mm of select] (return) {}; + + % Frames + \node[alsk/scheme/frame=colStruct,fit margins={top=1.5mm,bottom=1.5mm}, + fit=(ch0)(ls0)] (serial0) {}; + \node[alsk/scheme/frame=colStruct,fit margins={top=1.5mm,bottom=1.5mm}, + fit=(chn)(lsn)] (serialn) {}; + + \node[alsk/scheme/frame=colStruct,fit margins={top=1.5mm,bottom=1.5mm}, + fit=(split)(select)(serial0)(serialn)] (grasp) {}; + + % Links + \begin{scope}[alsk/scheme/link] + \draw[only on=<2>{ultra thick,colLinkIn}] (entry) -- (split); + + \draw[only on=<3>{ultra thick,colLinkIn}] (split.210) -- (serial0.north); + \draw[only on=<3>{ultra thick,colLinkIn}] (split.330) -- (serialn.north); + + \draw[only on=<4>{ultra thick,colLinkIn}] (serial0.north) -- (ch0); + \draw[only on=<4>{ultra thick,colLinkIn}] (serialn.north) -- (chn); + + \draw[only on=<5>{ultra thick,colLinkOut!50!colLinkIn}] (ch0) -- (ls0); + \draw[only on=<5>{ultra thick,colLinkOut!50!colLinkIn}] (chn) -- (lsn); + + \draw[only on=<6>{ultra thick,colLinkOut}] (ls0) -- (serial0.south); + \draw[only on=<6>{ultra thick,colLinkOut}] (lsn) -- (serialn.south); + + \draw[only on=<7>{ultra thick,colLinkOut}] (serial0.south) -- (merge.150); + \draw[only on=<7>{ultra thick,colLinkOut}] (serialn.south) -- (merge.30); + + \draw[only on=<7>{ultra thick,colLinkIn}] (merge) -- (select); + + \draw[only on=<{2,8}>{ultra thick,colLinkOut}] (select) -- (return); + \end{scope} + %}}} +\end{tikzpicture} diff --git a/src/fig/alsk/grasp_struct.tex b/src/fig/alsk/grasp_struct.tex new file mode 100644 index 0000000..1e76624 --- /dev/null +++ b/src/fig/alsk/grasp_struct.tex @@ -0,0 +1,75 @@ +\begin{tikzpicture} + \input{src/tikz/alsk} + + %{{{ GRASP " + % Nodes + \matrix[row sep=3mm, column sep=-1mm] { + & \node[alsk/scheme/split] (split) {}; \\ + \\ + \node[alsk/scheme/task] (ch0) {CH}; & \node[alsk/label] (chi) {\bf\scriptsize\dots}; & + \node[alsk/scheme/task] (chn) {CH}; \\ + \node[alsk/scheme/task] (ls0) {LS}; & \node[alsk/label] (lsi) {\bf\scriptsize\dots}; & + \node[alsk/scheme/task] (lsn) {LS}; \\ + \\ + & \node[alsk/scheme/join] (merge) {}; \\ + & \node[alsk/scheme/task] (select) {S}; \\ + }; + + \node[above=3mm of split] (entry) {}; + \node[below=3mm of select] (return) {}; + + % Frames + \node[alsk/scheme/frame=colStruct,fit margins={top=1.5mm,bottom=1.5mm}, + fit=(ch0)(ls0),only on=<3>{ultra thick},only on=<3>{solid,common/drawfill=colMuscle}, + only on=<4>{ultra thick}] (serial0) {\only<3>{T}}; + \node[alsk/scheme/frame=colStruct,fit margins={top=1.5mm,bottom=1.5mm}, + fit=(chn)(lsn),only on=<3>{ultra thick},only on=<3>{solid,common/drawfill=colMuscle}, + only on=<4>{ultra thick}] (serialn) {\only<3>{T}}; + + \node[alsk/scheme/frame=colStruct,fit margins={top=1.5mm,bottom=1.5mm}, + fit=(split)(select)(serial0)(serialn),only on=<1>{ultra thick}] (grasp) {}; + + % Links + \begin{scope}[alsk/scheme/link] + \draw (entry) -- (split); + + \draw (split.210) -- (serial0.north); + \draw (split.330) -- (serialn.north); + + \visible<-2,4->{ + \draw (serial0.north) -- (ch0); + \draw (serialn.north) -- (chn); + + \draw (ch0) -- (ls0); + \draw (chn) -- (lsn); + + \draw (ls0) -- (serial0.south); + \draw (lsn) -- (serialn.south); + } + + \draw (serial0.south) -- (merge.150); + \draw (serialn.south) -- (merge.30); + + \draw (merge) -- (select); + + \draw (select) -- (return); + \end{scope} + %}}} + + %{{{ animations " + \visible<2>{ + \node[alsk/scheme/split,ultra thick] at (split) {}; + \node[alsk/scheme/join,ultra thick] at (merge) {}; + } + \visible<3>{ + \node[alsk/scheme/task,ultra thick] at (select) {S}; + } + \visible<5>{ + \node[alsk/scheme/task,ultra thick] at (ch0) {CH}; + \node[alsk/scheme/task,ultra thick] at (chn) {CH}; + \node[alsk/scheme/task,ultra thick] at (ls0) {LS}; + \node[alsk/scheme/task,ultra thick] at (lsn) {LS}; + } + %}}} + %}}} +\end{tikzpicture} diff --git a/src/fig/alsk/graspels.tex b/src/fig/alsk/graspels.tex new file mode 100644 index 0000000..e603072 --- /dev/null +++ b/src/fig/alsk/graspels.tex @@ -0,0 +1,133 @@ +\begin{tikzpicture} + \input{src/tikz/alsk} + + \tikzset{split/.style={alsk/scheme/split,minimum width=8mm}} + \tikzset{task/.style={alsk/scheme/task,minimum width=6mm}} + \tikzset{join/.style={alsk/scheme/join,minimum width=8mm}} + \tikzset{loop/.style={alsk/scheme/loop,minimum width=6mm}} + \tikzset{frame/.style={alsk/scheme/frame=#1,inner sep=.5mm}} + + % GRASP nodes + \matrix[row sep=2.5mm, column sep=-1mm] { + & \node[split,minimum width=8mm] (grasp split) {}; \\ + \\ + \node[task] (grasp ch0) {\scriptsize CH}; & \node[alsk/label] (grasp chi) {\scriptsize\dots}; & + \node[task] (grasp chn) {\scriptsize CH}; \\ + \node[task] (grasp ls0) {}; & \node[alsk/label] (grasp lsi) {\scriptsize\dots}; & + \node[task] (grasp lsn) {}; \\ + \\ + & \node[join] (grasp merge) {}; \\ + & \node[task] (grasp select) {\scriptsize Sel\textsubscript{1}}; \\ + }; + + \node[above=3mm of grasp split] (grasp entry) {}; + \node[below=3mm of grasp select] (grasp return) {}; + + % Frames + \node[frame=colStruct,fit margins={top=1.5mm,bottom=1.5mm}, + fit=(grasp ch0)(grasp ls0)] (grasp serial0) {}; + \node[frame=colStruct,fit margins={top=1.5mm,bottom=1.5mm}, + fit=(grasp chn)(grasp lsn)] (grasp serialn) {}; + + \node[frame=colStruct,fit margins={top=1.5mm,bottom=1.5mm}, + fit=(grasp split)(grasp select)(grasp serial0)(grasp serialn)] {}; + + % GRASP Links + \begin{scope}[alsk/scheme/link] + \draw (grasp entry) -- (grasp split); + + \draw (grasp split.210) -- (grasp serial0.north); + \draw (grasp split.330) -- (grasp serialn.north); + + \draw (grasp serial0.north) -- (grasp ch0); + \draw (grasp serialn.north) -- (grasp chn); + + \draw (grasp ch0) -- (grasp ls0); + \draw (grasp chn) -- (grasp lsn); + + \draw (grasp ls0) -- (grasp serial0.south); + \draw (grasp lsn) -- (grasp serialn.south); + + \draw (grasp serial0.south) -- (grasp merge.150); + \draw (grasp serialn.south) -- (grasp merge.30); + + \draw (grasp merge) -- (grasp select); + + \draw (grasp select) -- (grasp return); + \end{scope} + + % ELS + \begin{scope}[common/overlay,spy using outlines={circle,magnification=.095,size=6.0mm}] + \begin{scope}[every node/.append style={transform shape,scale=.7}] + \matrix[row sep=1.5mm, column sep=-1mm] (els) at (5, 0) { + & \node[task] (els init ls) {\scriptsize iLS}; \\ + & \node[loop] (els loopbegin) {}; \\ + & \node[split] (els split) {}; \\ + \\ + \node[task] (els m0) {\scriptsize M}; & \node[alsk/label] (els mi) {\dots}; & + \node[task] (els mn) {\scriptsize M}; \\ + \node[task] (els ls0) {\scriptsize LS}; & \node[alsk/label] (els lsi) {\dots}; & + \node[task] (els lsn) {\scriptsize LS}; \\ + \\ + & \node[join] (els merge) {}; \\ + & \node[task] (els select2) {\scriptsize Sel\textsubscript{2}}; \\ + & \node[task] (els select3) {\scriptsize Sel\textsubscript{3}}; \\ + & \node[task] (els accept) {\scriptsize A}; \\ + & \node[loop] (els loopend) {}; \\ + }; + + \node[above=1.5mm of els init ls] (els entry) {}; + \node[below=1.5mm of els loopend] (els return) {}; + + % Frames + \node[frame=colStruct,fit margins={top=2mm,bottom=2mm,left=1.2mm,right=1.2mm}, + fit=(els m0)(els ls0)] (els serial0) {}; + \node[frame=colStruct,fit margins={top=2mm,bottom=2mm,left=1.2mm,right=1.2mm}, + fit=(els mn)(els lsn)] (els serialn) {}; + + \node[frame=colStruct,fit margins={top=4.4mm,bottom=4mm,left=2.8mm,right=2.8mm}, + fit=(els split)(els select2)(els serial0)(els serialn)] {}; + + % Links + \begin{scope}[alsk/scheme/link] + \draw (els entry) -- (els init ls); + + \draw (els init ls) -- (els loopbegin); + + \draw (els loopbegin) -- (els split); + + \draw (els split.210) -- (els serial0.north); + \draw (els split.330) -- (els serialn.north); + + \draw (els serial0.north) -- (els m0); + \draw (els serialn.north) -- (els mn); + + \draw (els m0) -- (els ls0); + \draw (els mn) -- (els lsn); + + \draw (els ls0) -- (els serial0.south); + \draw (els lsn) -- (els serialn.south); + + \draw (els serial0.south) -- (els merge.150); + \draw (els serialn.south) -- (els merge.30); + + \draw (els merge) -- (els select2); + + \draw (els select2) -- (els select3); + \draw (els select3) -- (els accept); + \draw (els accept) -- (els loopend); + \end{scope} + + \draw[alsk/scheme/link] (els loopend) -| +(-12mm, 0) |- ([xshift=-6mm]els loopbegin.west) + -- (els loopbegin); + + \draw[alsk/scheme/link] (els loopend) -- (els return); + \end{scope} + + \spy[densely dotted,thick,colMuscle] on (els) in node at (grasp ls0); + \spy[densely dotted,thick,colMuscle,connect spies] on (els) in node at (grasp lsn); + \end{scope} + + % Bounding box adjustments + \node[rectangle,fit=(els)(els entry)(els return),fit margins={right=3mm}]{}; +\end{tikzpicture} diff --git a/src/fig/alsk/seq.tex b/src/fig/alsk/seq.tex new file mode 100644 index 0000000..e3f223e --- /dev/null +++ b/src/fig/alsk/seq.tex @@ -0,0 +1,12 @@ +\begin{tikzpicture} + \input{src/tikz/parallel} + + \begin{scope}[node distance=8mm] + \begin{scope}[start chain=going below,every node/.style={on chain,join},parallel/arrow] + \node[parallel/block] (input) {}; + \node[parallel/task] (main) {T\textsubscript{0}}; + \node[parallel/task] (main) {T\textsubscript{1}}; + \node[parallel/block] (output) {}; + \end{scope} + \end{scope} +\end{tikzpicture} diff --git a/src/fig/alsk/tree_grasp.tex b/src/fig/alsk/tree_grasp.tex new file mode 100644 index 0000000..b61b3b4 --- /dev/null +++ b/src/fig/alsk/tree_grasp.tex @@ -0,0 +1,6 @@ +\begin{tikzpicture} + \input{src/tikz/alsk} + \begin{scope}[alsk/treestyle] + \Tree[.FarmSel [.Serial CH LS ] S ] + \end{scope} +\end{tikzpicture} diff --git a/src/fig/app/graspels.tex b/src/fig/app/graspels.tex new file mode 100644 index 0000000..e603072 --- /dev/null +++ b/src/fig/app/graspels.tex @@ -0,0 +1,133 @@ +\begin{tikzpicture} + \input{src/tikz/alsk} + + \tikzset{split/.style={alsk/scheme/split,minimum width=8mm}} + \tikzset{task/.style={alsk/scheme/task,minimum width=6mm}} + \tikzset{join/.style={alsk/scheme/join,minimum width=8mm}} + \tikzset{loop/.style={alsk/scheme/loop,minimum width=6mm}} + \tikzset{frame/.style={alsk/scheme/frame=#1,inner sep=.5mm}} + + % GRASP nodes + \matrix[row sep=2.5mm, column sep=-1mm] { + & \node[split,minimum width=8mm] (grasp split) {}; \\ + \\ + \node[task] (grasp ch0) {\scriptsize CH}; & \node[alsk/label] (grasp chi) {\scriptsize\dots}; & + \node[task] (grasp chn) {\scriptsize CH}; \\ + \node[task] (grasp ls0) {}; & \node[alsk/label] (grasp lsi) {\scriptsize\dots}; & + \node[task] (grasp lsn) {}; \\ + \\ + & \node[join] (grasp merge) {}; \\ + & \node[task] (grasp select) {\scriptsize Sel\textsubscript{1}}; \\ + }; + + \node[above=3mm of grasp split] (grasp entry) {}; + \node[below=3mm of grasp select] (grasp return) {}; + + % Frames + \node[frame=colStruct,fit margins={top=1.5mm,bottom=1.5mm}, + fit=(grasp ch0)(grasp ls0)] (grasp serial0) {}; + \node[frame=colStruct,fit margins={top=1.5mm,bottom=1.5mm}, + fit=(grasp chn)(grasp lsn)] (grasp serialn) {}; + + \node[frame=colStruct,fit margins={top=1.5mm,bottom=1.5mm}, + fit=(grasp split)(grasp select)(grasp serial0)(grasp serialn)] {}; + + % GRASP Links + \begin{scope}[alsk/scheme/link] + \draw (grasp entry) -- (grasp split); + + \draw (grasp split.210) -- (grasp serial0.north); + \draw (grasp split.330) -- (grasp serialn.north); + + \draw (grasp serial0.north) -- (grasp ch0); + \draw (grasp serialn.north) -- (grasp chn); + + \draw (grasp ch0) -- (grasp ls0); + \draw (grasp chn) -- (grasp lsn); + + \draw (grasp ls0) -- (grasp serial0.south); + \draw (grasp lsn) -- (grasp serialn.south); + + \draw (grasp serial0.south) -- (grasp merge.150); + \draw (grasp serialn.south) -- (grasp merge.30); + + \draw (grasp merge) -- (grasp select); + + \draw (grasp select) -- (grasp return); + \end{scope} + + % ELS + \begin{scope}[common/overlay,spy using outlines={circle,magnification=.095,size=6.0mm}] + \begin{scope}[every node/.append style={transform shape,scale=.7}] + \matrix[row sep=1.5mm, column sep=-1mm] (els) at (5, 0) { + & \node[task] (els init ls) {\scriptsize iLS}; \\ + & \node[loop] (els loopbegin) {}; \\ + & \node[split] (els split) {}; \\ + \\ + \node[task] (els m0) {\scriptsize M}; & \node[alsk/label] (els mi) {\dots}; & + \node[task] (els mn) {\scriptsize M}; \\ + \node[task] (els ls0) {\scriptsize LS}; & \node[alsk/label] (els lsi) {\dots}; & + \node[task] (els lsn) {\scriptsize LS}; \\ + \\ + & \node[join] (els merge) {}; \\ + & \node[task] (els select2) {\scriptsize Sel\textsubscript{2}}; \\ + & \node[task] (els select3) {\scriptsize Sel\textsubscript{3}}; \\ + & \node[task] (els accept) {\scriptsize A}; \\ + & \node[loop] (els loopend) {}; \\ + }; + + \node[above=1.5mm of els init ls] (els entry) {}; + \node[below=1.5mm of els loopend] (els return) {}; + + % Frames + \node[frame=colStruct,fit margins={top=2mm,bottom=2mm,left=1.2mm,right=1.2mm}, + fit=(els m0)(els ls0)] (els serial0) {}; + \node[frame=colStruct,fit margins={top=2mm,bottom=2mm,left=1.2mm,right=1.2mm}, + fit=(els mn)(els lsn)] (els serialn) {}; + + \node[frame=colStruct,fit margins={top=4.4mm,bottom=4mm,left=2.8mm,right=2.8mm}, + fit=(els split)(els select2)(els serial0)(els serialn)] {}; + + % Links + \begin{scope}[alsk/scheme/link] + \draw (els entry) -- (els init ls); + + \draw (els init ls) -- (els loopbegin); + + \draw (els loopbegin) -- (els split); + + \draw (els split.210) -- (els serial0.north); + \draw (els split.330) -- (els serialn.north); + + \draw (els serial0.north) -- (els m0); + \draw (els serialn.north) -- (els mn); + + \draw (els m0) -- (els ls0); + \draw (els mn) -- (els lsn); + + \draw (els ls0) -- (els serial0.south); + \draw (els lsn) -- (els serialn.south); + + \draw (els serial0.south) -- (els merge.150); + \draw (els serialn.south) -- (els merge.30); + + \draw (els merge) -- (els select2); + + \draw (els select2) -- (els select3); + \draw (els select3) -- (els accept); + \draw (els accept) -- (els loopend); + \end{scope} + + \draw[alsk/scheme/link] (els loopend) -| +(-12mm, 0) |- ([xshift=-6mm]els loopbegin.west) + -- (els loopbegin); + + \draw[alsk/scheme/link] (els loopend) -- (els return); + \end{scope} + + \spy[densely dotted,thick,colMuscle] on (els) in node at (grasp ls0); + \spy[densely dotted,thick,colMuscle,connect spies] on (els) in node at (grasp lsn); + \end{scope} + + % Bounding box adjustments + \node[rectangle,fit=(els)(els entry)(els return),fit margins={right=3mm}]{}; +\end{tikzpicture} diff --git a/src/fig/app/tspels.tex b/src/fig/app/tspels.tex new file mode 100644 index 0000000..9526641 --- /dev/null +++ b/src/fig/app/tspels.tex @@ -0,0 +1,104 @@ +\begin{tikzpicture} + \input{src/tikz/tsp} + + \tspnodes + + \def\bhstep{2.6} + \def\shstep{.75} + \def\vstep{-1.5} + \def\ratioodd{.666} + \def\ratioeven{.85} + + %{{{ first line " + \def\cl{1} + \begin{scope}[visible on=<3->,every path/.append style={visible on=<3->}] + \foreach \i in {0,...,\last} { + \coordinate (p-\cl-\i) at ($(p\i)!\ratioodd!(0,0)+(0,\vstep*\cl)$); + \node[tsp/node,minimum size=2pt] at (p-\cl-\i) {}; + } + + %{{{ boxes " + \begin{scope}[on background layer] + \node[fit=(p-\cl-0)(p-\cl-1)(p-\cl-2)(p-\cl-3)(p-\cl-4)(p-\cl-5)(p-\cl-6)(p-\cl-7)(p-\cl-8)(p-\cl-9), + rectangle,rounded corners] (sol-\cl) {}; + \end{scope} + %}}} + + \foreach [count=\i from 0] \o in {2,1,0,9,8,7,4,3,5,6} { \coordinate (s-\cl-\i) at (p-\cl-\o); } + \begin{scope}[on background layer] + \draw[tsp/edge,semithick,foreach/.style={insert path=--(s-\cl-#1)}] (s-\cl-0) [foreach/.list={1,...,\last}] -- cycle; + \end{scope} + \end{scope} + %}}} + + %{{{ second line " + \def\cl{2} + \begin{scope}[visible on=<4->,every path/.append style={visible on=<4->}] + \foreach \l in {0,...,2} { + \foreach \i in {0,...,\last} { + \coordinate (p-\cl-\i-\l) at ($(p\i)!\ratioeven!(0,0)+(\shstep*\l-.47,\vstep*\cl+.5)$); + \node[tsp/node,minimum size=1pt] at (p-\cl-\i-\l) {}; + } + + % box + \begin{scope}[on background layer] + \ifthenelse{\l=2} + {\tikzset{local/.style={only on=<5>{tsp/best,thin}}}} + {\tikzset{local/.style={}}} + \node[fit=(p-\cl-0-\l)(p-\cl-1-\l)(p-\cl-2-\l)(p-\cl-3-\l)(p-\cl-4-\l)(p-\cl-5-\l)(p-\cl-6-\l)(p-\cl-7-\l)(p-\cl-8-\l)(p-\cl-9-\l), + local,rectangle,rounded corners,inner sep=1pt] (sol-\cl-\l) {}; + \end{scope} + } + + %{{{ third column " + \foreach [count=\i from 0] \o in {2,1,0,4,8,7,9,3,5,6} { \coordinate (s-\cl-\i-0) at (p-\cl-\o-0); } + \foreach [count=\i from 0] \o in {2,3,0,9,8,7,4,1,5,6} { \coordinate (s-\cl-\i-1) at (p-\cl-\o-1); } + \foreach [count=\i from 0] \o in {2,1,0,9,8,7,4,6,5,3} { \coordinate (s-\cl-\i-2) at (p-\cl-\o-2); } + \begin{scope}[on background layer] + \draw[tsp/edge,very thin,foreach/.style={insert path=--(s-\cl-#1-0)}] (s-\cl-0-0) [foreach/.list={1,...,\last}] -- cycle; + \draw[tsp/edge,very thin,foreach/.style={insert path=--(s-\cl-#1-1)}] (s-\cl-0-1) [foreach/.list={1,...,\last}] -- cycle; + \draw[tsp/edge,very thin,foreach/.style={insert path=--(s-\cl-#1-2)}] (s-\cl-0-2) [foreach/.list={1,...,\last}] -- cycle; + \end{scope} + %}}} + \end{scope} + %}}} + + %{{{ third line " + \def\cl{3} + \begin{scope}[visible on=<6->,every path/.append style={visible on=<6->}] + \foreach \i in {0,...,\last} { + \coordinate (p-\cl-\i) at ($(p\i)!\ratioodd!(0,0)+(0,\vstep*\cl+.5)$); + \node[tsp/node,minimum size=2pt] at (p-\cl-\i) {}; + } + + \foreach [count=\i from 0] \o in {2,1,0,9,8,7,4,6,5,3} { \coordinate (s-\cl-\i) at (p-\cl-\o); } + \foreach \i in {0,...,\last} { + \node[tsp/node,minimum size=2pt] at (p-\cl-\i) {}; + } + + %{{{ boxes " + \begin{scope}[on background layer] + \node[fit=(p-\cl-0)(p-\cl-1)(p-\cl-2)(p-\cl-3)(p-\cl-4)(p-\cl-5)(p-\cl-6)(p-\cl-7)(p-\cl-8)(p-\cl-9), + rectangle,rounded corners] (sol-\cl) {}; + \end{scope} + %}}} + + \begin{scope}[on background layer] + \draw[tsp/edge,semithick,foreach/.style={insert path=--(s-\cl-#1)}] (s-\cl-0) [foreach/.list={1,...,\last}] -- cycle; + \end{scope} + \end{scope} + %}}} + + %{{{ links " + \foreach \l in {0,...,2} { + \draw[<-,>=stealth,visible on=<4->] (sol-2-\l) -- (sol-1); + } + \foreach \l in {0,...,2} { + \draw[->,>=stealth,visible on=<6->] (sol-2-\l) -- (sol-3); + } + %}}} + + %{{{ loop " + \draw[->,>=stealth,semithick,rounded corners,visible on=<7>] (sol-3.south) -- ++(0,-3mm) -| ([xshift=-5mm]sol-1.west) -- (sol-1); + %}}} +\end{tikzpicture} diff --git a/src/fig/app/tspgraspels.tex b/src/fig/app/tspgraspels.tex new file mode 100644 index 0000000..0dc8e46 --- /dev/null +++ b/src/fig/app/tspgraspels.tex @@ -0,0 +1,330 @@ +\begin{tikzpicture} + \input{src/tikz/tsp} + + \tspnodes + + \def\bhstep{2.6} + \def\shstep{.75} + \def\vstep{-1.5} + \def\ratioodd{.666} + \def\ratioeven{.85} + + %{{{ first line " + \def\cl{1} + \begin{scope}[visible on=<1->,every path/.append style={visible on=<1->}] + \foreach \i in {0,...,\last} { + \foreach \j in {0,...,3} { + \coordinate (p-\cl-\i-\j) at ($(p\i)!\ratioodd!(0,0)+(\bhstep*\j,\vstep*\cl)$); + \node[tsp/node,minimum size=2pt] at (p-\cl-\i-\j) {}; + } + } + + %{{{ boxes " + \begin{scope}[on background layer] + \def\cc{0} + \node[fit=(p-\cl-0-\cc)(p-\cl-1-\cc)(p-\cl-2-\cc)(p-\cl-3-\cc)(p-\cl-4-\cc)(p-\cl-5-\cc)(p-\cl-6-\cc)(p-\cl-7-\cc)(p-\cl-8-\cc)(p-\cl-9-\cc), + rectangle,rounded corners] (sol-\cl-\cc) {}; + \end{scope} + \begin{scope}[on background layer] + \def\cc{1} + \node[fit=(p-\cl-0-\cc)(p-\cl-1-\cc)(p-\cl-2-\cc)(p-\cl-3-\cc)(p-\cl-4-\cc)(p-\cl-5-\cc)(p-\cl-6-\cc)(p-\cl-7-\cc)(p-\cl-8-\cc)(p-\cl-9-\cc), + rectangle,rounded corners] (sol-\cl-\cc) {}; + \end{scope} + \begin{scope}[on background layer] + \def\cc{2} + \node[fit=(p-\cl-0-\cc)(p-\cl-1-\cc)(p-\cl-2-\cc)(p-\cl-3-\cc)(p-\cl-4-\cc)(p-\cl-5-\cc)(p-\cl-6-\cc)(p-\cl-7-\cc)(p-\cl-8-\cc)(p-\cl-9-\cc), + rectangle,rounded corners] (sol-\cl-\cc) {}; + \end{scope} + \begin{scope}[on background layer] + \def\cc{3} + \node[fit=(p-\cl-0-\cc)(p-\cl-1-\cc)(p-\cl-2-\cc)(p-\cl-3-\cc)(p-\cl-4-\cc)(p-\cl-5-\cc)(p-\cl-6-\cc)(p-\cl-7-\cc)(p-\cl-8-\cc)(p-\cl-9-\cc), + rectangle,rounded corners] (sol-\cl-\cc) {}; + \end{scope} + %}}} + + \foreach [count=\i from 0] \o in {0,9,1,8,7,6,4,2,3,5} { \coordinate (s-\cl-\i-0) at (p-\cl-\o-0); } + \foreach [count=\i from 0] \o in {4,5,3,6,8,7,1,2,0,9} { \coordinate (s-\cl-\i-1) at (p-\cl-\o-1); } + \foreach [count=\i from 0] \o in {2,1,0,9,8,7,4,3,5,6} { \coordinate (s-\cl-\i-2) at (p-\cl-\o-2); } + \foreach [count=\i from 0] \o in {8,7,6,4,5,1,9,0,2,3} { \coordinate (s-\cl-\i-3) at (p-\cl-\o-3); } + \begin{scope}[on background layer] + \draw[tsp/edge,semithick,foreach/.style={insert path=--(s-\cl-#1-0)}] (s-\cl-0-0) [foreach/.list={1,...,\last}] -- cycle; + \draw[tsp/edge,semithick,foreach/.style={insert path=--(s-\cl-#1-1)}] (s-\cl-0-1) [foreach/.list={1,...,\last}] -- cycle; + \draw[tsp/edge,semithick,foreach/.style={insert path=--(s-\cl-#1-2)}] (s-\cl-0-2) [foreach/.list={1,...,\last}] -- cycle; + \draw[tsp/edge,semithick,foreach/.style={insert path=--(s-\cl-#1-3)}] (s-\cl-0-3) [foreach/.list={1,...,\last}] -- cycle; + \end{scope} + \end{scope} + %}}} + + %{{{ second line " + \def\cl{2} + \begin{scope}[visible on=<2->,every path/.append style={visible on=<2->}] + \foreach \j in {0,...,3} { + \foreach \l in {0,...,2} { + \foreach \i in {0,...,\last} { + \coordinate (p-\cl-\i-\j-\l) at ($(p\i)!\ratioeven!(0,0)+(\bhstep*\j+\shstep*\l-.47,\vstep*\cl+.5)$); + \node[tsp/node,minimum size=1pt] at (p-\cl-\i-\j-\l) {}; + } + + % box + \begin{scope}[on background layer] + \ifthenelse{\(\j=0 \AND \l=1\) \OR \(\j=1 \AND \l=0\) \OR \(\j=2 \AND \l=2\) \OR \(\j=3 \AND \l=2\)} + {\tikzset{local/.style={only on=<3>{tsp/best,thin}}}} + {\tikzset{local/.style={}}} + \node[fit=(p-\cl-0-\j-\l)(p-\cl-1-\j-\l)(p-\cl-2-\j-\l)(p-\cl-3-\j-\l)(p-\cl-4-\j-\l)(p-\cl-5-\j-\l)(p-\cl-6-\j-\l)(p-\cl-7-\j-\l)(p-\cl-8-\j-\l)(p-\cl-9-\j-\l), + local,rectangle,rounded corners,inner sep=1pt] (sol-\cl-\j-\l) {}; + \end{scope} + } + } + + %{{{ first column " + \foreach [count=\i from 0] \o in {0,9,8,1,7,6,4,2,3,5} { \coordinate (s-\cl-\i-0-0) at (p-\cl-\o-0-0); } + \foreach [count=\i from 0] \o in {0,9,1,8,7,6,4,5,3,2} { \coordinate (s-\cl-\i-0-1) at (p-\cl-\o-0-1); } + \foreach [count=\i from 0] \o in {0,2,1,8,7,6,4,9,3,5} { \coordinate (s-\cl-\i-0-2) at (p-\cl-\o-0-2); } + \begin{scope}[on background layer] + \draw[tsp/edge,very thin,foreach/.style={insert path=--(s-\cl-#1-0-0)}] (s-\cl-0-0-0) [foreach/.list={1,...,\last}] -- cycle; + \draw[tsp/edge,very thin,foreach/.style={insert path=--(s-\cl-#1-0-1)}] (s-\cl-0-0-1) [foreach/.list={1,...,\last}] -- cycle; + \draw[tsp/edge,very thin,foreach/.style={insert path=--(s-\cl-#1-0-2)}] (s-\cl-0-0-2) [foreach/.list={1,...,\last}] -- cycle; + \end{scope} + %}}} + %{{{ second column " + \foreach [count=\i from 0] \o in {4,5,3,6,8,7,1,9,0,2} { \coordinate (s-\cl-\i-1-0) at (p-\cl-\o-1-0); } + \foreach [count=\i from 0] \o in {4,3,5,6,8,7,1,2,0,9} { \coordinate (s-\cl-\i-1-1) at (p-\cl-\o-1-1); } + \foreach [count=\i from 0] \o in {4,5,3,2,8,7,1,6,0,9} { \coordinate (s-\cl-\i-1-2) at (p-\cl-\o-1-2); } + \begin{scope}[on background layer] + \draw[tsp/edge,very thin,foreach/.style={insert path=--(s-\cl-#1-1-0)}] (s-\cl-0-1-0) [foreach/.list={1,...,\last}] -- cycle; + \draw[tsp/edge,very thin,foreach/.style={insert path=--(s-\cl-#1-1-1)}] (s-\cl-0-1-1) [foreach/.list={1,...,\last}] -- cycle; + \draw[tsp/edge,very thin,foreach/.style={insert path=--(s-\cl-#1-1-2)}] (s-\cl-0-1-2) [foreach/.list={1,...,\last}] -- cycle; + \end{scope} + %}}} + %{{{ third column " + \foreach [count=\i from 0] \o in {2,1,0,4,8,7,9,3,5,6} { \coordinate (s-\cl-\i-2-0) at (p-\cl-\o-2-0); } + \foreach [count=\i from 0] \o in {2,3,0,9,8,7,4,1,5,6} { \coordinate (s-\cl-\i-2-1) at (p-\cl-\o-2-1); } + \foreach [count=\i from 0] \o in {2,1,0,9,8,7,4,6,5,3} { \coordinate (s-\cl-\i-2-2) at (p-\cl-\o-2-2); } + \begin{scope}[on background layer] + \draw[tsp/edge,very thin,foreach/.style={insert path=--(s-\cl-#1-2-0)}] (s-\cl-0-2-0) [foreach/.list={1,...,\last}] -- cycle; + \draw[tsp/edge,very thin,foreach/.style={insert path=--(s-\cl-#1-2-1)}] (s-\cl-0-2-1) [foreach/.list={1,...,\last}] -- cycle; + \draw[tsp/edge,very thin,foreach/.style={insert path=--(s-\cl-#1-2-2)}] (s-\cl-0-2-2) [foreach/.list={1,...,\last}] -- cycle; + \end{scope} + %}}} + %{{{ fourth column " + \foreach [count=\i from 0] \o in {8,1,6,4,5,7,9,0,2,3} { \coordinate (s-\cl-\i-3-0) at (p-\cl-\o-3-0); } + \foreach [count=\i from 0] \o in {8,4,6,7,5,1,9,0,2,3} { \coordinate (s-\cl-\i-3-1) at (p-\cl-\o-3-1); } + \foreach [count=\i from 0] \o in {5,7,6,4,8,1,9,0,2,3} { \coordinate (s-\cl-\i-3-2) at (p-\cl-\o-3-2); } + \begin{scope}[on background layer] + \draw[tsp/edge,very thin,foreach/.style={insert path=--(s-\cl-#1-3-0)}] (s-\cl-0-3-0) [foreach/.list={1,...,\last}] -- cycle; + \draw[tsp/edge,very thin,foreach/.style={insert path=--(s-\cl-#1-3-1)}] (s-\cl-0-3-1) [foreach/.list={1,...,\last}] -- cycle; + \draw[tsp/edge,very thin,foreach/.style={insert path=--(s-\cl-#1-3-2)}] (s-\cl-0-3-2) [foreach/.list={1,...,\last}] -- cycle; + \end{scope} + %}}} + \end{scope} + %}}} + + %{{{ third line " + \def\cl{3} + \begin{scope}[visible on=<4->,every path/.append style={visible on=<4->}] + \foreach \i in {0,...,\last} { + \foreach \j in {0,...,3} { + \coordinate (p-\cl-\i-\j) at ($(p\i)!\ratioodd!(0,0)+(\bhstep*\j,\vstep*\cl+.5)$); + \node[tsp/node,minimum size=2pt] at (p-\cl-\i-\j) {}; + } + } + + \foreach [count=\i from 0] \o in {0,9,1,8,7,6,4,5,3,2} { \coordinate (s-\cl-\i-0) at (p-\cl-\o-0); } + \foreach [count=\i from 0] \o in {4,5,3,6,8,7,1,9,0,2} { \coordinate (s-\cl-\i-1) at (p-\cl-\o-1); } + \foreach [count=\i from 0] \o in {2,1,0,9,8,7,4,6,5,3} { \coordinate (s-\cl-\i-2) at (p-\cl-\o-2); } + \foreach [count=\i from 0] \o in {5,7,6,4,8,1,9,0,2,3} { \coordinate (s-\cl-\i-3) at (p-\cl-\o-3); } + \foreach \j in {0,...,3} { + \foreach \i in {0,...,\last} { + \node[tsp/node,minimum size=2pt] at (p-\cl-\i-\j) {}; + } + } + + %{{{ boxes " + \begin{scope}[on background layer] + \def\cc{0}% best + \node[fit=(p-\cl-0-\cc)(p-\cl-1-\cc)(p-\cl-2-\cc)(p-\cl-3-\cc)(p-\cl-4-\cc)(p-\cl-5-\cc)(p-\cl-6-\cc)(p-\cl-7-\cc)(p-\cl-8-\cc)(p-\cl-9-\cc), + only on=<4-7>{tsp/best},only on=<8>{tsp/localbest},rectangle,rounded corners] (sol-\cl-\cc) {}; + \end{scope} + \begin{scope}[on background layer] + \def\cc{1}% best + \node[fit=(p-\cl-0-\cc)(p-\cl-1-\cc)(p-\cl-2-\cc)(p-\cl-3-\cc)(p-\cl-4-\cc)(p-\cl-5-\cc)(p-\cl-6-\cc)(p-\cl-7-\cc)(p-\cl-8-\cc)(p-\cl-9-\cc), + only on=<4-7>{tsp/best},only on=<8>{tsp/localbest},rectangle,rounded corners] (sol-\cl-\cc) {}; + \end{scope} + \begin{scope}[on background layer] + \def\cc{2} + \node[fit=(p-\cl-0-\cc)(p-\cl-1-\cc)(p-\cl-2-\cc)(p-\cl-3-\cc)(p-\cl-4-\cc)(p-\cl-5-\cc)(p-\cl-6-\cc)(p-\cl-7-\cc)(p-\cl-8-\cc)(p-\cl-9-\cc), + only on=<4-6>{tsp/best},rectangle,rounded corners] (sol-\cl-\cc) {}; + \end{scope} + \begin{scope}[on background layer] + \def\cc{3} + \node[fit=(p-\cl-0-\cc)(p-\cl-1-\cc)(p-\cl-2-\cc)(p-\cl-3-\cc)(p-\cl-4-\cc)(p-\cl-5-\cc)(p-\cl-6-\cc)(p-\cl-7-\cc)(p-\cl-8-\cc)(p-\cl-9-\cc), + only on=<4-6>{tsp/best},rectangle,rounded corners] (sol-\cl-\cc) {}; + \end{scope} + %}}} + + \begin{scope}[on background layer] + \draw[tsp/edge,semithick,foreach/.style={insert path=--(s-\cl-#1-0)}] (s-\cl-0-0) [foreach/.list={1,...,\last}] -- cycle; + \draw[tsp/edge,semithick,foreach/.style={insert path=--(s-\cl-#1-1)}] (s-\cl-0-1) [foreach/.list={1,...,\last}] -- cycle; + \draw[tsp/edge,semithick,foreach/.style={insert path=--(s-\cl-#1-2)}] (s-\cl-0-2) [foreach/.list={1,...,\last}] -- cycle; + \draw[tsp/edge,semithick,foreach/.style={insert path=--(s-\cl-#1-3)}] (s-\cl-0-3) [foreach/.list={1,...,\last}] -- cycle; + \end{scope} + \end{scope} + %}}} + + %{{{ fourth line " + \def\cl{4} + \begin{scope}[visible on=<5->,every path/.append style={visible on=<5->}] + \foreach \j in {0,...,3} { + \foreach \l in {0,...,2} { + \foreach \i in {0,...,\last} { + \coordinate (p-\cl-\i-\j-\l) at ($(p\i)!\ratioeven!(0,0)+(\bhstep*\j+\shstep*\l-.47,\vstep*\cl+1)$); + \node[tsp/node,minimum size=1pt] at (p-\cl-\i-\j-\l) {}; + } + + % box + \begin{scope}[on background layer] + \ifthenelse{\(\j=0 \AND \l=2\) \OR \(\j=1 \AND \l=0\) \OR \(\j=2 \AND \l=1\) \OR \(\j=3 \AND \l=0\)} + {\tikzset{local/.style={only on=<6>{tsp/best,thin}}}} + {\tikzset{local/.style={}}} + \node[fit=(p-\cl-0-\j-\l)(p-\cl-1-\j-\l)(p-\cl-2-\j-\l)(p-\cl-3-\j-\l)(p-\cl-4-\j-\l)(p-\cl-5-\j-\l)(p-\cl-6-\j-\l)(p-\cl-7-\j-\l)(p-\cl-8-\j-\l)(p-\cl-9-\j-\l), + local,rectangle,rounded corners,inner sep=1pt] (sol-\cl-\j-\l) {}; + \end{scope} + } + } + + %{{{ first column " + \foreach [count=\i from 0] \o in {0,1,9,8,7,6,4,5,3,2} { \coordinate (s-\cl-\i-0-0) at (p-\cl-\o-0-0); } + \foreach [count=\i from 0] \o in {0,9,3,8,7,6,4,5,1,2} { \coordinate (s-\cl-\i-0-1) at (p-\cl-\o-0-1); } + \foreach [count=\i from 0] \o in {0,9,1,8,7,6,5,4,3,2} { \coordinate (s-\cl-\i-0-2) at (p-\cl-\o-0-2); } + \begin{scope}[on background layer] + \draw[tsp/edge,very thin,foreach/.style={insert path=--(s-\cl-#1-0-0)}] (s-\cl-0-0-0) [foreach/.list={1,...,\last}] -- cycle; + \draw[tsp/edge,very thin,foreach/.style={insert path=--(s-\cl-#1-0-1)}] (s-\cl-0-0-1) [foreach/.list={1,...,\last}] -- cycle; + \draw[tsp/edge,very thin,foreach/.style={insert path=--(s-\cl-#1-0-2)}] (s-\cl-0-0-2) [foreach/.list={1,...,\last}] -- cycle; + \end{scope} + %}}} + %{{{ second column " + \foreach [count=\i from 0] \o in {5,4,3,6,8,7,1,9,0,2} { \coordinate (s-\cl-\i-1-0) at (p-\cl-\o-1-0); } + \foreach [count=\i from 0] \o in {8,5,3,6,4,7,1,9,0,2} { \coordinate (s-\cl-\i-1-1) at (p-\cl-\o-1-1); } + \foreach [count=\i from 0] \o in {7,5,3,6,8,4,1,9,0,2} { \coordinate (s-\cl-\i-1-2) at (p-\cl-\o-1-2); } + \begin{scope}[on background layer] + \draw[tsp/edge,very thin,foreach/.style={insert path=--(s-\cl-#1-1-0)}] (s-\cl-0-1-0) [foreach/.list={1,...,\last}] -- cycle; + \draw[tsp/edge,very thin,foreach/.style={insert path=--(s-\cl-#1-1-1)}] (s-\cl-0-1-1) [foreach/.list={1,...,\last}] -- cycle; + \draw[tsp/edge,very thin,foreach/.style={insert path=--(s-\cl-#1-1-2)}] (s-\cl-0-1-2) [foreach/.list={1,...,\last}] -- cycle; + \end{scope} + %}}} + %{{{ third column " + \foreach [count=\i from 0] \o in {2,8,0,9,1,7,4,6,5,3} { \coordinate (s-\cl-\i-2-0) at (p-\cl-\o-2-0); } + \foreach [count=\i from 0] \o in {2,1,0,9,8,7,6,4,5,3} { \coordinate (s-\cl-\i-2-1) at (p-\cl-\o-2-1); } + \foreach [count=\i from 0] \o in {2,1,0,5,8,7,4,6,9,3} { \coordinate (s-\cl-\i-2-2) at (p-\cl-\o-2-2); } + \begin{scope}[on background layer] + \draw[tsp/edge,very thin,foreach/.style={insert path=--(s-\cl-#1-2-0)}] (s-\cl-0-2-0) [foreach/.list={1,...,\last}] -- cycle; + \draw[tsp/edge,very thin,foreach/.style={insert path=--(s-\cl-#1-2-1)}] (s-\cl-0-2-1) [foreach/.list={1,...,\last}] -- cycle; + \draw[tsp/edge,very thin,foreach/.style={insert path=--(s-\cl-#1-2-2)}] (s-\cl-0-2-2) [foreach/.list={1,...,\last}] -- cycle; + \end{scope} + %}}} + %{{{ fourth column " + \foreach [count=\i from 0] \o in {5,6,7,4,8,1,9,0,2,3} { \coordinate (s-\cl-\i-3-0) at (p-\cl-\o-3-0); } + \foreach [count=\i from 0] \o in {5,7,6,4,8,1,3,0,2,9} { \coordinate (s-\cl-\i-3-1) at (p-\cl-\o-3-1); } + \foreach [count=\i from 0] \o in {5,7,6,4,2,1,9,0,8,3} { \coordinate (s-\cl-\i-3-2) at (p-\cl-\o-3-2); } + \begin{scope}[on background layer] + \draw[tsp/edge,very thin,foreach/.style={insert path=--(s-\cl-#1-3-0)}] (s-\cl-0-3-0) [foreach/.list={1,...,\last}] -- cycle; + \draw[tsp/edge,very thin,foreach/.style={insert path=--(s-\cl-#1-3-1)}] (s-\cl-0-3-1) [foreach/.list={1,...,\last}] -- cycle; + \draw[tsp/edge,very thin,foreach/.style={insert path=--(s-\cl-#1-3-2)}] (s-\cl-0-3-2) [foreach/.list={1,...,\last}] -- cycle; + \end{scope} + %}}} + \end{scope} + %}}} + + %{{{ fifth line " + \def\cl{5} + \begin{scope}[visible on=<7->,every path/.append style={visible on=<7->}] + \foreach \i in {0,...,\last} { + \foreach \j in {0,...,3} { + \coordinate (p-\cl-\i-\j) at ($(p\i)!\ratioodd!(0,0)+(\bhstep*\j,\vstep*\cl+1)$); + \node[tsp/node,minimum size=2pt] at (p-\cl-\i-\j) {}; + } + } + + \foreach [count=\i from 0] \o in {0,9,1,8,7,6,5,4,3,2} { \coordinate (s-\cl-\i-0) at (p-\cl-\o-0); } + \foreach [count=\i from 0] \o in {5,4,3,6,8,7,1,9,0,2} { \coordinate (s-\cl-\i-1) at (p-\cl-\o-1); } + \foreach [count=\i from 0] \o in {2,1,0,9,8,7,6,4,5,3} { \coordinate (s-\cl-\i-2) at (p-\cl-\o-2); } + \foreach [count=\i from 0] \o in {5,6,7,4,8,1,9,0,2,3} { \coordinate (s-\cl-\i-3) at (p-\cl-\o-3); } + \foreach \j in {0,...,3} { + \foreach \i in {0,...,\last} { + \node[tsp/node,minimum size=2pt] at (p-\cl-\i-\j) {}; + } + } + + %{{{ boxes " + \begin{scope}[on background layer] + \def\cc{0} + \node[fit=(p-\cl-0-\cc)(p-\cl-1-\cc)(p-\cl-2-\cc)(p-\cl-3-\cc)(p-\cl-4-\cc)(p-\cl-5-\cc)(p-\cl-6-\cc)(p-\cl-7-\cc)(p-\cl-8-\cc)(p-\cl-9-\cc), + rectangle,rounded corners] (sol-\cl-\cc) {}; + \end{scope} + \begin{scope}[on background layer] + \def\cc{1} + \node[fit=(p-\cl-0-\cc)(p-\cl-1-\cc)(p-\cl-2-\cc)(p-\cl-3-\cc)(p-\cl-4-\cc)(p-\cl-5-\cc)(p-\cl-6-\cc)(p-\cl-7-\cc)(p-\cl-8-\cc)(p-\cl-9-\cc), + rectangle,rounded corners] (sol-\cl-\cc) {}; + \end{scope} + \begin{scope}[on background layer] + \def\cc{2}% best all + \node[fit=(p-\cl-0-\cc)(p-\cl-1-\cc)(p-\cl-2-\cc)(p-\cl-3-\cc)(p-\cl-4-\cc)(p-\cl-5-\cc)(p-\cl-6-\cc)(p-\cl-7-\cc)(p-\cl-8-\cc)(p-\cl-9-\cc), + only on=<7-8>{tsp/best},rectangle,rounded corners] (sol-\cl-\cc) {}; + \end{scope} + \begin{scope}[on background layer] + \def\cc{3}% best + \node[fit=(p-\cl-0-\cc)(p-\cl-1-\cc)(p-\cl-2-\cc)(p-\cl-3-\cc)(p-\cl-4-\cc)(p-\cl-5-\cc)(p-\cl-6-\cc)(p-\cl-7-\cc)(p-\cl-8-\cc)(p-\cl-9-\cc), + only on=<7>{tsp/best},only on=<8>{tsp/localbest},rectangle,rounded corners] (sol-\cl-\cc) {}; + \end{scope} + %}}} + + \begin{scope}[on background layer] + \draw[tsp/edge,semithick,foreach/.style={insert path=--(s-\cl-#1-0)}] (s-\cl-0-0) [foreach/.list={1,...,\last}] -- cycle; + \draw[tsp/edge,semithick,foreach/.style={insert path=--(s-\cl-#1-1)}] (s-\cl-0-1) [foreach/.list={1,...,\last}] -- cycle; + \draw[tsp/edge,semithick,foreach/.style={insert path=--(s-\cl-#1-2)}] (s-\cl-0-2) [foreach/.list={1,...,\last}] -- cycle; + \draw[tsp/edge,semithick,foreach/.style={insert path=--(s-\cl-#1-3)}] (s-\cl-0-3) [foreach/.list={1,...,\last}] -- cycle; + \end{scope} + \end{scope} + %}}} + + %{{{ links " + \foreach \cl/\nl/\vi in {1/2/2,3/4/5} { + \foreach \j in {0,...,3} { + \foreach \l in {0,...,2} { + \draw[<-,>=stealth,visible on=<\vi->] (sol-\nl-\j-\l) -- (sol-\cl-\j); + } + } + } + \foreach \cl/\nl/\vi in {2/3/4,4/5/7} { + \foreach \j in {0,...,3} { + \foreach \l in {0,...,2} { + \draw[->,>=stealth,visible on=<\vi->] (sol-\cl-\j-\l) -- (sol-\nl-\j); + } + } + } + %}}} + + %{{{ + \begin{scope}[on background layer] + \foreach \i in {0,...,3} { + \node[fit=(sol-1-\i)(sol-2-\i-0)(sol-2-\i-1)(sol-2-\i-2)(sol-5-\i), + draw,rectangle,rounded corners,dashed,thin,inner sep=2pt,visible on=<9->] (els-\i) {}; + \node[node distance=.5pt,above=of els-\i,visible on=<9->] (els-\i-label) {\scriptsize ELS}; + } + + \node[fit=(els-0-label)(els-1-label)(els-2-label)(els-3-label),fill=green!70!black,rectangle,rounded + corners,opacity=.1,fit margins={top=.25pt,bottom=.25pt,left=11pt,right=11pt},visible on=<9->] {}; + + \foreach \i in {0,...,3} { + \foreach \cl in {2,4} { + \node[fit=(sol-\cl-\i-0)(sol-\cl-\i-1)(sol-\cl-\i-2),fill=green!70!black,rectangle,rounded + corners,opacity=.1,inner sep=2pt,visible on=<9->] {}; + } + } + \end{scope} + %}}} + + \only<10>{ + + } +\end{tikzpicture} diff --git a/src/fig/app/tspgreedysolution.tex b/src/fig/app/tspgreedysolution.tex new file mode 100644 index 0000000..2aaf338 --- /dev/null +++ b/src/fig/app/tspgreedysolution.tex @@ -0,0 +1,35 @@ +\begin{tikzpicture} + \input{src/tikz/tsp} + + \tspnodes + + % \def\tspstart{0} + + \coordinate (E) at (p\tspstart); + + \ifthenelse{\tspstart=0}{\def\tspsolution{0,9,1,8,7,6,4,2,3,5}}{} + \ifthenelse{\tspstart=1}{\def\tspsolution{1,8,7,9,0,2,4,5,6,3}}{} + \ifthenelse{\tspstart=2}{\def\tspsolution{2,1,0,9,8,7,4,3,5,6}}{} + \ifthenelse{\tspstart=3}{\def\tspsolution{3,4,5,6,8,7,1,2,0,9}}{} + \ifthenelse{\tspstart=4}{\def\tspsolution{4,5,3,6,8,7,1,2,0,9}}{} + \ifthenelse{\tspstart=5}{\def\tspsolution{5,4,3,6,8,7,1,2,0,9}}{} + \ifthenelse{\tspstart=6}{\def\tspsolution{6,4,5,3,8,7,1,2,0,9}}{} + \ifthenelse{\tspstart=7}{\def\tspsolution{7,8,6,4,5,1,9,0,2,3}}{} + \ifthenelse{\tspstart=8}{\def\tspsolution{8,7,6,4,5,1,9,0,2,3}}{} + \ifthenelse{\tspstart=9}{\def\tspsolution{9,0,1,8,7,6,4,5,3,2}}{} + + \foreach [count=\i from 0] \o in \tspsolution { + \coordinate (s\i) at (p\o); + } + + \foreach \i in {0,...,\last} { + \node[tsp/node] at (p\i) {}; + } + \node[tsp/node,common/drawfillf={black}{20}] at (E) {}; + + \ifthenelse{\istep=0}{}{ + \begin{scope}[on background layer] + \draw[tsp/edge,foreach/.style={insert path=--(s#1)}] (E) [foreach/.list={1,...,\istep}] -- cycle; + \end{scope} + } +\end{tikzpicture} diff --git a/src/fig/app/tspinstance.tex b/src/fig/app/tspinstance.tex new file mode 100644 index 0000000..6b5d7da --- /dev/null +++ b/src/fig/app/tspinstance.tex @@ -0,0 +1,18 @@ +\begin{tikzpicture} + \input{src/tikz/tsp} + + \tspnodes + + \foreach \i in {0,...,\last} { + \node[tsp/node] at (p\i) {}; + } + + \begin{scope}[on background layer] + \foreach \i in {0,...,\penult} { + \pgfmathtruncatemacro{\b}{\i+1} + \foreach \j in {\b,...,\last} { + \draw[black!40] (p\i) -- (p\j); + } + } + \end{scope} +\end{tikzpicture} diff --git a/src/fig/app/tspopti.tex b/src/fig/app/tspopti.tex new file mode 100644 index 0000000..50fca10 --- /dev/null +++ b/src/fig/app/tspopti.tex @@ -0,0 +1,18 @@ +\begin{tikzpicture}[thick] + \input{src/tikz/tsp} + + \tspnodes + + \coordinate (s0) at (p0); + \foreach [count=\i] \o in {1,2,3,5,4,6,7,8,9} { + \coordinate (s\i) at (p\o); + } + + \foreach \i in {0,...,\last} { + \node[tsp/node] at (p\i) {}; + } + + \begin{scope}[on background layer] + \draw[tsp/edge,foreach/.style={insert path=--(s#1)}] (p0) [foreach/.list={1,...,\last}] -- cycle; + \end{scope} +\end{tikzpicture} diff --git a/src/fig/app/tsprp.tex b/src/fig/app/tsprp.tex new file mode 100644 index 0000000..cc1d790 --- /dev/null +++ b/src/fig/app/tsprp.tex @@ -0,0 +1,9 @@ +\begin{tikzpicture}[remember picture] + \input{src/tikz/tsp} + + \tspnodes + + \foreach \i in {0,...,\last} { + \node[tsp/node,draw=none,fill=none] (tsp node \i) at (p\i) {}; + } +\end{tikzpicture} diff --git a/src/fig/app/tspsolution.tex b/src/fig/app/tspsolution.tex new file mode 100644 index 0000000..1704409 --- /dev/null +++ b/src/fig/app/tspsolution.tex @@ -0,0 +1,18 @@ +\begin{tikzpicture}[thick] + \input{src/tikz/tsp} + + \tspnodes + + \coordinate (s0) at (p0); + \foreach [count=\i] \o in {2,3,1,4,5,8,6,7,9} { + \coordinate (s\i) at (p\o); + } + + \foreach \i in {0,...,\last} { + \node[tsp/node] at (p\i) {}; + } + + \begin{scope}[on background layer] + \draw[tsp/edge,foreach/.style={insert path=--(s#1)}] (p0) [foreach/.list={1,...,\last}] -- cycle; + \end{scope} +\end{tikzpicture} diff --git a/src/fig/context/farmsel.tex b/src/fig/context/farmsel.tex new file mode 100644 index 0000000..3f944a8 --- /dev/null +++ b/src/fig/context/farmsel.tex @@ -0,0 +1,26 @@ +\begin{tikzpicture} + \input{src/tikz/parallel} + + \begin{scope}[node distance=6mm] + \begin{scope}[start chain=going below,every node/.style={on chain,join},parallel/arrow] + \node[parallel/block] (input) {}; + \node[parallel/point] (fork) {}; + \node[parallel/task] (main) {\dots}; + \node[parallel/point] (join) {}; + \node[parallel/task] (select) {T\textsubscript{S}}; + \node[parallel/block] (output) {}; + \end{scope} + + \node[parallel/task,left=of main] (thread 0) {T\textsubscript{0}}; + \node[parallel/task,right=of main] (thread n) {T\textsubscript{n-1}}; + \end{scope} + + \begin{scope}[on background layer] + \node[parallel/region=(thread 0)(main)(thread n)] {}; + \end{scope} + + \begin{scope}[parallel/arrow] + \draw (fork) -| (thread 0) |- (join); + \draw (fork) -| (thread n) |- (join); + \end{scope} +\end{tikzpicture} diff --git a/src/fig/context/par.tex b/src/fig/context/par.tex new file mode 100644 index 0000000..585719e --- /dev/null +++ b/src/fig/context/par.tex @@ -0,0 +1,31 @@ +\begin{tikzpicture} + \input{src/tikz/orchestration} + + \begin{scope}[overlay] + \node(origin){}; + \node at (origin) (t-1) {}; + \end{scope} + + \begin{scope}[node distance=4mm and 12mm] + \node[orch/task=black,right=of t-1] (t0) {m\textsubscript{0}}; + \node[orch/task=black,right=of t0] (t1) {m\textsubscript{1}}; + \node[orch/task=white,draw=none,fill=none,node distance=6mm,right=of t1] (t2) {\dots}; + \node[orch/task=black,node distance=6mm,right=of t2] (t3) {m\textsubscript{N-2}}; + \node[orch/task=black,right=of t3] (t4) {m\textsubscript{N-1}}; + + \foreach \i/\t in {0/0,1/1,3/N-2,4/N-1} { + \node[above=of t\i] (label\i) {\en{thread}~\t}; + \node[below=of t\i] (endthread\i) {}; + } + \end{scope} + + \foreach \i in {0,1,3,4} { + \draw[-] (label\i) -- (t\i); + \draw[-] (t\i) -- (endthread\i); + } + + \begin{scope}[on background layer] + \node[common/drawfill=green!40!black,dashed,rectangle,rounded corners,fit=(t0)(t4)](par){}; + \end{scope} +\end{tikzpicture} + diff --git a/src/fig/context/seq.tex b/src/fig/context/seq.tex new file mode 100644 index 0000000..ca33ee3 --- /dev/null +++ b/src/fig/context/seq.tex @@ -0,0 +1,31 @@ +\begin{tikzpicture} + \input{src/tikz/orchestration} + + \begin{scope}[overlay] + \node(origin){}; + \node at (origin) (t-1) {}; + \end{scope} + + \begin{scope}[node distance=4mm and 4mm] + \node[orch/task=black,below=of t-1] (t0) {m\textsubscript{0}}; + \node[orch/task=white,draw=none,fill=none,below=of t0] (t1) {}; + \node[orch/task=black,below=of t1] (t2) {m\textsubscript{N-1}}; + + \node[above=of t0] (label0) {\en{thread}~0}; + \node[below=of t2] (endthread0) {}; + \end{scope} + + \draw[-] (label0) -- (t0); + + \draw[-] (t0) -- (t1); + \draw[dashed] (t1.north) -- (t1.south); + \draw[-] (t1) -- (t2); + + \draw[-] (t2) -- (endthread0); + + \begin{scope}[common/overlay] + \draw[decorate,decoration={brace, amplitude=4pt, raise=9mm, mirror}] + (t0.north) -- (t2.south) node[left,midway,xshift=-11mm] {$N$ tâches}; + \end{scope} +\end{tikzpicture} + diff --git a/src/fig/context/threadpool.tex b/src/fig/context/threadpool.tex new file mode 100644 index 0000000..330a52f --- /dev/null +++ b/src/fig/context/threadpool.tex @@ -0,0 +1,51 @@ +\begin{tikzpicture} + \input{src/tikz/exec} + + % pool + \begin{scope}[start chain=circle placed {at=(\tikzchaincount*72+18:.8)}] + \foreach \i in {0,...,4} { + \node[on chain,exec/thread=black] (t\i) {t\textsubscript{\i}}; + } + \end{scope} + \path (t0) |- node[pos=.2,exec/thread=black]{t\textsubscript{k}} ($(t2)!.5!(t3)$); + + \begin{scope}[on background layer] + \node[exec/pool=(t0)(t1)(t2)(t3)(t4)](pool){}; + \end{scope} + \path (pool.north west) -- node[above]{\en{pool}} (pool.north east); + + \draw[decorate,decoration={brace,amplitude=4pt,raise=3pt,mirror}] + (pool.north west) -- node[left=5pt]{$k+1$ \en{threads}} (pool.south west); + + % fifo + \node[exec/fifonode,draw=none,fill=none,above=of t0](fifo3) {\dots}; + \begin{scope}[node distance=-.1mm,start chain=fifo] + \foreach \i/\p/\n in {2/3/n-2,1/2/n-1,0/1/n} { \node[exec/fifonode,left=of fifo\p] (fifo\i) {$m_{\n}$}; } + \foreach \i/\p/\n in {4/3/2,5/4/1,6/5/0} { \node[exec/fifonode,right=of fifo\p] (fifo\i) {$m_{\n}$}; } + \end{scope} + \draw[-,densely dotted] ([yshift=-.05mm]fifo3.north west) -- ([yshift=-.05mm]fifo3.north east); + \draw[-,densely dotted] ([yshift=+.05mm]fifo3.south west) -- ([yshift=+.05mm]fifo3.south east); + + \node[exec/fit=(fifo0)(fifo6),fit margins={left=2.25mm},dash phase=2](mutex) {}; + \path (mutex.north west) + -- node[above](lblmutex){accès en section critique (\en{mutex}) à la file de tâches} (mutex.north east); + + % arrows + \draw[-] ([xshift=-8mm]fifo0.west) -- (fifo0.west); + + \draw[->,rounded corners] (fifo6.east) -- ++(4mm,0) |- (pool.east); + + \coordinate (mutexeast) at ([xshift=3mm]mutex.east); + \node[exec/fit=(lblmutex)(mutex)(pool)(mutexeast),densely dashed](threadpool) {}; + \path (threadpool.north west) -- node[above]{\en{thread pool}} (threadpool.north east); + + % background + \begin{scope}[on background layer] + \node[fit=(threadpool),inner sep=3ex,rectangle,rounded corners,fill=white,opacity=.95]{}; + \end{scope} + + % fix thread pool border + \begin{scope}[on background layer] + \node[exec/pool=(t0)(t1)(t2)(t3)(t4)]{}; + \end{scope} +\end{tikzpicture} diff --git a/src/fig/exec/firstlevel.tex b/src/fig/exec/firstlevel.tex new file mode 100644 index 0000000..db8792b --- /dev/null +++ b/src/fig/exec/firstlevel.tex @@ -0,0 +1,70 @@ +\begin{tikzpicture} + \input{src/tikz/orchestration} + + % \def\N{12} + % \def\T{4} + + \pgfmathtruncatemacro{\nlasttask}{\N-1} + \pgfmathtruncatemacro{\nlastthread}{\T-1} + \pgfmathtruncatemacro{\R}{mod(\N, \T)} + + \begin{scope}[overlay] + \node(origin){}; + \node at (origin) (t-\T) {}; + \end{scope} + + \begin{scope}[node distance=4mm and 4mm] + \foreach \task in {0,...,\nlasttask} { + \pgfmathtruncatemacro{\r}{mod(\task, \T)} + \ifthenelse{\r = 0}{ + \pgfmathtruncatemacro{\uppertask}{\T*(\task/\T-1)} + \def\reltype{below} + \def\relnode{t\uppertask} + }{ + \pgfmathtruncatemacro{\prevtask}{\task-1} + \def\reltype{right} + \def\relnode{t\prevtask} + } + \node[orch/task=black,\reltype=of \relnode] (t\task) {m\textsubscript{\task}}; + } + + \ifthenelse{\R = 0}{}{ + \pgfmathtruncatemacro{\ntaskfill}{mod(\T-\R, \T)-1} + \foreach \taskfill in {0,...,\ntaskfill} { + \pgfmathtruncatemacro{\task}{\nlasttask+\taskfill+1} + \pgfmathtruncatemacro{\prevtask}{\task-1} + \node[orch/task=white,draw=none,fill=none,right=of t\prevtask] (t\task) {}; + \draw[-] (t\task.north) -- (t\task.south); + } + } + + \foreach \thread in {0,...,\nlastthread} { + \node[above=of t\thread] (label\thread) {\en{thread}~\thread}; + \draw[-] (label\thread) -- (t\thread); + + \pgfmathtruncatemacro{\n}{floor((\N-1)/\T)-1} + \ifthenelse{\n = -1}{}{% only if N>T + \foreach \task in {0,...,\n} { + \pgfmathtruncatemacro{\curtask}{\thread+\task*\T} + \pgfmathtruncatemacro{\nexttask}{\curtask+\T} + \draw[-] (t\curtask) -- (t\nexttask); + } + } + + \pgfmathtruncatemacro{\lasttask}{\thread+(\n+1)*\T} + \node[below=of t\lasttask] (endthread\thread) {}; + \draw[-] (t\lasttask) -- (endthread\thread); + } + \end{scope} + + \begin{scope}[common/overlay] + \draw[decorate,decoration={brace, amplitude=4pt, raise=9mm, mirror}] + (t0.north) -- (t0.south) node[left,midway,xshift=-11mm] {$T$}; + + \pgfmathtruncatemacro{\n}{ceil(\N/\T)} + \pgfmathtruncatemacro{\nr}{(\N-1)/\T} + \pgfmathtruncatemacro{\ftlt}{\nr*\T} + \draw[decorate,decoration={brace, amplitude=4pt, raise=18mm, mirror}] + (t0.north) -- (t\ftlt.south) node[left,midway,xshift=-20mm] {$\n\,T$}; + \end{scope} +\end{tikzpicture} diff --git a/src/fig/exec/firstleveldetails.tex b/src/fig/exec/firstleveldetails.tex new file mode 100644 index 0000000..c94885f --- /dev/null +++ b/src/fig/exec/firstleveldetails.tex @@ -0,0 +1,76 @@ +\begin{tikzpicture} + \input{src/tikz/orchestration} + + % \def\N{15} + % \def\T{6} + + \pgfmathtruncatemacro{\nlasttask}{\N-1} + \pgfmathtruncatemacro{\nlastthread}{\T-1} + \pgfmathtruncatemacro{\R}{mod(\N, \T)} + + \begin{scope}[overlay] + \node(origin){}; + \node at (origin) (t-\T) {}; + \end{scope} + + \begin{scope}[node distance=4mm and 4mm] + \foreach \task in {0,...,\nlasttask} { + \pgfmathtruncatemacro{\r}{mod(\task, \T)} + \ifthenelse{\r = 0}{ + \pgfmathtruncatemacro{\uppertask}{\T*(\task/\T-1)} + \def\reltype{below} + \def\relnode{t\uppertask} + }{ + \pgfmathtruncatemacro{\prevtask}{\task-1} + \def\reltype{right} + \def\relnode{t\prevtask} + } + \node[orch/task=black,\reltype=of \relnode] (t\task) {}; + + \draw[-] (t\task.north) + -- node[pos=.3,orch/subtask=black] {} + node[pos=.7,orch/subtask=black] {} + (t\task.south); + } + + \ifthenelse{\R = 0}{}{ + \pgfmathtruncatemacro{\ntaskfill}{mod(\T-\R, \T)-1} + \foreach \taskfill in {0,...,\ntaskfill} { + \pgfmathtruncatemacro{\task}{\nlasttask+\taskfill+1} + \pgfmathtruncatemacro{\prevtask}{\task-1} + \node[orch/task=white,draw=none,fill=none,right=of t\prevtask] (t\task) {}; + \draw[-] (t\task.north) -- (t\task.south); + } + } + + \foreach \thread in {0,...,\nlastthread} { + \node[above=of t\thread] (label\thread) {\en{thread}~\thread}; + \draw[-] (label\thread) -- (t\thread); + + \pgfmathtruncatemacro{\n}{floor((\N-1)/\T)-1} + \ifthenelse{\n = -1}{}{% only if N>T + \foreach \task in {0,...,\n} { + \pgfmathtruncatemacro{\curtask}{\thread+\task*\T} + \pgfmathtruncatemacro{\nexttask}{\curtask+\T} + \draw[-] (t\curtask) -- (t\nexttask); + } + } + + \pgfmathtruncatemacro{\lasttask}{\thread+(\n+1)*\T} + \node[below=of t\lasttask] (endthread\thread) {}; + \draw[-] (t\lasttask) -- (endthread\thread); + } + \end{scope} + + \begin{scope}[common/overlay] + \pgfmathtruncatemacro{\n}{2*ceil(\N/\T)} + \pgfmathtruncatemacro{\nr}{(\N-1)/\T} + \pgfmathtruncatemacro{\ftlt}{\nr*\T} + + \draw[decorate,decoration={brace, amplitude=4pt, raise=9mm, mirror}] + (t0.north) -- (t0.south) node[left,midway,xshift=-11mm] {$2\,T$}; + + \draw[decorate,decoration={brace, amplitude=4pt, raise=18mm, mirror}] + (t0.north) -- (t\ftlt.south) node[left,midway,xshift=-20mm] {$\n\,T$}; + \end{scope} +\end{tikzpicture} diff --git a/src/fig/exec/multilevel.tex b/src/fig/exec/multilevel.tex new file mode 100644 index 0000000..de3eec3 --- /dev/null +++ b/src/fig/exec/multilevel.tex @@ -0,0 +1,85 @@ +\begin{tikzpicture} + \input{src/tikz/orchestration} + + % \def\N{15} + % \def\T{6} + + \pgfmathtruncatemacro{\nlasttask}{\N-1} + \pgfmathtruncatemacro{\nlastthread}{\T-1} + \pgfmathtruncatemacro{\R}{mod(\N, \T)} + + \begin{scope}[overlay] + \node(origin){}; + \node at (origin) (t-\T) {}; + \end{scope} + + \begin{scope}[node distance=4mm and 4mm] + \pgfmathtruncatemacro{\nlasttaskA}{\nlasttask-\R} + + \foreach \task in {0,...,\nlasttaskA} { + \pgfmathtruncatemacro{\r}{mod(\task, \T)} + \ifthenelse{\r = 0}{ + \pgfmathtruncatemacro{\uppertask}{\T*(\task/\T-1)} + \def\reltype{below} + \def\relnode{t\uppertask} + }{ + \pgfmathtruncatemacro{\prevtask}{\task-1} + \def\reltype{right} + \def\relnode{t\prevtask} + } + \node[orch/task=black,\reltype=of \relnode] (t\task) {}; + + \draw[-] (t\task.north) + -- node[pos=.3,orch/subtask=black] {} + node[pos=.7,orch/subtask=black] {} + (t\task.south); + } + + \foreach \taskfill in {1,...,\R} { + \pgfmathtruncatemacro{\task}{\taskfill-1} + \pgfmathtruncatemacro{\prevtaskl}{\nlasttaskA+\task-\T+\taskfill)} + \pgfmathtruncatemacro{\prevtaskr}{\prevtaskl+1} + \path (t\prevtaskl.south) -- coordinate[midway](prevtask\taskfill) (t\prevtaskr.south); + \node[orch/taskspan=black,below=of prevtask\taskfill] (ts\task) {}; + + \pgfmathtruncatemacro{\taska}{\nlasttaskA+\task*2+1} + \pgfmathtruncatemacro{\taskb}{\nlasttaskA+\task*2+2} + + \path (t\prevtaskl.south) |- node[orch/subtask=black] (t\taska) {} (ts\task.west); + \path (t\prevtaskr.south) |- node[orch/subtask=black] (t\taskb) {} (ts\task.west); + } + + \foreach \thread in {0,...,\nlastthread} { + \node[above=of t\thread] (label\thread) {\en{thread}~\thread}; + \draw[-] (label\thread) -- (t\thread); + + \pgfmathtruncatemacro{\n}{floor((\N-1)/\T)-1} + \ifthenelse{\n = -1}{}{% only if N>T + \foreach \task in {0,...,\n} { + \pgfmathtruncatemacro{\curtask}{\thread+\task*\T} + \pgfmathtruncatemacro{\nexttask}{\curtask+\T} + \draw[-] (t\curtask) -- (t\nexttask); + } + } + + \pgfmathtruncatemacro{\lasttask}{\thread+(\n+1)*\T} + \draw[-] (t\lasttask) -- (\curcoord |- ts0.south) -- +(0,-4mm); + } + \end{scope} + + \begin{scope}[common/overlay] + \pgfmathtruncatemacro{\n}{ceil((2*\N-1)/\T)} + \pgfmathtruncatemacro{\nr}{(\N-1)/\T} + \pgfmathtruncatemacro{\ftlt}{\nr*\T} + \node[orch/task=black,draw=none,fill=none](lt) at (t\ftlt) {}; + + \draw[decorate,decoration={brace, amplitude=4pt, raise=9mm, mirror}] + (t0.north) -- (t0.south) node[left,midway,xshift=-11mm] {$2\,T$}; + + \draw[decorate,decoration={brace, amplitude=4pt, raise=9mm, mirror}] + (lt.north) -- (lt.south) node[left,midway,xshift=-11mm] {$T$}; + + \draw[decorate,decoration={brace, amplitude=4pt, raise=18mm, mirror}] + (t0.north) -- (lt.south) node[left,midway,xshift=-20mm] {$\n{}\,T$}; + \end{scope} +\end{tikzpicture} diff --git a/src/fig/exec/threadpool.tex b/src/fig/exec/threadpool.tex new file mode 100644 index 0000000..7800225 --- /dev/null +++ b/src/fig/exec/threadpool.tex @@ -0,0 +1,50 @@ +\begin{tikzpicture} + \input{src/tikz/exec} + + % pool + \begin{scope}[start chain=circle placed {at=(\tikzchaincount*72+18:.8)}] + \foreach \i in {0,...,4} { + \node[on chain,exec/thread=black] (t\i) {t\textsubscript{\i}}; + } + \end{scope} + \path (t0) |- node[pos=.2,exec/thread=black]{t\textsubscript{k}} ($(t2)!.5!(t3)$); + + \begin{scope}[on background layer] + \node[exec/pool=(t0)(t1)(t2)(t3)(t4)](pool){}; + \end{scope} + \path (pool.north west) -- node[above]{\en{pool}} (pool.north east); + + \draw[decorate,decoration={brace,amplitude=4pt,raise=3pt,mirror}] + (pool.north west) -- node[left=5pt]{$k+1$ \en{threads}} (pool.south west); + + % fifo + \node[exec/fifonode,draw=none,fill=none,above=of t0](fifo3) {}; + \begin{scope}[node distance=-.1mm,start chain=fifo] + \foreach \i/\p/\n in {2/3/n-2,1/2/n-1,0/1/n} { \node[exec/fifonode,left=of fifo\p] (fifo\i) {$m_{\n}$}; } + \foreach \i/\p/\n in {4/3/2,5/4/1,6/5/0} { \node[exec/fifonode,right=of fifo\p] (fifo\i) {$m_{\n}$}; } + \end{scope} + \draw[-,densely dotted] ([yshift=-.05mm]fifo3.north west) -- ([yshift=-.05mm]fifo3.north east); + \draw[-,densely dotted] ([yshift=+.05mm]fifo3.south west) -- ([yshift=+.05mm]fifo3.south east); + + \node[exec/fit=(fifo0)(fifo6),fit margins={left=2.25mm},dash phase=2](mutex) {}; + \path (mutex.north west) + -- node[above](lblmutex){accès en section critique (\en{mutex}) à la file de tâches} (mutex.north east); + + % arrows + \draw[-] ([xshift=-8mm]fifo0.west) -- (fifo0.west); + + \draw[->,rounded corners] (fifo6.east) -- ++(4mm,0) |- (pool.east); + + \coordinate (mutexeast) at ([xshift=3mm]mutex.east); + \node[exec/fit=(lblmutex)(mutex)(pool)(mutexeast),densely dashed](threadpool) {}; + + % background + \begin{scope}[on background layer] + \node[fit=(threadpool),inner sep=3ex,rectangle,rounded corners,fill=white,opacity=.95]{}; + \end{scope} + + % fix thread pool border + \begin{scope}[on background layer] + \node[exec/pool=(t0)(t1)(t2)(t3)(t4)]{}; + \end{scope} +\end{tikzpicture} diff --git a/src/fig/mp/et_basic.tex b/src/fig/mp/et_basic.tex new file mode 100644 index 0000000..1441398 --- /dev/null +++ b/src/fig/mp/et_basic.tex @@ -0,0 +1,7 @@ +\begin{tikzpicture} + \input{src/tikz/et} + + \begin{scope}[et/treestyle] + \Tree[.\texttt{+} \texttt{a} [.\texttt{*} \texttt{b} \texttt{c} ] ] + \end{scope} +\end{tikzpicture} diff --git a/src/fig/mp/et_linexpr.tex b/src/fig/mp/et_linexpr.tex new file mode 100644 index 0000000..927a601 --- /dev/null +++ b/src/fig/mp/et_linexpr.tex @@ -0,0 +1,14 @@ +\begin{tikzpicture} + \input{src/tikz/et} + + \begin{scope}[et/treestyle,level distance=12mm] + \Tree + [.\texttt{-} + [.\texttt{*} + \texttt{5} + [.\texttt{+} [.\texttt{*} \texttt{2} \texttt{x} ] \texttt{1} ] + ] + [.\texttt{+} \texttt{x} \texttt{3} ] + ] + \end{scope} +\end{tikzpicture} diff --git a/src/fig/mp/et_linexpr_opti0.tex b/src/fig/mp/et_linexpr_opti0.tex new file mode 100644 index 0000000..62f25c0 --- /dev/null +++ b/src/fig/mp/et_linexpr_opti0.tex @@ -0,0 +1,11 @@ +\begin{tikzpicture} + \input{src/tikz/et} + + \begin{scope}[et/treestyle,level distance=12mm] + \Tree + [.\texttt{-} + [.\texttt{+} [.\texttt{*} \texttt{10} \texttt{x} ] \texttt{5} ] + [.\texttt{+} \texttt{x} \texttt{3} ] + ] + \end{scope} +\end{tikzpicture} diff --git a/src/fig/mp/et_linexpr_opti1.tex b/src/fig/mp/et_linexpr_opti1.tex new file mode 100644 index 0000000..910533a --- /dev/null +++ b/src/fig/mp/et_linexpr_opti1.tex @@ -0,0 +1,7 @@ +\begin{tikzpicture} + \input{src/tikz/et} + + \begin{scope}[et/treestyle,level distance=12mm] + \Tree[.\texttt{+} [.\texttt{*} \texttt{9} \texttt{x} ] \texttt{2} ] + \end{scope} +\end{tikzpicture} diff --git a/src/fig/mp/metaprogram.tex b/src/fig/mp/metaprogram.tex new file mode 100644 index 0000000..9375940 --- /dev/null +++ b/src/fig/mp/metaprogram.tex @@ -0,0 +1,17 @@ +\begin{tikzpicture} + \input{src/tikz/mp} + + \pic[local bounding box=cpptmp] at (0,0) {program}; + \pic[local bounding box=cpp] at (4,0) {program}; + \pic[local bounding box=bin] at (8,0) {binary}; + + \path (cpptmp.north west) -- node[above,align=center]{C++ avec\\templates} (cpptmp.north east); + \path (cpp.north west) -- node[above]{C++} (cpp.north east); + \path (bin.north west) -- node[above]{binaire} (bin.north east); + + \begin{scope}[->,>=stealth] + \draw[double distance=2pt] ($(cpptmp.east)!.5!(cpp.west)$) -- ++(0,-1.3) -- ++(-3,0) |- (cpptmp.west); + \draw[double distance=2pt] (cpptmp) -- node[above]{\footnotesize compilation} (cpp); + \draw[double distance=2pt] (cpp) -- node[above]{\footnotesize compilation} (bin); + \end{scope} +\end{tikzpicture} diff --git a/src/fig/pagemask.tex b/src/fig/pagemask.tex new file mode 100644 index 0000000..ec35ef6 --- /dev/null +++ b/src/fig/pagemask.tex @@ -0,0 +1,6 @@ +\begin{tikzpicture}[remember picture,overlay] + \coordinate (north west) at ([yshift=-16.1mm]current page.north west); + \coordinate (south east) at (current page.south east); + + \fill[opacity=.7,black] (north west) rectangle (south east); +\end{tikzpicture}% diff --git a/src/fig/pfor/indices.tex b/src/fig/pfor/indices.tex new file mode 100644 index 0000000..85d4539 --- /dev/null +++ b/src/fig/pfor/indices.tex @@ -0,0 +1,16 @@ +\begin{tikzpicture} + \input{src/tikz/et} + + \begin{scope}[et/treestyle] + \Tree[., + [.= + [.\texttt{[]} a i ] + [.\texttt{*} [.\texttt{[]} a i ] [.\texttt{[]} b i ] ] + ] + [.= + [.\texttt{[]} c i ] + [.\texttt{[]} c [.\texttt{+} i 1 ] ] + ] + ]; + \end{scope} +\end{tikzpicture} diff --git a/src/fig/pfor/indices_small.tex b/src/fig/pfor/indices_small.tex new file mode 100644 index 0000000..2065d28 --- /dev/null +++ b/src/fig/pfor/indices_small.tex @@ -0,0 +1,10 @@ +\begin{tikzpicture} + \input{src/tikz/et} + + \begin{scope}[et/treestyle] + \Tree[.= + [.\texttt{[]} c i ] + [.\texttt{[]} c [.\texttt{+} i 1 ] ] + ]; + \end{scope} +\end{tikzpicture} diff --git a/src/fig/repeat/identify.tex b/src/fig/repeat/identify.tex new file mode 100644 index 0000000..06d237d --- /dev/null +++ b/src/fig/repeat/identify.tex @@ -0,0 +1,92 @@ +\begin{tikzpicture} + \input{src/tikz/alsk} + + \begin{scope}[alsk/treestyle, + alsk/tree/muscle/.append style={font=\footnotesize,minimum width=8mm,minimum height=3mm}, + alsk/tree/struct/.append style={font=\footnotesize,minimum width=12mm,minimum height=3mm}, + level distance=11mm, sibling distance=16mm, + every node/.style=leaf, + ] + \node[branch](farmsel1){farmsel\textsubscript{1}} + child{ node[branch](serial1){serial\textsubscript{1}} + child{ node(ch){HC} } + child{ node[branch](serial2){serial\textsubscript{2}} + child{ node(init ls){RLI} } + child{ node[branch](itersel){itersel} + child{ node[branch](farmsel2){farmsel\textsubscript{2}} + child{ node[branch](serial3){serial\textsubscript{3}} + child{ node(m){M} } + child{ node(ls){RL} } + } + child{ node(sel3){Sel\textsubscript{3}} } + } + child{ node(sel2){Sel\textsubscript{2}} } + } + } + } + child{ node(sel1){Sel\textsubscript{1}} }; + \end{scope} + + % task count + \path (farmsel1) -- node[left=2mm]{\only<4->{\footnotesize$a \times$}} (serial1); + \path (farmsel2) -- node[left=2mm]{\only<6->{\footnotesize$b \times$}} (serial3); + + % identifiers + \begin{scope}[ + ->,dashed,rounded corners=1mm, + frame/.style={draw,rectangle,rounded corners=1mm,dashed,fit=#1} + ] + \coordinate (yline) at ($(farmsel1)+(30mm,0)$); + + \path[only on=<2->{draw}] (farmsel1) -- (farmsel1 -| yline) node(n9t){}; + \path[only on=<3->{draw}] (sel1) -- (sel1 -| yline) node(n9b){}; + + \path[only on=<{4-7,10-}>{draw}] (serial1) |- ++(0,-5mm) -- (\curcoord -| yline) node(nat){}; + + \visible<5-7,10->{ + \node[frame=(ch)(itersel)(farmsel2)(sel2)] (fserial1) {}; + } + \path[only on=<{5-7,10-}>{draw}] (fserial1) -- (fserial1 -| yline) node(nfs1){}; + \path[only on=<{5-7,10-}>{draw}] (sel3) -- (sel3 -| yline) node(nab){}; + + \path[only on=<{6-7,9-}>{draw}] (serial3) |- ++(0,-5mm) -- (\curcoord -| yline) node(nbt){}; + \visible<7,9->{ + \node[frame=(m)(ls)] (fserial3) {}; + } + \path[only on=<{7,9-}>{draw}] (fserial3) -- (fserial3 -| yline) node(nbb){}; + \end{scope} + + \begin{scope} + \only<2>{\node[right] at (n9t) {\num{1} exécution};} + \only<4>{\node[right] at (nat) {$a$ exécutions parallèles};} + \only<6>{\node[right] at (nbt) {$a \times b$ exécutions parallèles};} + \end{scope} + + \begin{scope}[decoration={brace,amplitude=4pt,raise=4pt}] + \visible<3-7,8->{ + \draw[decorate] (n9t.north) -- (n9b.south) node[midway,right=10pt] + {\alt<3-7>{\num{1} exécution}{$\text{id} = 0$}}; + } + \visible<5-7,10->{ + \draw[decorate] (nat.north) -- (nab.south) node[midway,right=10pt,only on=<10->{text justified}] + {\alt<5-7>{$a$ exécutions parallèles}{$ + \begin{aligned} + &\text{id} \in \{0, b, 2\,b, \dots, (a-1)\,b\}\\ + &\iff \text{id} \in b\,\llbracket 0, a \llbracket + \end{aligned} + $}}; + } + \visible<7>{ + \draw[decorate] (nbt.north) -- (nbb.south) node[midway,right=10pt] + {$a \times b$ exécutions parallèles}; + } + \visible<9>{ + \draw[decorate] (nbt.north) -- (nbb.south) node[midway,right=10pt] + {$\text{id} \in \llbracket 0, a\,b \llbracket$}; + } + \visible<10->{ + \draw[decorate] (nbt.north) -- (nbb.south) node[midway,right=10pt] + {$\text{id} \in \llbracket 0, a\,b \llbracket (= \displaystyle\bigcup^{a-1}_{k=0} \llbracket k\,b, (k+1)\,b-1 \rrbracket)$}; + } + \end{scope} +\end{tikzpicture} diff --git a/src/fig/repeat/par.tex b/src/fig/repeat/par.tex new file mode 100644 index 0000000..d85f46d --- /dev/null +++ b/src/fig/repeat/par.tex @@ -0,0 +1,63 @@ +\begin{tikzpicture} + \input{src/tikz/orchestration} + + \tikzset{orch/task/.append style={minimum width=10mm}} + + \pgfmathtruncatemacro{\nlasttask}{\N-1} + \pgfmathtruncatemacro{\nlastthread}{\T-1} + \pgfmathtruncatemacro{\R}{mod(\N, \T)} + + \begin{scope}[overlay] + \node(origin){}; + \node at (origin) (t-\T) {}; + \end{scope} + + \begin{scope}[node distance=3mm and 3mm] + \pgfmathtruncatemacro{\multiplier}{\N/\T} + \pgfmathtruncatemacro{\offset}{mod(\N, \T)} + + \foreach \task in {0,...,\nlasttask} { + \pgfmathtruncatemacro{\r}{mod(\task, \T)} + \ifthenelse{\r = 0}{ + \pgfmathtruncatemacro{\uppertask}{\T*(\task/\T-1)} + \def\reltype{below} + \def\relnode{t\uppertask} + }{ + \pgfmathtruncatemacro{\prevtask}{\task-1} + \def\reltype{right} + \def\relnode{t\prevtask} + } + + \pgfmathtruncatemacro{\id}{(\task/\T)+\r*\multiplier+min(\r, \offset)} + \node[orch/task=black,\reltype=of \relnode] (t\task) {$m_\id$}; + } + + \ifthenelse{\R = 0}{}{ + \pgfmathtruncatemacro{\ntaskfill}{mod(\T-\R, \T)-1} + \foreach \taskfill in {0,...,\ntaskfill} { + \pgfmathtruncatemacro{\task}{\nlasttask+\taskfill+1} + \pgfmathtruncatemacro{\prevtask}{\task-1} + \node[orch/task=white,draw=none,fill=none,right=of t\prevtask] (t\task) {}; + \draw[-] (t\task.north) -- (t\task.south); + } + } + + \foreach \thread in {0,...,\nlastthread} { + \node[above=of t\thread] (label\thread) {\footnotesize\en{thread}~\thread}; + \draw[-] (label\thread) -- (t\thread); + + \pgfmathtruncatemacro{\n}{floor((\N-1)/\T)-1} + \ifthenelse{\n = -1}{}{% only if N>T + \foreach \task in {0,...,\n} { + \pgfmathtruncatemacro{\curtask}{\thread+\task*\T} + \pgfmathtruncatemacro{\nexttask}{\curtask+\T} + \draw[-] (t\curtask) -- (t\nexttask); + } + } + + \pgfmathtruncatemacro{\lasttask}{\thread+(\n+1)*\T} + \node[below=of t\lasttask] (endthread\thread) {}; + \draw[-] (t\lasttask) -- (endthread\thread); + } + \end{scope} +\end{tikzpicture} diff --git a/src/fig/repeat/prng/par.tex b/src/fig/repeat/prng/par.tex new file mode 100644 index 0000000..c25e9bd --- /dev/null +++ b/src/fig/repeat/prng/par.tex @@ -0,0 +1,28 @@ +\begin{tikzpicture} + \input{src/tikz/repeat} + + \visible<1->{ + \begin{scope}[start chain,node distance=0pt,every node/.style={on chain,prng/element}] + \node[only on=<2-12>{opacity=.8},only on=<2->{prng/drawfill=a}](a0) {12}; + \foreach[count=\i from 3] \v/\col in {2/b,34/a,85/b,4/a,91/b,29/a,85/b,98/a,3/b,35/b,65/a} { + \node[only on=<\i-12>{opacity=.8},only on=<\i->{prng/drawfill=\col}] {\v}; + } + \end{scope} + } + \visible<14->{ + \begin{scope}[start chain,node distance=0pt,every node/.style={on chain,prng/element}] + \node[prng/drawfill=b,prng/below=a0](b0) {12}; + \foreach[count=\i from 3] \v/\col in {2/b,34/a,85/a,4/b,91/a,29/a,85/b,98/a,3/b,35/a,65/b} { + \node[prng/drawfill=\col] {\v}; + } + \end{scope} + } + \visible<15->{ + \begin{scope}[start chain,node distance=0pt,every node/.style={on chain,prng/element}] + \node[prng/drawfill=b,prng/below=b0](c0) {12}; + \foreach[count=\i from 3] \v/\col in {2/a,34/a,85/a,4/b,91/a,29/b,85/b,98/b,3/b,35/a,65/a} { + \node[prng/drawfill=\col] {\v}; + } + \end{scope} + } +\end{tikzpicture} diff --git a/src/fig/repeat/prng/parthread.tex b/src/fig/repeat/prng/parthread.tex new file mode 100644 index 0000000..f87eee0 --- /dev/null +++ b/src/fig/repeat/prng/parthread.tex @@ -0,0 +1,23 @@ +\begin{tikzpicture} + \input{src/tikz/repeat} + + \begin{scope}[start chain,node distance=0pt,every node/.style={on chain,prng/element}] + \node[prng/drawfill=a](a0) {12}; + \foreach[count=\i from 1] \v/\col in {2/a,34/a,85/a,4/a,91/a,29/c,85/c,98/c,3/c,35/c,65/c} { + \node[prng/drawfill=\col] (a\i) {\v}; + } + \end{scope} + + \visible<-1>{ + \begin{scope}[start chain,node distance=0pt,every node/.style={on chain,prng/element}] + \node[prng/drawfill=b,node distance=5mm,below=of a0](b0) {42}; + \foreach[count=\i from 1] \v/\col in {8/b,9/b,54/b,95/b,80/b,48/c,7/c,10/c,58/c,18/c,44/c} { + \node[prng/drawfill=\col] (b\i) {\v}; + } + \end{scope} + \node[fit=(a0)(b0)(a11)(b11),fit margins={right=2mm},draw,rectangle,dashed,rounded corners]{}; + } + \visible<2->{ + \node[fit=(a0)(a11),fit margins={right=2mm},draw,rectangle,dashed,rounded corners]{}; + } +\end{tikzpicture} diff --git a/src/fig/repeat/prng/seq.tex b/src/fig/repeat/prng/seq.tex new file mode 100644 index 0000000..a90b88c --- /dev/null +++ b/src/fig/repeat/prng/seq.tex @@ -0,0 +1,18 @@ +\begin{tikzpicture} + \input{src/tikz/repeat} + + \begin{scope}[start chain,node distance=0pt,every node/.style={on chain,prng/element}] + \node[only on=<2-13>{opacity=.8},only on=<2->{prng/drawfill=a}](a0) {12}; + \foreach[count=\i from 3] \v/\col in {2/a,34/a,85/a,4/a,91/a,29/b,85/b,98/b,3/b,35/b,65/b} { + \node[only on=<\i-13>{opacity=.8},only on=<\i->{prng/drawfill=\col}] {\v}; + } + \end{scope} + \begin{scope}[start chain,node distance=0pt,every node/.style={on chain,prng/element,opacity=0}] + \node[prng/below=a0](b0) {12}; + \foreach \v in {2,34,85,4,91,29,85,98,3,35,65} { \node{\v}; } + \end{scope} + \begin{scope}[start chain,node distance=0pt,every node/.style={on chain,prng/element,opacity=0}] + \node[prng/below=b0](c0) {12}; + \foreach \v in {2,34,85,4,91,29,85,98,3,35,65} { \node {\v}; } + \end{scope} +\end{tikzpicture} diff --git a/src/fig/repeat/seq.tex b/src/fig/repeat/seq.tex new file mode 100644 index 0000000..3a3fc46 --- /dev/null +++ b/src/fig/repeat/seq.tex @@ -0,0 +1,28 @@ +\begin{tikzpicture} + \input{src/tikz/orchestration} + + \tikzset{orch/task/.append style={minimum width=10mm}} + + \begin{scope}[overlay] + \node(origin){}; + \node at (origin) (t-1) {}; + \end{scope} + + \begin{scope}[node distance=3mm and 3mm] + \node[orch/task=black,below=of t-1] (t0) {$m_0$}; + \node[orch/task=white,draw=none,fill=none,below=of t0] (t1) {}; + \node[orch/task=black,below=of t1] (t2) {$m_8$}; + + \node[above=of t0] (label0) {\footnotesize\en{thread}~0}; + \node[below=of t2] (endthread0) {}; + \end{scope} + + \draw[-] (label0) -- (t0); + + \draw[-] (t0) -- (t1); + \draw[dashed] (t1.north) -- (t1.south); + \draw[-] (t1) -- (t2); + + \draw[-] (t2) -- (endthread0); +\end{tikzpicture} + diff --git a/src/lst/alsk/elsbody.tex b/src/lst/alsk/elsbody.tex new file mode 100644 index 0000000..13cdd12 --- /dev/null +++ b/src/lst/alsk/elsbody.tex @@ -0,0 +1,6 @@ +\begin{cppcode} + using Els = SkelEls< + tsp::Problem, tsp::Solution, + iLS, M, LS, sel2, sel3, A + >; +\end{cppcode} diff --git a/src/lst/alsk/grasp.tex b/src/lst/alsk/grasp.tex new file mode 100644 index 0000000..9f4ca6b --- /dev/null +++ b/src/lst/alsk/grasp.tex @@ -0,0 +1,13 @@ +\begin{cppcode} + template< + typename Problem, typename Solution, + typename CH, typename LS, typename Sel + > + using SkelGrasp = BuildSkeleton< + SkelGraspStructure, + SkelGraspLinks + >::template skeleton< + Pack, + Pack + >; +\end{cppcode} diff --git a/src/lst/alsk/grasp_links.tex b/src/lst/alsk/grasp_links.tex new file mode 100644 index 0000000..ed84e95 --- /dev/null +++ b/src/lst/alsk/grasp_links.tex @@ -0,0 +1,13 @@ +\begin{cppcode} + template< + typename Problem, typename Solution + > + using SkelGraspLinks = + L}|(|\textcolor{colSp0}{P<0>}|), + |\textcolor{colCHr}{Solution}|(|\textcolor{colCHp0}{P<0>}|, |\textcolor{colCHp1}{RNG}|), + |\textcolor{colLSr}{Solution}|(|\textcolor{colLSp0}{R<0>}|, |\textcolor{colLSp1}{RNG}|) + >, + |\textcolor{colSelr}{Solution}|(|\textcolor{colSelp}{Solution}|, |\textcolor{colSelp}{Solution}|) + >; +\end{cppcode} diff --git a/src/lst/alsk/grasp_struct.tex b/src/lst/alsk/grasp_struct.tex new file mode 100644 index 0000000..66d6458 --- /dev/null +++ b/src/lst/alsk/grasp_struct.tex @@ -0,0 +1,12 @@ +\begin{cppcode} + template< + typename |\textcolor{colMuscle}{CH}|, typename |\textcolor{colMuscle}{LS}|, typename |\textcolor{colMuscle}{S}| + > + using SkelGraspStructure = + S<|\textcolor{colStruct}{FarmSel}|, + S<|\textcolor{colStruct}{Serial}|, + |\textcolor{colMuscle}{CH}|, |\textcolor{colMuscle}{LS}| + >, + |\textcolor{colMuscle}{S}| + >; +\end{cppcode} diff --git a/src/lst/alsk/graspbody.tex b/src/lst/alsk/graspbody.tex new file mode 100644 index 0000000..20ecc10 --- /dev/null +++ b/src/lst/alsk/graspbody.tex @@ -0,0 +1,6 @@ +\begin{cppcode} + using GraspEls = SkelGrasp< + tsp::Problem, tsp::Solution, + Greedy, Els, sel1 + >; +\end{cppcode} diff --git a/src/lst/alsk/graspexec.tex b/src/lst/alsk/graspexec.tex new file mode 100644 index 0000000..1d3837f --- /dev/null +++ b/src/lst/alsk/graspexec.tex @@ -0,0 +1,11 @@ +\begin{cppcode} + auto graspEls = implement(); + + graspEls.skeleton.n = 10; + graspEls.skeleton.task.task<1>().task<1>().n = 15; + graspEls.skeleton.task.task<1>().task<1>().task.n = 20; + + graspEls.executor.cores = 16; + + tsp::Solution solution = graspEls(problem); +\end{cppcode} diff --git a/src/lst/intro/loop_par.tex b/src/lst/intro/loop_par.tex new file mode 100644 index 0000000..14960c4 --- /dev/null +++ b/src/lst/intro/loop_par.tex @@ -0,0 +1,4 @@ +\begin{cppcode} + for(int i = 0; i < N; ++i) + a[i] = a[i] + 1; +\end{cppcode} diff --git a/src/lst/intro/loop_par_hard.tex b/src/lst/intro/loop_par_hard.tex new file mode 100644 index 0000000..1930bfd --- /dev/null +++ b/src/lst/intro/loop_par_hard.tex @@ -0,0 +1,4 @@ +\begin{cppcode} + for(int i = 1; i < N; i += 2) + a[i] = a[i-1]; +\end{cppcode} diff --git a/src/lst/intro/loop_seq.tex b/src/lst/intro/loop_seq.tex new file mode 100644 index 0000000..00696f6 --- /dev/null +++ b/src/lst/intro/loop_seq.tex @@ -0,0 +1,4 @@ +\begin{cppcode} + for(int i = 1; i < N; ++i) + a[i] = a[i-1]; +\end{cppcode} diff --git a/src/lst/mp/cpplogo.tex b/src/lst/mp/cpplogo.tex new file mode 100644 index 0000000..ca07cf6 --- /dev/null +++ b/src/lst/mp/cpplogo.tex @@ -0,0 +1,22 @@ +\begin{minicppcode} + static char *cpplogo_data = + "````````````````````````W/(Q@+<7@+<7W/(Q````````````````````````" + "````````````````[?\\WF\\8=::L3::L3::L3::L3F\\8=[?\\W````````````````" + "````````^PD]MM@L=;$5::L3::L3::L3B+L9K=(BK-$BB+L9::L3::L3::L3=;$5S>@L_`T^" + "J,XA::L3::L3::L3B;L9X/8S````````````````X/4SB;L9::L3::L3::L3H<46" + "::L3::L3::L3B;L9]`<[````````````````````````]`<[B;L98:,,-GWL!&G=" + "::L3::L3::L3X?8S````````[O`XOMTGOMTG[O`X````^P@ZF;<&!&G=!&G=!&G=" + "::L3::L3B;L9````````[O`X=;$5::L3::L3=K(5OM482G[F!&G=!&G=!&G=!&G=" + "::L3::L3KM,C````````O=PG::L3::L36YT&+'?G!&G=5(/HR=T<9H[MR=T<9H[M" + "::L3::L3K],C````````O-PG8:$)/GGB$5W,!&;9!&G=;I3PVNPFA*3YVNPFA*3Y" + "::L3::L3B;L9````````[?XT06O/!%3#!%3#/FG-N]$3/7?C!&G=!&G=!&G=!&G=" + "::L3::L3::L3XO0N````````Z_HNKL$\"KL$\"Z_HN````^P@ZD:W\\!&G=!&G=!&G=" + "::L379P$-F_798/:]@,U````````````````````````]@,U98/:&ES*!&77!&G=" + "E[8$!%3#!%3#!%3#98/:X.\\F````````````````X.\\E98/:!%3#!%3#!%3#CJ?T" + "_`P]P=(//&?+!%3#!%3#!%3#98/:G[3ZG[3Z98/:!%3#!%3#!%3#/&?+P-(._`P]" + "````````]P0VI;C]!%3#!%3#!%3#!%3#!%3#!%3#!%3#!%3#I;C]]P0V````````" + "````````````````YO4J?)7E!%3#!%3#!%3#!%3#?)7EYO4J````````````````" + "````````````````````````TN(;4W;24W;2TN(;````````````````````````" + ""; +\end{minicppcode} diff --git a/src/lst/mp/edsl_basic.tex b/src/lst/mp/edsl_basic.tex new file mode 100644 index 0000000..3f31d97 --- /dev/null +++ b/src/lst/mp/edsl_basic.tex @@ -0,0 +1,3 @@ +\begin{cppcode} + auto e = a + b * c; +\end{cppcode} diff --git a/src/lst/mp/edsl_linexpr.tex b/src/lst/mp/edsl_linexpr.tex new file mode 100644 index 0000000..ec7a4d7 --- /dev/null +++ b/src/lst/mp/edsl_linexpr.tex @@ -0,0 +1,3 @@ +\begin{cppcode} + 5 * (2 * x + 1) - (x + 3) +\end{cppcode} diff --git a/src/lst/mp/edsl_linexpr_opti.tex b/src/lst/mp/edsl_linexpr_opti.tex new file mode 100644 index 0000000..00c897e --- /dev/null +++ b/src/lst/mp/edsl_linexpr_opti.tex @@ -0,0 +1,3 @@ +\begin{cppcode} + 9 * x + 2 +\end{cppcode} diff --git a/src/lst/mp/edsl_linexpr_opti0.tex b/src/lst/mp/edsl_linexpr_opti0.tex new file mode 100644 index 0000000..3311cd6 --- /dev/null +++ b/src/lst/mp/edsl_linexpr_opti0.tex @@ -0,0 +1,3 @@ +\begin{cppcode} + 10 * x + 5 - (x + 3) +\end{cppcode} diff --git a/src/lst/mp/et.tex b/src/lst/mp/et.tex new file mode 100644 index 0000000..894b9db --- /dev/null +++ b/src/lst/mp/et.tex @@ -0,0 +1,16 @@ +\begin{cppcode} + Expr, + Expr, x + > + Cst<1> + > + >, + Expr + > + > +\end{cppcode} diff --git a/src/lst/mp/et_basic.tex b/src/lst/mp/et_basic.tex new file mode 100644 index 0000000..050ff9f --- /dev/null +++ b/src/lst/mp/et_basic.tex @@ -0,0 +1,9 @@ +\begin{cppcode} + Expr + > +\end{cppcode} diff --git a/src/lst/mp/et_pattern_lin.tex b/src/lst/mp/et_pattern_lin.tex new file mode 100644 index 0000000..9498978 --- /dev/null +++ b/src/lst/mp/et_pattern_lin.tex @@ -0,0 +1,7 @@ +\begin{cppcode} + Lin -> + Expr, x>, + Cst + > +\end{cppcode} diff --git a/src/lst/mp/et_pattern_mulcstlin.tex b/src/lst/mp/et_pattern_mulcstlin.tex new file mode 100644 index 0000000..f2fe770 --- /dev/null +++ b/src/lst/mp/et_pattern_mulcstlin.tex @@ -0,0 +1,4 @@ +\begin{cppcode} + Opt, Lin> + -> Lin +\end{cppcode} diff --git a/src/lst/mp/et_pattern_sublinlin.tex b/src/lst/mp/et_pattern_sublinlin.tex new file mode 100644 index 0000000..5226870 --- /dev/null +++ b/src/lst/mp/et_pattern_sublinlin.tex @@ -0,0 +1,4 @@ +\begin{cppcode} + Opt, Lin> + -> Lin +\end{cppcode} diff --git a/src/lst/mp/opadd.tex b/src/lst/mp/opadd.tex new file mode 100644 index 0000000..c9e80ce --- /dev/null +++ b/src/lst/mp/opadd.tex @@ -0,0 +1,6 @@ +\begin{cppcode} + template + auto operator+(Lhs, Rhs) { + return Expr{}; + } +\end{cppcode} diff --git a/src/lst/mp/opmul.tex b/src/lst/mp/opmul.tex new file mode 100644 index 0000000..0183d6d --- /dev/null +++ b/src/lst/mp/opmul.tex @@ -0,0 +1,6 @@ +\begin{cppcode} + template + auto operator*(Lhs, Rhs) { + return Expr{}; + } +\end{cppcode} diff --git a/src/lst/mp/pow.ct.asm.tex b/src/lst/mp/pow.ct.asm.tex new file mode 100644 index 0000000..14b56a5 --- /dev/null +++ b/src/lst/mp/pow.ct.asm.tex @@ -0,0 +1,7 @@ +\begin{asmcode} + imul ecx, ecx ; |$x^2$| + imul ecx, eax ; |$x^3$| + imul ecx, ecx ; |$x^6$| + imul ecx, ecx ; |$x^{12}$| + imul ecx, ecx ; |$x^{24}$| +\end{asmcode} diff --git a/src/lst/mp/pow.ct.call.tex b/src/lst/mp/pow.ct.call.tex new file mode 100644 index 0000000..87103bd --- /dev/null +++ b/src/lst/mp/pow.ct.call.tex @@ -0,0 +1,4 @@ +\begin{cppcode} + int x = 2; + int r = pow<24>(x); +\end{cppcode} diff --git a/src/lst/mp/pow.ct.tex b/src/lst/mp/pow.ct.tex new file mode 100644 index 0000000..c0d513f --- /dev/null +++ b/src/lst/mp/pow.ct.tex @@ -0,0 +1,11 @@ +\begin{cppcode} + template + constexpr int pow(int x) { + return x * pow(x); + } + + template<> + constexpr int pow<0>(int) { + return 1; + } +\end{cppcode} diff --git a/src/lst/mp/pow.rt.asm.tex b/src/lst/mp/pow.rt.asm.tex new file mode 100644 index 0000000..d9e97ae --- /dev/null +++ b/src/lst/mp/pow.rt.asm.tex @@ -0,0 +1,12 @@ +\begin{asmcode} + lea eax, [rsi-0x1] + mov r8d, 0x1 + test esi, esi + |\tikzmark{powjend}|jle end +|\tikzmark{powlloop}|loop: + |\tikzmark{powimul}|imul r8d, edi + |\tikzmark{powsub}|sub eax, 0x1 + |\tikzmark{powjloop}|jae loop +|\tikzmark{powlend}|end: + mov eax, r8d +\end{asmcode} diff --git a/src/lst/mp/pow.rt.call.tex b/src/lst/mp/pow.rt.call.tex new file mode 100644 index 0000000..0c76d10 --- /dev/null +++ b/src/lst/mp/pow.rt.call.tex @@ -0,0 +1,4 @@ +\begin{cppcode} + int x = 2; + int r = pow(x, 24); +\end{cppcode} diff --git a/src/lst/mp/pow.rt.tex b/src/lst/mp/pow.rt.tex new file mode 100644 index 0000000..1552f16 --- /dev/null +++ b/src/lst/mp/pow.rt.tex @@ -0,0 +1,7 @@ +\begin{cppcode} + int pow(int x, int n) { + int r = 1; + while(n-- > 0) r *= x; + return r; + } +\end{cppcode} diff --git a/src/lst/mp/tmptype.tex b/src/lst/mp/tmptype.tex new file mode 100644 index 0000000..9609f70 --- /dev/null +++ b/src/lst/mp/tmptype.tex @@ -0,0 +1,6 @@ +\begin{cppcode*}{mp tmptype} + template + struct Array { + T data[n]; + }; +\end{cppcode*} diff --git a/src/lst/mp/tmptype_Foo_256.tex b/src/lst/mp/tmptype_Foo_256.tex new file mode 100644 index 0000000..deea082 --- /dev/null +++ b/src/lst/mp/tmptype_Foo_256.tex @@ -0,0 +1,5 @@ +\begin{cppcode*}{mp tmptype Foo 256} + struct { + Foo data[256]; + }; +\end{cppcode*} diff --git a/src/lst/mp/tmptype_float_3.tex b/src/lst/mp/tmptype_float_3.tex new file mode 100644 index 0000000..962cae9 --- /dev/null +++ b/src/lst/mp/tmptype_float_3.tex @@ -0,0 +1,5 @@ +\begin{cppcode*}{mp tmptype float 3} + struct { + float data[3]; + }; +\end{cppcode*} diff --git a/src/lst/mp/tmptype_int_5.tex b/src/lst/mp/tmptype_int_5.tex new file mode 100644 index 0000000..8551d2a --- /dev/null +++ b/src/lst/mp/tmptype_int_5.tex @@ -0,0 +1,5 @@ +\begin{cppcode*}{mp tmptype int 5} + struct { + int data[5]; + }; +\end{cppcode*} diff --git a/src/lst/pfor/indices_small.tex b/src/lst/pfor/indices_small.tex new file mode 100644 index 0000000..9500e56 --- /dev/null +++ b/src/lst/pfor/indices_small.tex @@ -0,0 +1,4 @@ +\begin{cppcode} + Index i; + auto e = (c[i] = c[i+ctv<1>]); +\end{cppcode} diff --git a/src/lst/pfor/loop.tex b/src/lst/pfor/loop.tex new file mode 100644 index 0000000..2c0f7e8 --- /dev/null +++ b/src/lst/pfor/loop.tex @@ -0,0 +1,9 @@ +\begin{cppcode} + for(int i = 0; i < n; ++i) { + |\tikzmark{pforloopl2b}|a[i] = a[i] * |\tikzmark{pforloopbrb}|b[i]|\tikzmark{pforloopbre}|;|\tikzmark{pforloopl2e}| + |\tikzmark{pforloopl3b}\tikzmark{pforloopcwb}|c[i]|\tikzmark{pforloopcwe}| = c[i+1] - |\tikzmark{pforloopdrb}|d[i]|\tikzmark{pforloopdre}|;|\tikzmark{pforloopl3e}| + |\tikzmark{pforloopl4b}\tikzmark{pforloopbwb}|b[i]|\tikzmark{pforloopbwe}| = b[i] + i;|\tikzmark{pforloopl4e}| + |\tikzmark{pforloopl5b}\tikzmark{pforloopdwb}|d[i]|\tikzmark{pforloopdwe}| = std::pow(|\tikzmark{pforloopcrb}|c[i]|\tikzmark{pforloopcre}|, e[i]);|\tikzmark{pforloopl5e}| + |\tikzmark{pforloopl6b}|f[i*i] = 2 * f[i*i];|\tikzmark{pforloopl6e}| + } +\end{cppcode} diff --git a/src/lst/pfor/loop_noanim.tex b/src/lst/pfor/loop_noanim.tex new file mode 100644 index 0000000..6cf1ba3 --- /dev/null +++ b/src/lst/pfor/loop_noanim.tex @@ -0,0 +1,9 @@ +\begin{cppcode} + for(int i = 0; i < n; ++i) { + a[i] = a[i] * b[i]; + c[i] = c[i+1] - d[i]; + b[i] = b[i] + i; + d[i] = std::pow(c[i], e[i]); + f[i*i] = 2 * f[i*i]; + } +\end{cppcode} diff --git a/src/lst/pfor/loop_par.tex b/src/lst/pfor/loop_par.tex new file mode 100644 index 0000000..d63d85d --- /dev/null +++ b/src/lst/pfor/loop_par.tex @@ -0,0 +1,13 @@ +\begin{cppcode} + #pragma omp parallel for + for(int i = 0; i < n; ++i) { + a[i] = a[i] * b[i]; + b[i] = b[i] + i; + f[i*i] = 2 * f[i*i]; + } + + for(int i = 0; i < n; ++i) { + c[i] = c[i+1] - d[i]; + d[i] = std::pow(c[i], e[i]); + } +\end{cppcode} diff --git a/src/lst/pfor/loop_pfor.tex b/src/lst/pfor/loop_pfor.tex new file mode 100644 index 0000000..883ad4d --- /dev/null +++ b/src/lst/pfor/loop_pfor.tex @@ -0,0 +1,9 @@ +\begin{cppcode} + parallelFor(Range{0, n}, + a[i] = a[i] * b[i], + c[i] = c[i+ctv<1>] - d[i], + b[i] = b[i] + i, + d[i] = pow(c[i], e[i]) + f[i*i] = 2 * f[i*i] + ); +\end{cppcode} diff --git a/src/lst/pfor/loop_split.tex b/src/lst/pfor/loop_split.tex new file mode 100644 index 0000000..687de56 --- /dev/null +++ b/src/lst/pfor/loop_split.tex @@ -0,0 +1,14 @@ +\begin{cppcode} + for(int i = 0; i < n; ++i) { + a[i] = a[i] * b[i]; + b[i] = b[i] + i; + } + + for(int i = 0; i < n; ++i) { + |\tikzmark{pforloopsplitcwb}|c[i]|\tikzmark{pforloopsplitcwe}| = |\tikzmark{pforloopsplitcrb}|c[i+1]|\tikzmark{pforloopsplitcre}| - d[i]; + d[i] = std::pow(c[i], e[i]); + } + + for(int i = 0; i < n; ++i) + f[i*i] = 2 * f[i*i]; +\end{cppcode} diff --git a/src/main_default.tex b/src/main_default.tex new file mode 100644 index 0000000..8db4703 --- /dev/null +++ b/src/main_default.tex @@ -0,0 +1,11 @@ +\input{src/usr/silence} + +\documentclass{beamer} + +\input{src/preamble} +\input{src/usr/beamer} + +% \setbeameroption{show notes on second screen=right} +% \includeonlyframes{current} + +\input{src/document} diff --git a/src/main_notes.tex b/src/main_notes.tex new file mode 100644 index 0000000..5ec5c76 --- /dev/null +++ b/src/main_notes.tex @@ -0,0 +1,18 @@ +\input{src/usr/silence} + +\documentclass{beamer} + +\input{src/preamble} +\input{src/usr/beamer} + +\setbeameroption{show notes on second screen=right} +% \setbeamertemplate{note page}{ + % { + % \centering + % \insertslideintonotes{0.4} + % } + % \rule{\textwidth}{0.1pt} + % \insertnote +% } + +\input{src/document} diff --git a/src/preamble.tex b/src/preamble.tex new file mode 100644 index 0000000..53febd8 --- /dev/null +++ b/src/preamble.tex @@ -0,0 +1,168 @@ +%{{{ packages " +\usepackage[T1]{fontenc} +\usepackage[utf8]{inputenc} +\usepackage[english,main=french]{babel} + +\usepackage{lmodern} +\usepackage{microtype} + +\usepackage{minted}% before csquotes +\usepackage[most,minted]{tcolorbox} + +% \usepackage[ + % backend=biber, + % doi=false,isbn=false, + % style=alphabetic,citestyle=authoryear,sorting=nyt, + % maxbibnames=99,maxcitenames=2,uniquelist=false, + % language=auto]{biblatex} + +\usepackage{multicol} + +\usepackage{amsmath}% cleveref +\usepackage{amsthm} +\usepackage{amssymb} +\usepackage{stmaryrd} +\usepackage{ulem} + +\usepackage[binary-units]{siunitx} + +\usepackage{algorithm} + +\usepackage{tikz} +\usepackage{ifthen} +\usepackage[tikz]{ocgx2} +\usepackage{tikz-qtree} + +\usepackage{morewrites}% increase 16 open files limit (scrwfile is incompatible with titletoc) +\usepackage{chngcntr} + +\PassOptionsToPackage{hyphens}{url} +\usepackage{hyperref} +\usepackage[noabbrev,nameinlink]{cleveref}% after hyperref (see documentation) +\usepackage[commentColor=black!75]{algpseudocodex}% after cleveref +% \usepackage[acronyms,section=chapter]{glossaries-extra}% after hyperref +\usepackage{sty/acref}% after cleveref +%}}} + +%{{{ configuration " +\title{Application de la métaprogrammation template à la conception de bibliothèques actives de +parallélisation assistée} +\subtitle{} +\author[Alexis Pereda]{Alexis Pereda} +\institute[UCA]{Université Clermont Auvergne} +\date{01/07/2021} + +\subject{Application de la métaprogrammation template à la conception de bibliothèques actives de +parallélisation assistée} +\keywords{C++, métaprogrammation, template, parallélisation, parallélisation automatique, +répétabilité} + +% \input{src/usr/bibstyle} +% \addbibresource{src/references.bib} +% \AtEveryCite{\restorecommand\mkbibnamefamily}% disable small caps in citations + +\sisetup{locale=FR} +\DeclareSIUnit{\octet}{o} + +\microtypesetup{ + protrusion=alltext-nott, + expansion=alltext-nott, + final +} + +\hypersetup{ + pdftitle={Soutenance de thèse sur l'application de la métaprogrammation template à la conception + de bibliothèques actives de parallélisation assistée}, + pdfnewwindow=true, + % colorlinks, + linkcolor={red!50!black}, + citecolor={blue!50!black}, + urlcolor={blue!80!black} +} + +%{{{ TikZ " +\usetikzlibrary{shapes,matrix,fit,spy,arrows.meta,chains,backgrounds} +\usetikzlibrary{positioning,intersections,calc} +\usetikzlibrary{decorations.pathreplacing,decorations.pathmorphing} +\usetikzlibrary{shadows,patterns} +\usetikzlibrary{tikzmark} +\usetikzlibrary{external} + +\AtBeginEnvironment{tikzpicture}{\shorthandoff{;}} +%}}} + +%{{{ acref " +\crefname{listing}{extrait de code}{extraits de code} +\Crefname{listing}{Extrait de code}{Extraits de code} +\acrefarticle{listing}{l'}{L'} +%}}} + +%{{{ locale " +\renewcommand{\listingscaption}{Extrait de code} +\renewcommand{\listoflistingscaption}{Liste des extraits de code} + +% \DefineBibliographyStrings{french}{% + % backrefpage = {page}, + % backrefpages = {pages}, + % in = {dans}, +% } +% \DeclareFieldFormat{titlecase}{\MakeSentenceCase{\foreignlanguage{english}{#1}}} +%}}} +%}}} + +%{{{ input extra configuration " +\input{src/usr/alg} +\input{src/usr/colors} +\input{src/usr/listing} +\input{src/usr/math} +\input{src/usr/ocg} +\input{src/usr/tikz} +%}}} + +%{{{ other input " +\input{src/tikz/common} +%}}} + +%{{{ commands " +\newcommand*{\en}[1]{\foreignlanguage{english}{\textit{#1}}} +\newcommand*{\encitetitle}[1]{{\foreignlanguage{english}{\citetitle{#1}}}} + +\newcommand*{\chapterdir}{} +\newcommand*{\inputchd}[2]{\input{src/#1/\chapterdir/#2}} +\newcommand*{\labelchd}[2]{\label{#1:\chapterdir/#2}} + +\def\compilationversion{} + +\input{src/commands} + +\newcommand{\fig}[1]{% + \begin{figure}% + \input{src/fig/#1}% + \end{figure}% +} +\newcommand<>{\figonly}[1]{\only#2{\fig{#1}}} +\newcommand<>{\figvisible}[1]{\visible#2{\fig{#1}}} +\newcommand<>{\figuncover}[1]{\uncover#2{\fig{#1}}} + +\newcommand{\alg}[1]{% + \input{src/alg/#1}% +} + +\newcommand{\lst}[1]{% + \input{src/lst/#1}% +} +\newcommand<>{\lstonly}[1]{\only#2{\lst{#1}}} +\newcommand<>{\lstvisible}[1]{\visible#2{\lst{#1}}} + +\newcommand\resetpauses{\setcounter{beamerpauses}{1}} +\newcommand\startnotes{\resetpauses} + +\newcommand<>{\colorletonly}[2]{\only#3{\colorlet{#1}{#2}}} +%}}} + +%{{{ glossaries " +% \makeglossaries +% \setabbreviationstyle[acronym]{short-long} + +% \input{src/acronyms} +%}}} diff --git a/src/references.bib b/src/references.bib new file mode 100644 index 0000000..cfa17b5 --- /dev/null +++ b/src/references.bib @@ -0,0 +1,2457 @@ + +@book{ref:abrahams2004, + title = {C++ Template Metaprogramming: Concepts, Tools, and Techniques from Boost and Beyond}, + shorttitle = {C++ Template Metaprogramming}, + author = {Abrahams, David and Gurtovoy, Aleksey}, + date = {2004}, + edition = {5. printing}, + publisher = {{Addison-Wesley}}, + location = {{Boston, Mass}}, + annotation = {OCLC: 553640289}, + isbn = {978-0-321-22725-6}, + langid = {english}, + pagetotal = {373}, + series = {The {{C}}++ In-Depth Series} +} + +@inproceedings{ref:ahmad1997, + title = {Automatic Parallelization and Scheduling of Programs on Multiprocessors Using {{CASCH}}}, + booktitle = {Proceedings of the {{International Conference}} on {{Parallel Processing}}}, + author = {Ahmad, Ishfaq and Kwok, Yu-Kwong and Wu, Min-You and Shu, Wei}, + date = {1997}, + pages = {288--291}, + publisher = {{IEEE Computer Society}}, + location = {{Washington, DC, USA}}, + doi = {10.1109/ICPP.1997.622657}, + isbn = {978-0-8186-8108-0}, + langid = {english}, + series = {{{ICPP}} '97} +} + +@book{ref:aho1986, + title = {Compilers: Principles, Techniques, and Tools}, + shorttitle = {Compilers}, + author = {Aho, Alfred V and Sethi, Ravi and Ullman, Jeffrey D}, + date = {1986}, + publisher = {{Pearson Education}}, + location = {{India}}, + annotation = {OCLC: 57725385}, + isbn = {978-81-7808-046-8}, + langid = {english} +} + +@inproceedings{ref:aldinucci2009, + title = {Efficient Streaming Applications on Multi-Core with {{FastFlow}}: The Biosequence Alignment Test-Bed}, + booktitle = {{{ParCo}} 2009: {{Parallel Computing}}}, + author = {Aldinucci, Marco and Danelutto, Marco and Meneghin, Massimiliano and Torquati, Massimo and Kilpatrick, Peter}, + date = {2009-09}, + volume = {19}, + pages = {273--280}, + doi = {10.3233/978-1-60750-530-3-273}, + langid = {english} +} + +@article{ref:alexandrescu2000, + title = {Traits: The Else-If-Then of Types}, + author = {Alexandrescu, Andrei}, + date = {2000}, + journaltitle = {C++ Report}, + volume = {12}, + langid = {english}, + number = {4} +} + +@book{ref:alexandrescu2001, + title = {Modern {{C}}++ Design: Generic Programming and Design Patterns Applied}, + shorttitle = {Modern {{C}}++ Design}, + author = {Alexandrescu, Andrei}, + date = {2001}, + edition = {2. print}, + publisher = {{Addison-Wesley}}, + location = {{Boston, Mass.}}, + annotation = {OCLC: 747927476}, + isbn = {0-201-70431-5}, + langid = {english}, + pagetotal = {352}, + series = {The {{C}}++ In-Depth Series} +} + +@inproceedings{ref:amdahl1967, + title = {Validity of the Single Processor Approach to Achieving Large Scale Computing Capabilities}, + booktitle = {Proceedings of the {{April}} 18-20, 1967, Spring Joint Computer Conference on - {{AFIPS}} '67 ({{Spring}})}, + author = {Amdahl, Gene M.}, + date = {1967}, + pages = {483}, + publisher = {{ACM Press}}, + location = {{Atlantic City, New Jersey}}, + doi = {10.1145/1465482.1465560}, + eventtitle = {The {{April}} 18-20, 1967, Spring Joint Computer Conference}, + langid = {english} +} +% == BibLateX quality report for ref:amdahl1967: +% ? Unsure about the formatting of the booktitle + +@inproceedings{ref:arabnejad2018, + title = {{{AutoPar}}-{{Clava}}: {{An Automatic Parallelization}} Source-to-Source Tool for {{C}} Code Applications}, + shorttitle = {{{AutoPar}}-{{Clava}}}, + booktitle = {Proceedings of the 9th {{Workshop}} and 7th {{Workshop}} on {{Parallel Programming}} and {{RunTime Management Techniques}} for {{Manycore Architectures}} and {{Design Tools}} and {{Architectures}} for {{Multicore Embedded Computing Platforms}} - {{PARMA}}-{{DITAM}} '18}, + author = {Arabnejad, Hamid and Bispo, Jo\~ao and Barbosa, Jorge G. and Cardoso, Jo\~ao M.P.}, + date = {2018}, + pages = {13--19}, + publisher = {{ACM Press}}, + location = {{Manchester, United Kingdom}}, + doi = {10.1145/3183767.3183770}, + eventtitle = {The 9th {{Workshop}} and 7th {{Workshop}}}, + isbn = {978-1-4503-6444-7}, + langid = {english} +} + +@inproceedings{ref:artigas2000, + title = {Automatic Loop Transformations and Parallelization for {{Java}}}, + booktitle = {Proceedings of the 14th International Conference on {{Supercomputing}} - {{ICS}} '00}, + author = {Artigas, Pedro V. and Gupta, Manish and Midkiff, Samuel P. and Moreira, Jos\'e E.}, + date = {2000}, + pages = {1--10}, + publisher = {{ACM Press}}, + location = {{Santa Fe, New Mexico, United States}}, + doi = {10.1145/335231.335232}, + eventtitle = {The 14th International Conference}, + isbn = {978-1-58113-270-0}, + langid = {english} +} +% == BibLateX quality report for ref:artigas2000: +% ? Unsure about the formatting of the booktitle + +@inproceedings{ref:asai2014, + title = {Compiling a Reflective Language Using {{MetaOCaml}}}, + booktitle = {Proceedings of the 2014 {{International Conference}} on {{Generative Programming}}: {{Concepts}} and {{Experiences}} - {{GPCE}} 2014}, + author = {Asai, Kenichi}, + date = {2014}, + pages = {113--122}, + publisher = {{ACM Press}}, + doi = {10.1145/2658761.2658775}, + eventtitle = {The 2014 {{International Conference}}}, + isbn = {978-1-4503-3161-6}, + langid = {english} +} + +@article{ref:bachelet2013, + title = {Template Metaprogramming Techniques for Concept-Based Specialization}, + author = {Bachelet, Bruno and Mahul, Antoine and Yon, Lo\"ic}, + date = {2013}, + journaltitle = {Scientific Programming}, + volume = {21}, + pages = {43--61}, + issn = {1058-9244, 1875-919X}, + doi = {10.1155/2013/581397}, + langid = {english}, + number = {1-2} +} +% == BibLateX quality report for ref:bachelet2013: +% 'issn': not a valid ISSN + +@thesis{ref:bachelet2016, + title = {Flexibilit\'e et Performance de Codes de Calcul En Optimisation et Simulation}, + author = {Bachelet, Bruno}, + date = {2016}, + institution = {{Universit\'e Blaise Pascal - Clermont-Ferrand II}}, + langid = {english} +} +% == BibLateX quality report for ref:bachelet2016: +% Missing required field 'type' + +@article{ref:bachelet2017, + title = {Designing Expression Templates with Concepts}, + shorttitle = {Designing Expression Templates with Concepts}, + author = {Bachelet, Bruno and Yon, Lo\"ic}, + date = {2017-11}, + journaltitle = {Software: Practice and Experience}, + volume = {47}, + pages = {1521--1537}, + issn = {00380644}, + doi = {10.1002/spe.2483}, + langid = {english}, + number = {11} +} + +@article{ref:barney2009, + title = {{{POSIX}} Threads Programming}, + author = {Barney, Blaise}, + date = {2009}, + journaltitle = {Lawrence Livermore National Laborator}, + pages = {26}, + langid = {english} +} + +@article{ref:batcher1980, + title = {Design of a Massively Parallel Processor}, + author = {Batcher, Kenneth}, + date = {1980-09}, + journaltitle = {IEEE Transactions on Computers}, + volume = {C-29}, + pages = {836--840}, + issn = {0018-9340}, + doi = {10.1109/TC.1980.1675684}, + number = {9} +} + +@article{ref:batlle2002, + title = {A {{New FPGA}}/{{DSP}}-{{Based Parallel Architecture}} for {{Real}}-{{Time Image Processing}}}, + author = {Batlle, J}, + date = {2002-10}, + journaltitle = {Real-Time Imaging}, + volume = {8}, + pages = {345--356}, + issn = {10772014}, + doi = {10.1006/rtim.2001.0273}, + langid = {english}, + number = {5} +} +% == BibLateX quality report for ref:batlle2002: +% ? Title looks like it was stored in title-case in Zotero + +@inproceedings{ref:beard2015, + title = {{{RaftLib}}: A {{C}}++ Template Library for High Performance Stream Parallel Processing}, + shorttitle = {{{RaftLib}}}, + author = {Beard, Jonathan C. and Li, Peng and Chamberlain, Roger D.}, + date = {2015}, + pages = {96--105}, + publisher = {{ACM}}, + location = {{New York, NY, USA}}, + doi = {10.1145/2712386.2712400}, + isbn = {978-1-4503-3404-4}, + langid = {english}, + series = {{{PMAM}} '15} +} +% == BibLateX quality report for ref:beard2015: +% Missing required field 'booktitle' + +@incollection{ref:benoit2005, + title = {Two Fundamental Concepts in Skeletal Parallel Programming}, + booktitle = {Computational {{Science}} \textendash{} {{ICCS}} 2005}, + author = {Benoit, Anne and Cole, Murray}, + date = {2005}, + volume = {3515}, + pages = {764--771}, + publisher = {{Springer Berlin Heidelberg}}, + location = {{Berlin, Heidelberg}}, + doi = {10.1007/11428848_98}, + isbn = {978-3-540-26043-1}, + langid = {english} +} +% == BibLateX quality report for ref:benoit2005: +% Missing required field 'editor' + +@article{ref:bernstein1966, + title = {Analysis of Programs for Parallel Processing}, + author = {Bernstein, A. J.}, + date = {1966-10}, + journaltitle = {IEEE Transactions on Electronic Computers}, + volume = {EC-15}, + pages = {757--763}, + issn = {0367-7508}, + doi = {10.1109/PGEC.1966.264565}, + langid = {english}, + number = {5} +} + +@inproceedings{ref:binkley2007, + title = {Source Code Analysis: A Road Map}, + shorttitle = {Source {{Code Analysis}}}, + booktitle = {Future of {{Software Engineering}} ({{FOSE}} '07)}, + author = {Binkley, David}, + date = {2007-05}, + pages = {104--119}, + publisher = {{IEEE}}, + location = {{Minneapolis, MN, USA}}, + doi = {10.1109/FOSE.2007.27}, + eventtitle = {Future of {{Software Engineering}}}, + isbn = {978-0-7695-2829-8} +} + +@article{ref:blume1995, + title = {Effective Automatic Parallelization with {{Polaris}}}, + author = {Blume, William and Eigenmann, Rudolf and Faigin, Keith and Grout, John and Hoeflinger, Jay and Padua, David and Petersen, Paul and Pottenger, William and Rauchwerger, Lawrence and Tu, Peng and Weatherford, Stephen}, + date = {1995}, + journaltitle = {International Journal of Parallel Programming}, + langid = {english} +} + +@article{ref:blumofe1996, + title = {Cilk: An Efficient Multithreaded Runtime System}, + shorttitle = {Cilk}, + author = {Blumofe, Robert D. and Joerg, Christopher F. and Kuszmaul, Bradley C. and Leiserson, Charles E. and Randall, Keith H. and Zhou, Yuli}, + date = {1996-08}, + journaltitle = {Journal of Parallel and Distributed Computing}, + volume = {37}, + pages = {55--69}, + issn = {07437315}, + doi = {10.1006/jpdc.1996.0107}, + langid = {english}, + number = {1} +} + +@inproceedings{ref:bondhugula2008, + title = {A Practical Automatic Polyhedral Parallelizer and Locality Optimizer}, + booktitle = {Proceedings of the 2008 {{ACM SIGPLAN}} Conference on {{Programming}} Language Design and Implementation - {{PLDI}} '08}, + author = {Bondhugula, Uday and Hartono, Albert and Ramanujam, J. and Sadayappan, P.}, + date = {2008}, + pages = {101}, + publisher = {{ACM Press}}, + location = {{Tucson, AZ, USA}}, + doi = {10.1145/1375581.1375595}, + eventtitle = {The 2008 {{ACM SIGPLAN}} Conference}, + isbn = {978-1-59593-860-2}, + langid = {english} +} +% == BibLateX quality report for ref:bondhugula2008: +% ? Unsure about the formatting of the booktitle + +@online{ref:boostlambda, + title = {Boost.{{Lambda}}}, + author = {J\"arvi, Jaakko and Powell, Gary}, + date = {2003}, + url = {https://www.boost.org/doc/libs/1_73_0/doc/html/lambda.html}, + urldate = {2020-06-10}, + annotation = {boostlambda} +} + +@inproceedings{ref:bringmann1993, + title = {Speculative Execution Exception Recovery Using Write-Back Suppression}, + booktitle = {Proceedings of the 26th {{Annual International Symposium}} on {{Microarchitecture}}}, + author = {Bringmann, Roger A. and Mahlke, Scott A. and Hank, Richard E. and Gyllenhaal, John C. and Hwu, Wen-mei W.}, + date = {1993}, + pages = {214--223}, + publisher = {{IEEE}}, + location = {{Austin, TX, USA}}, + doi = {10.1109/MICRO.1993.282757}, + eventtitle = {Proceedings of 26th {{Annual International Symposium}} on {{Microarchitecture}} ({{Cat}}. {{No}}.{{93TH0602}}-3)}, + isbn = {978-0-8186-5280-6} +} + +@book{ref:butenhof1997, + title = {Programming with {{POSIX}} Threads}, + author = {Butenhof, David R.}, + date = {1997}, + publisher = {{Addison-Wesley}}, + location = {{Reading, Mass}}, + isbn = {978-0-201-63392-4}, + pagetotal = {381}, + series = {Addison-{{Wesley}} Professional Computing Series} +} + +@report{ref:campbell1996, + title = {Towards the Classification of Algorithmic Skeletons}, + author = {Campbell, Duncan K. G.}, + date = {1996}, + institution = {{University of York department of computer science YCS}}, + langid = {english}, + number = {YCS 276} +} +% == BibLateX quality report for ref:campbell1996: +% Missing required field 'type' + +@thesis{ref:caux2012, + title = {Parall\'elisation et optimisation d'un simulateur de morphog\'en\`ese d'organes. Application aux \'el\'ements du rein}, + author = {Caux, Jonathan}, + date = {2012-10}, + institution = {{Universit\'e Blaise Pascal}}, + url = {https://tel.archives-ouvertes.fr/tel-00932303/}, + langid = {french}, + pagetotal = {267} +} +% == BibLateX quality report for ref:caux2012: +% Missing required field 'type' + +@article{ref:chamberlain2007, + title = {Parallel Programmability and the {{Chapel}} Language}, + author = {Chamberlain, B.L. and Callahan, D. and Zima, H.P.}, + date = {2007-08}, + journaltitle = {The International Journal of High Performance Computing Applications}, + volume = {21}, + pages = {291--312}, + issn = {1094-3420, 1741-2846}, + doi = {10.1177/1094342007078442}, + langid = {english}, + number = {3} +} +% == BibLateX quality report for ref:chamberlain2007: +% 'issn': not a valid ISSN + +@article{ref:chan2004, + title = {Run-Time Support for the Automatic Parallelization of {{Java}} Programs}, + author = {Chan, Bryan and Abdelrahman, Tarek S.}, + date = {2004-04}, + journaltitle = {The Journal of Supercomputing}, + volume = {28}, + pages = {91--117}, + issn = {0920-8542}, + doi = {10.1023/B:SUPE.0000014804.20789.21}, + langid = {english}, + number = {1} +} + +@article{ref:ciechanowicz2009, + title = {The {{M\"unster}} Skeleton Library {{Muesli}} - a Comprehensive Overview}, + author = {Ciechanowicz, Philipp and Poldner, Michael and Kuchen, Herbert}, + date = {2009}, + langid = {english} +} +% == BibLateX quality report for ref:ciechanowicz2009: +% Missing required field 'journaltitle' + +@book{ref:cole1989, + title = {Algorithmic Skeletons: Structured Management of Parallel Computation}, + shorttitle = {Algorithmic {{Skeletons}}}, + author = {Cole, Murray}, + date = {1989}, + publisher = {{MIT Press}}, + location = {{Cambridge, MA, USA}}, + isbn = {978-0-262-53086-6} +} + +@article{ref:collard1995, + title = {Automatic Parallelization of While-Loops Using Speculative Execution}, + author = {Collard, Jean-Fran\c{c}ois}, + date = {1995-04}, + journaltitle = {International Journal of Parallel Programming}, + volume = {23}, + pages = {191--219}, + issn = {0885-7458, 1573-7640}, + doi = {10.1007/BF02577789}, + langid = {english}, + number = {2} +} +% == BibLateX quality report for ref:collard1995: +% 'issn': not a valid ISSN + +@inproceedings{ref:cordes2010, + title = {Automatic Parallelization of Embedded Software Using Hierarchical Task Graphs and Integer Linear Programming}, + booktitle = {International {{Conference}} on {{Hardware Software Codesign}}}, + author = {Cordes, Daniel and Marwedel, Peter and Mallik, Arindam}, + date = {2010}, + pages = {267--276}, + langid = {english} +} +% == BibLateX quality report for ref:cordes2010: +% ? Unsure about the formatting of the booktitle + +@article{ref:courtois1971, + title = {Concurrent Control with ``Readers'' and ``Writers''}, + author = {Courtois, P. J. and Heymans, F. and Parnas, D. L.}, + date = {1971-10-01}, + journaltitle = {Communications of the ACM}, + volume = {14}, + pages = {667--668}, + issn = {00010782}, + doi = {10.1145/362759.362813}, + number = {10} +} + +@online{ref:cppref_ref_decl, + title = {Reference Declaration}, + author = {{cppreference}}, + date = {2011}, + url = {https://en.cppreference.com/w/cpp/language/reference#Reference_collapsing}, + urldate = {2019-11-06}, + annotation = {cppref ref decl} +} + +@patent{ref:cray1978, + title = {Computer Vector Register Processing}, + author = {Cray, Seymour R}, + date = {1978}, + pages = {19}, + langid = {english}, + number = {4128880}, + type = {patent} +} +% == BibLateX quality report for ref:cray1978: +% Unexpected field 'pages' + +@book{ref:culler1997, + title = {Parallel Computer Architecture: A Hardware/Software Approach}, + shorttitle = {Parallel Computer Architecture}, + author = {Culler, David E. and Singh, Jaswinder Pal and Gupta, Anoop}, + date = {1997}, + edition = {Nachdr.}, + publisher = {{Kaufmann}}, + location = {{San Francisco, Calif}}, + annotation = {OCLC: 255755318}, + isbn = {978-1-55860-343-1}, + langid = {english}, + pagetotal = {879} +} + +@article{ref:dagum1998, + title = {{{OpenMP}}: An Industry Standard {{API}} for Shared-Memory Programming}, + shorttitle = {{{OpenMP}}}, + author = {Dagum, L. and Menon, R.}, + date = {1998-01}, + journaltitle = {IEEE Computational Science and Engineering}, + volume = {5}, + pages = {46--55}, + issn = {1070-9924}, + doi = {10.1109/99.660313}, + langid = {english}, + number = {1} +} + +@article{ref:dahl1966, + title = {{{SIMULA}}: An {{ALGOL}}-Based Simulation Language}, + shorttitle = {{{SIMULA}}}, + author = {Dahl, Ole-Johan and Nygaard, Kristen}, + date = {1966-09-01}, + journaltitle = {Communications of the ACM}, + volume = {9}, + pages = {671--678}, + issn = {00010782}, + doi = {10.1145/365813.365819}, + langid = {english}, + number = {9} +} + +@article{ref:dantzig1954, + title = {Solution of a Large-Scale Traveling-Salesman Problem}, + author = {Dantzig, George and Fulkerson, Ray and Johnson, Selmer}, + date = {1954}, + journaltitle = {Journal of the operations research society of America}, + edition = {Informs}, + pages = {393--410}, + entrysubtype = {newspaper} +} +% == BibLateX quality report for ref:dantzig1954: +% Unexpected field 'edition' + +@inproceedings{ref:davidson1995, + title = {Improving Instruction-Level Parallelism by Loop Unrolling and Dynamic Memory Disambiguation}, + booktitle = {Proceedings of the 28th {{Annual International Symposium}} on {{Microarchitecture}}}, + author = {Davidson, J.W. and Jinturkar, S.}, + date = {1995-11}, + pages = {125--132}, + publisher = {{IEEE}}, + location = {{Ann Arbor, MI, USA}}, + doi = {10.1109/MICRO.1995.476820}, + eventtitle = {Proceedings of {{MICRO}}'95: 28th {{Annual IEEE}}/{{ACM International Symposium}} on {{Microarchitecture}}}, + isbn = {978-0-8186-7349-8} +} + +@incollection{ref:dietz2010, + title = {{{MIMD Interpretation}} on a {{GPU}}}, + booktitle = {Languages and {{Compilers}} for {{Parallel Computing}}}, + author = {Dietz, Henry G. and Young, B. Dalton}, + editor = {Gao, Guang R. and Pollock, Lori L. and Cavazos, John and Li, Xiaoming}, + date = {2010}, + volume = {5898}, + pages = {65--79}, + publisher = {{Springer Berlin Heidelberg}}, + location = {{Berlin, Heidelberg}}, + doi = {10.1007/978-3-642-13374-9_5}, + editorb = {Hutchison, David and Kanade, Takeo and Kittler, Josef and Kleinberg, Jon M. and Mattern, Friedemann and Mitchell, John C. and Naor, Moni and Nierstrasz, Oscar and Pandu Rangan, C. and Steffen, Bernhard and Sudan, Madhu and Terzopoulos, Demetri and Tygar, Doug and Vardi, Moshe Y. and Weikum, Gerhard}, + editorbtype = {redactor}, + isbn = {978-3-642-13373-2 978-3-642-13374-9}, + series = {Lecture {{Notes}} in {{Computer Science}}} +} +% == BibLateX quality report for ref:dietz2010: +% 'isbn': not a valid ISBN +% ? Title looks like it was stored in title-case in Zotero + +@incollection{ref:dijkstra1968, + title = {Cooperating Sequential Processes}, + booktitle = {The {{Origin}} of {{Concurrent Programming}}}, + author = {Dijkstra, Edsger W.}, + editor = {Hansen, Per Brinch}, + date = {1968}, + pages = {65--138}, + publisher = {{Springer New York}}, + location = {{New York, NY}}, + doi = {10.1007/978-1-4757-3472-0_2}, + isbn = {978-1-4419-2986-0}, + langid = {english} +} + +@online{ref:dimov2002, + title = {The Forwarding Problem: Arguments}, + shorttitle = {N1385}, + author = {Dimov, Peter and Hinnant, Howard E. and Abrahams, David}, + date = {2002-09}, + url = {http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm}, + annotation = {dimov2002}, + langid = {english} +} + +@inproceedings{ref:dittamo2007, + title = {Parallelization of {{C}}\# Programs through Annotations}, + booktitle = {Computational {{Science}} \textendash{} {{ICCS}} 2007}, + author = {Dittamo, Cristian and Cisternino, Antonio and Danelutto, Marco}, + editor = {Shi, Yong and family=Albada, given=Geert Dick, prefix=van, useprefix=true and Dongarra, Jack and Sloot, Peter M. A.}, + date = {2007}, + volume = {4488}, + pages = {585--592}, + publisher = {{Springer Berlin Heidelberg}}, + location = {{Berlin, Heidelberg}}, + doi = {10.1007/978-3-540-72586-2_86}, + editorb = {Hutchison, David and Kanade, Takeo and Kittler, Josef and Kleinberg, Jon M. and Mattern, Friedemann and Mitchell, John C. and Naor, Moni and Nierstrasz, Oscar and Rangan, C. Pandu and Steffen, Bernhard and Sudan, Madhu and Terzopoulos, Demetri and Tygar, Doug and Vardi, Moshe Y. and Weikum, Gerhard}, + editorbtype = {redactor}, + series = {Lecture {{Notes}} in {{Computer Science}}} +} +% == BibLateX quality report for ref:dittamo2007: +% Unexpected field 'editorb' +% Unexpected field 'editorbtype' +% ? Unsure about the formatting of the booktitle + +@inproceedings{ref:drummond2009, + title = {Replicability Is Not Reproducibility: Nor Is It Good Science}, + booktitle = {Proceedings of the {{Evaluation Methods}} for {{Machine Learning Workshop}}}, + author = {Drummond, Chris}, + date = {2009}, + pages = {696--701}, + location = {{Montreal, Quebec, Canada}}, + eventtitle = {26th {{International Conference}} for {{Machine Learning}}}, + langid = {english} +} + +@article{ref:ernstsson2018, + title = {{{SkePU}} 2: Flexible and Type-Safe Skeleton Programming for Heterogeneous Parallel Systems}, + shorttitle = {{{SkePU}} 2}, + author = {Ernstsson, August and Li, Lu and Kessler, Christoph}, + date = {2018-02}, + journaltitle = {International Journal of Parallel Programming}, + volume = {46}, + pages = {62--80}, + issn = {0885-7458, 1573-7640}, + doi = {10.1007/s10766-017-0490-5}, + langid = {english}, + number = {1} +} +% == BibLateX quality report for ref:ernstsson2018: +% 'issn': not a valid ISSN + +@article{ref:esterie2014, + title = {The Numerical Template Toolbox: A Modern {{C}}++ Design for Scientific Computing}, + shorttitle = {The Numerical Template Toolbox}, + author = {Est\'erie, Pierre and Falcou, Joel and Gaunard, Mathias and Laprest\'e, Jean-Thierry and Lacassagne, Lionel}, + date = {2014-12}, + journaltitle = {Journal of Parallel and Distributed Computing}, + volume = {74}, + pages = {3240--3253}, + issn = {07437315}, + doi = {10.1016/j.jpdc.2014.07.002}, + langid = {english}, + number = {12} +} + +@article{ref:falcou2006a, + title = {Quaff: Efficient {{C}}++ Design for Parallel Skeletons}, + shorttitle = {Quaff}, + author = {Falcou, J. and S\'erot, J. and Chateau, T. and Laprest\'e, J. T.}, + date = {2006-09}, + journaltitle = {Parallel Computing}, + shortjournal = {Parallel Computing}, + volume = {32}, + pages = {604--615}, + issn = {0167-8191}, + doi = {10.1016/j.parco.2006.06.001}, + langid = {english}, + number = {7}, + series = {Algorithmic {{Skeletons}}} +} + +@incollection{ref:falcou2008, + title = {Meta-Programming Applied to Automatic {{SMP}} Parallelization of Linear Algebra Code}, + booktitle = {Euro-{{Par}} 2008 \textendash{} {{Parallel Processing}}}, + author = {Falcou, Joel and S\'erot, Jocelyn and Pech, Lucien and Laprest\'e, Jean-Thierry}, + date = {2008}, + volume = {5168}, + pages = {729--738}, + publisher = {{Springer Berlin Heidelberg}}, + location = {{Berlin, Heidelberg}}, + doi = {10.1007/978-3-540-85451-7_78}, + isbn = {978-3-540-85450-0}, + langid = {english}, + series = {Lecture {{Notes}} in {{Computer Science}}} +} +% == BibLateX quality report for ref:falcou2008: +% Missing required field 'editor' + +@article{ref:feo1989, + title = {A Probabilistic Heuristic for a Computationally Difficult Set Covering Problem}, + author = {Feo, Thomas A. and Resende, Mauricio G. C.}, + date = {1989-04}, + journaltitle = {Operations Research Letters}, + volume = {8}, + pages = {67--71}, + issn = {01676377}, + doi = {10.1016/0167-6377(89)90002-3}, + langid = {english}, + number = {2} +} + +@article{ref:ferrante1987, + title = {The Program Dependence Graph and {{Its}} Use in Optimization}, + author = {Ferrante, Jeanne and Ottenstein, Karl J. and Warren, Joe D.}, + date = {1987-07}, + journaltitle = {ACM Transactions on Programming Languages and Systems}, + volume = {9}, + pages = {319--349}, + issn = {0164-0925}, + doi = {10.1145/24039.24041}, + langid = {english}, + number = {3} +} + +@article{ref:flynn1972, + title = {Some Computer Organizations and Their Effectiveness}, + author = {Flynn, Michael J.}, + date = {1972-09}, + journaltitle = {IEEE Transactions on Computers}, + volume = {C-21}, + pages = {948--960}, + issn = {0018-9340}, + doi = {10.1109/TC.1972.5009071}, + number = {9} +} + +@article{ref:fonseca2016, + title = {Automatic Parallelization: Executing Sequential Programs on a Task-Based Parallel Runtime}, + shorttitle = {Automatic {{Parallelization}}}, + author = {Fonseca, Alcides and Cabral, Bruno and Rafael, Jo\~ao and Correia, Ivo}, + date = {2016-12}, + journaltitle = {International Journal of Parallel Programming}, + volume = {44}, + pages = {1337--1358}, + issn = {0885-7458, 1573-7640}, + doi = {10.1007/s10766-016-0426-5}, + langid = {english}, + number = {6} +} +% == BibLateX quality report for ref:fonseca2016: +% 'issn': not a valid ISSN + +@inproceedings{ref:frumkin1998, + title = {A Comparison of Automatic Parallelization Tools/Compilers on the {{SGI Origin}} 2000}, + booktitle = {Proceedings of the 1998 {{ACM}}/{{IEEE Conference}} on {{Supercomputing}}}, + author = {Frumkin, Michael and Hribar, Michelle and Jin, Haoqiang and Waheed, Abdul and Yan, Jerry}, + date = {1998}, + pages = {1--22}, + publisher = {{IEEE Computer Society}}, + location = {{Washington, DC, USA}}, + url = {http://dl.acm.org/citation.cfm?id=509058.509119}, + urldate = {2018-02-15}, + isbn = {978-0-89791-984-5}, + langid = {english}, + series = {{{SC}} '98} +} + +@book{ref:gamma1995, + title = {Design Patterns: Elements of Reusable Software Architecture}, + author = {Gamma, Erich and Helm, Richard and Johnson, Ralph and Vlissides, John}, + date = {1995}, + edition = {Addison-Wesley} +} + +@inproceedings{ref:geuns2011, + title = {Parallelization of While Loops in Nested Loop Programs for Shared-Memory Multiprocessor Systems}, + booktitle = {2011 {{Design}}, {{Automation}} \& {{Test}} in {{Europe}}}, + author = {Geuns, S J and Bekooij, M J G and Bijlsma, T and Corporaal, H}, + date = {2011-03}, + pages = {1--6}, + publisher = {{IEEE}}, + location = {{Grenoble}}, + doi = {10.1109/DATE.2011.5763118}, + eventtitle = {2011 {{Design}}, {{Automation}} \& {{Test}} in {{Europe}}}, + isbn = {978-3-9810801-8-6} +} +% == BibLateX quality report for ref:geuns2011: +% ? Unsure about the formatting of the booktitle + +@article{ref:gingras1990, + title = {Dining Philosophers Revisited}, + author = {Gingras, Armando R.}, + date = {1990-08}, + journaltitle = {ACM SIGCSE Bulletin}, + volume = {22}, + pages = {21}, + issn = {0097-8418}, + doi = {10.1145/101085.101091}, + langid = {english}, + number = {3} +} + +@article{ref:gordon1998, + title = {A Survey of Fast Exponentiation Methods}, + author = {Gordon, Daniel M.}, + date = {1998-04}, + journaltitle = {Journal of Algorithms}, + volume = {27}, + pages = {129--146}, + issn = {01966774}, + doi = {10.1006/jagm.1997.0913}, + langid = {english}, + number = {1} +} + +@incollection{ref:griebl1995, + title = {Generation of Synchronous Code for Automatic Parallelization of While Loops}, + booktitle = {{{EURO}}-{{PAR}} '95 {{Parallel Processing}}}, + author = {Griebl, Martin and Collard, Jean-Fran\c{c}ois}, + editor = {Haridi, Seif and Ali, Khayri and Magnusson, Peter}, + date = {1995}, + volume = {966}, + pages = {313--326}, + publisher = {{Springer Berlin Heidelberg}}, + location = {{Berlin, Heidelberg}}, + doi = {10.1007/BFb0020474}, + editorb = {Goos, Gerhard and Hartmanis, Juris and family=Leeuwen, given=Jan, prefix=van, useprefix=true}, + editorbtype = {redactor}, + isbn = {978-3-540-60247-7}, + langid = {english}, + series = {Lecture {{Notes}} in {{Computer Science}}} +} + +@inproceedings{ref:griebl1998, + title = {Code Generation in the Polytope Model}, + booktitle = {Proceedings. 1998 {{International Conference}} on {{Parallel Architectures}} and {{Compilation Techniques}} ({{Cat}}. {{No}}.{{98EX192}})}, + author = {Griebl, M. and Lengauer, C. and Wetzel, S.}, + date = {1998}, + pages = {106--111}, + publisher = {{IEEE Comput. Soc}}, + location = {{Paris, France}}, + doi = {10.1109/PACT.1998.727179}, + eventtitle = {1998 {{International Conference}} on {{Parallel Architectures}} and {{Compilation Techniques}}}, + isbn = {978-0-8186-8591-0} +} +% == BibLateX quality report for ref:griebl1998: +% ? Unsure about the formatting of the booktitle + +@article{ref:gropp1996, + title = {A High-Performance, Portable Implementation of the {{MPI}} Message Passing Interface Standard}, + author = {Gropp, William and Lusk, Ewing and Doss, Nathan and Skjellum, Anthony}, + date = {1996-09}, + journaltitle = {Parallel Computing}, + shortjournal = {Parallel Computing}, + volume = {22}, + pages = {789--828}, + issn = {0167-8191}, + doi = {10.1016/0167-8191(96)00024-5}, + langid = {english}, + number = {6} +} + +@inproceedings{ref:gustafson1988, + title = {The Scaled-Sized Model: A Revision of {{Amdahl}}'s Law}, + booktitle = {Supercomputing}, + author = {Gustafson, John L}, + date = {1988}, + pages = {130--133}, + location = {{Boston, MA, USA}}, + eventtitle = {International Conference on Supercomputing}, + langid = {english} +} +% == BibLateX quality report for ref:gustafson1988: +% ? Unsure about the formatting of the booktitle + +@article{ref:halstead1985, + title = {{{MULTILISP}}: A Language for Concurrent Symbolic Computation}, + shorttitle = {{{MULTILISP}}}, + author = {Halstead, Robert H.}, + date = {1985-10}, + journaltitle = {ACM Transactions on Programming Languages and Systems (TOPLAS)}, + volume = {7}, + pages = {501--538}, + issn = {0164-0925, 1558-4593}, + doi = {10.1145/4472.4478}, + langid = {english}, + number = {4} +} +% == BibLateX quality report for ref:halstead1985: +% 'issn': not a valid ISSN + +@incollection{ref:hardtlein2005, + title = {Fast {{Expression Templates}}: Object-Oriented {{High Performance Computing}}}, + booktitle = {Lecture {{Notes}} in {{Computer Science}}}, + author = {H\"ardtlein, Jochen and Linke, Alexander and Pflaum, Christoph}, + date = {2005}, + edition = {Springer-Verlag}, + pages = {1055--1063}, + langid = {english} +} +% == BibLateX quality report for ref:hardtlein2005: +% Missing required field 'editor' + +@inproceedings{ref:hill1998, + title = {Practical Barrier Synchronisation}, + booktitle = {Proceedings of the {{Sixth Euromicro Workshop}} on {{Parallel}} and {{Distributed Processing}} - {{PDP}} '98 -}, + author = {Hill, J.M.D. and Skillicorn, D.B.}, + date = {1998}, + pages = {438--444}, + publisher = {{IEEE Comput. Soc}}, + location = {{Madrid, Spain}}, + doi = {10.1109/EMPDP.1998.647231}, + eventtitle = {Sixth {{Euromicro Workshop}} on {{Parallel}} and {{Distributed Processing}} - {{PDP}} '98 -}, + isbn = {978-0-8186-8332-9} +} + +@article{ref:hill2013, + title = {Distribution of Random Streams for Simulation Practitioners: {{CPE HPCS}} 2010 Special Issue Submission}, + shorttitle = {Distribution of Random Streams for Simulation Practitioners}, + author = {Hill, David R. C. and Mazel, Claude and Passerat-Palmbach, Jonathan and Traore, Mamadou K.}, + date = {2013-07}, + journaltitle = {Concurrency and Computation: Practice and Experience}, + volume = {25}, + pages = {1427--1442}, + issn = {15320626}, + doi = {10.1002/cpe.2942}, + langid = {english}, + number = {10} +} + +@article{ref:hill2015, + title = {Parallel Random Numbers, Simulation, and Reproducible Research}, + author = {Hill, David R. C.}, + date = {2015-07}, + journaltitle = {Computing in Science \& Engineering}, + volume = {17}, + pages = {66--71}, + issn = {1521-9615}, + doi = {10.1109/MCSE.2015.79}, + number = {4} +} + +@article{ref:hoare1971, + title = {Proof of a Program: {{FIND}}}, + shorttitle = {Proof of a Program}, + author = {Hoare, C. A. R.}, + date = {1971-01-01}, + journaltitle = {Communications of the ACM}, + volume = {14}, + pages = {39--45}, + issn = {00010782}, + doi = {10.1145/362452.362489}, + number = {1} +} + +@online{ref:hoberock2013, + title = {A Parallel Algorithms Library}, + shorttitle = {N3724}, + author = {Hoberock, Jared and Marathe, Jaydeep and Garland, Michael and Giroux, Olivier and Grover, Vinod and Laksberg, Artur and Sutter, Herb and Robison, Arch}, + date = {2013-08-30}, + url = {http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3724.pdf}, + annotation = {hoberock2013}, + langid = {english} +} + +@inproceedings{ref:horwitz1989, + title = {Dependence Analysis for Pointer Variables}, + booktitle = {Proceedings of the {{ACM SIGPLAN}} 1989 {{Conference}} on {{Programming}} Language Design and Implementation - {{PLDI}} '89}, + author = {Horwitz, S. and Pfeiffer, P. and Reps, T.}, + date = {1989}, + pages = {28--40}, + publisher = {{ACM Press}}, + location = {{Portland, Oregon, United States}}, + doi = {10.1145/73141.74821}, + eventtitle = {The {{ACM SIGPLAN}} 1989 {{Conference}}}, + isbn = {978-0-89791-306-5}, + langid = {english} +} + +@article{ref:howard1973, + title = {Mixed Solutions for the Deadlock Problem}, + author = {Howard, John H.}, + date = {1973-07-01}, + journaltitle = {Communications of the ACM}, + volume = {16}, + pages = {427--430}, + issn = {00010782}, + doi = {10.1145/362280.362290}, + number = {7} +} + +@article{ref:hwu1986, + title = {{{HPSm}}, a High Performance Restricted Data Flow Architecture Having Minimal Functionality}, + author = {Hwu, W. and Patt, Y. N.}, + date = {1986-06-01}, + journaltitle = {ACM SIGARCH Computer Architecture News}, + volume = {14}, + pages = {297--306}, + issn = {01635964}, + doi = {10.1145/17356.17391}, + langid = {english}, + number = {2} +} + +@inproceedings{ref:iglberger2012, + title = {High Performance Smart Expression Template Math Libraries}, + booktitle = {2012 {{International Conference}} on {{High Performance Computing}} \& {{Simulation}} ({{HPCS}})}, + author = {Iglberger, Klaus and Hager, Georg and Treibig, Jan and Rude, Ulrich}, + date = {2012-07}, + pages = {367--373}, + publisher = {{IEEE}}, + location = {{Madrid, Spain}}, + doi = {10.1109/HPCSim.2012.6266939}, + eventtitle = {2012 {{International Conference}} on {{High Performance Computing}} \& {{Simulation}} ({{HPCS}})}, + isbn = {978-1-4673-2362-8}, + langid = {english} +} +% == BibLateX quality report for ref:iglberger2012: +% ? Unsure about the formatting of the booktitle + +@article{ref:ioannidis2005, + title = {Why Most Published Research Findings Are False}, + author = {Ioannidis, John P. A.}, + date = {2005-08-30}, + journaltitle = {PLoS Medicine}, + volume = {2}, + pages = {e124}, + issn = {1549-1676}, + doi = {10.1371/journal.pmed.0020124}, + langid = {english}, + number = {8} +} + +@report{ref:iso2011, + title = {Programming Language - {{C}}++}, + author = {{ISO} and {C++ committee}}, + date = {2011-09}, + pages = {1338}, + institution = {{International Organization for Standardization}}, + url = {http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf}, + langid = {english}, + number = {ISO/IEC 14882:2011}, + type = {Standard} +} + +@report{ref:iso2020, + title = {Programming Language - {{C}}++}, + author = {{ISO} and {C++ committee}}, + date = {2020-01}, + pages = {1815}, + institution = {{International Organization for Standardization}}, + langid = {english}, + number = {ISO/IEC CD 14882}, + type = {Standard} +} + +@inproceedings{ref:jackson1992, + title = {Exploiting Bit-Level Parallelism in {{Boolean}} Matrix Operations for Graph Analysis}, + booktitle = {Proceedings {{IEEE Southeastcon}} '92}, + author = {Jackson, D.J. and Whiteside, D.M. and Wurtz, L.T.}, + date = {1992}, + pages = {838--841}, + publisher = {{IEEE}}, + location = {{Birmingham, AL, USA}}, + doi = {10.1109/SECON.1992.202252}, + eventtitle = {{{IEEE Southeastcon}} '92}, + isbn = {978-0-7803-0494-9} +} + +@article{ref:jarvi2001, + title = {Side Effects and Partial Function Application in {{C}}++}, + author = {J\"arvi, Jaakko and Powell, Gary}, + date = {2001}, + journaltitle = {Proceedings of the Multiparadigm Programming with OO Languages Workshop (MPOOL'01)}, + pages = {17}, + langid = {english} +} + +@article{ref:jarvi2003a, + title = {The Lambda Library: Unnamed Functions in {{C}}++}, + shorttitle = {The {{Lambda Library}}}, + author = {J\"arvi, Jaakko and Powell, Gary and Lumsdaine, Andrew}, + date = {2003-03}, + journaltitle = {Software: Practice and Experience}, + volume = {33}, + pages = {259--291}, + issn = {0038-0644}, + doi = {10.1002/spe.504}, + langid = {english}, + number = {3} +} + +@inproceedings{ref:jo2013, + title = {Automatic Vectorization of Tree Traversals}, + booktitle = {Proceedings of the 22nd {{International Conference}} on {{Parallel Architectures}} and {{Compilation Techniques}}}, + author = {Jo, Youngjoon and Goldfarb, Michael and Kulkarni, Milind}, + date = {2013}, + pages = {12}, + publisher = {{IEEE}}, + location = {{Edinburgh, UK}}, + doi = {10.1109/PACT.2013.6618832}, + eventtitle = {22nd {{International Conference}} on {{Parallel Architectures}} and {{Compilation Techniques}}}, + isbn = {978-1-4799-1021-2}, + langid = {english} +} + +@inproceedings{ref:kale1993, + title = {{{CHARM}}++: A Portable Concurrent Object Oriented System Based on {{C}}++}, + shorttitle = {{{CHARM}}++}, + booktitle = {Proceedings of the {{Conference}} on {{Object Oriented Programming Systems}}, {{Languages}} and {{Applications}}}, + author = {Kale, Laxmikant V. and Krishnan, Sanjeev}, + date = {1993}, + pages = {91--108}, + publisher = {{ACM Press}}, + doi = {10.1145/165854.165874}, + isbn = {978-0-89791-587-8}, + langid = {english} +} + +@article{ref:keller1975, + title = {Look-Ahead Processors}, + author = {Keller, Robert M.}, + date = {1975-12-01}, + journaltitle = {ACM Computing Surveys}, + volume = {7}, + pages = {177--195}, + issn = {03600300}, + doi = {10.1145/356654.356657}, + number = {4} +} + +@article{ref:kennedy1994, + title = {Compiler Technology for Machine-Indepenent Parallel Programming}, + author = {Kennedy, Ken}, + date = {1994-02}, + journaltitle = {International Journal of Parallel Programming}, + volume = {22}, + pages = {79--98}, + issn = {0885-7458, 1573-7640}, + doi = {10.1007/BF02577793}, + langid = {english}, + number = {1} +} +% == BibLateX quality report for ref:kennedy1994: +% 'issn': not a valid ISSN + +@book{ref:kernighan1988, + title = {The {{C}} Programming Language}, + author = {Kernighan, Brian W and Ritchie, Dennis M}, + date = {1988}, + publisher = {{Prentice Hall}}, + location = {{Upper Saddle River, NJ}}, + annotation = {OCLC: 1047831315}, + isbn = {978-0-13-110362-7}, + langid = {english} +} + +@article{ref:kirby2003, + title = {A New Look at Expression Templates for Maxtrix Computation}, + author = {Kirby, R.C.}, + date = {2003-05}, + journaltitle = {Computing in Science \& Engineering}, + volume = {5}, + pages = {66--70}, + issn = {1521-9615}, + doi = {10.1109/MCISE.2003.1196309}, + langid = {english}, + number = {3} +} + +@article{ref:kish2002, + title = {End of {{Moore}}'s Law: Thermal (Noise) Death of Integration in Micro and Nano Electronics}, + shorttitle = {End of {{Moore}}'s Law}, + author = {Kish, Laszlo B}, + date = {2002-12}, + journaltitle = {Physics Letters A}, + volume = {305}, + pages = {144--149}, + issn = {03759601}, + doi = {10.1016/S0375-9601(02)01365-8}, + langid = {english}, + number = {3-4} +} + +@inproceedings{ref:klint2009, + title = {{{RASCAL}}: A Domain Specific Language for Source Code Analysis and Manipulation}, + shorttitle = {{{RASCAL}}}, + booktitle = {2009 {{Ninth IEEE International Working Conference}} on {{Source Code Analysis}} and {{Manipulation}}}, + author = {Klint, Paul and family=Storm, given=Tijs, prefix=van der, useprefix=false and Vinju, Jurgen}, + date = {2009}, + pages = {168--177}, + publisher = {{IEEE}}, + location = {{Edmonton, Alberta, Canada}}, + doi = {10.1109/SCAM.2009.28}, + eventtitle = {2009 {{Ninth IEEE International Working Conference}} on {{Source Code Analysis}} and {{Manipulation}}}, + isbn = {978-0-7695-3793-1} +} +% == BibLateX quality report for ref:klint2009: +% ? Unsure about the formatting of the booktitle + +@article{ref:kremer1988, + title = {Advanced Tools and Techniques for Automatic Parallelization}, + author = {Kremer, Ulrich and Bast, Heinz-J and Gerndt, Michael and Zima, Hans P.}, + date = {1988-09}, + journaltitle = {Parallel Computing}, + shortjournal = {Parallel Computing}, + volume = {7}, + pages = {387--393}, + issn = {0167-8191}, + doi = {10.1016/0167-8191(88)90057-9}, + langid = {english}, + number = {3} +} + +@inproceedings{ref:kuchen2002, + title = {Higher-Order Functions and Partial Applications for a {{C}}++ Skeleton Library}, + booktitle = {Proceedings of the 2002 Joint {{ACM}}-{{ISCOPE}} Conference on {{Java Grande}} - {{JGI}} '02}, + author = {Kuchen, Herbert and Striegnitz, J\"org}, + date = {2002}, + pages = {122--130}, + publisher = {{ACM Press}}, + location = {{Seattle, Washington, USA}}, + doi = {10.1145/583810.583824}, + eventtitle = {The 2002 Joint {{ACM}}-{{ISCOPE}} Conference}, + isbn = {978-1-58113-599-2}, + langid = {english} +} +% == BibLateX quality report for ref:kuchen2002: +% ? Unsure about the formatting of the booktitle + +@incollection{ref:kuchen2002a, + title = {A Skeleton Library}, + booktitle = {Euro-{{Par}} 2002 {{Parallel Processing}}}, + author = {Kuchen, Herbert}, + date = {2002}, + volume = {2400}, + pages = {620--629}, + publisher = {{Springer Berlin Heidelberg}}, + location = {{Berlin, Heidelberg}}, + doi = {10.1007/3-540-45706-2_86}, + isbn = {978-3-540-44049-9} +} +% == BibLateX quality report for ref:kuchen2002a: +% Missing required field 'editor' + +@inproceedings{ref:landi1991, + title = {Pointer-Induced Aliasing: A Problem Taxonomy}, + shorttitle = {Pointer-Induced Aliasing}, + booktitle = {Proceedings of the 18th {{ACM SIGPLAN}}-{{SIGACT}} Symposium on {{Principles}} of Programming Languages - {{POPL}} '91}, + author = {Landi, William and Ryder, Barbara G.}, + date = {1991}, + pages = {93--103}, + publisher = {{ACM Press}}, + location = {{Orlando, Florida, United States}}, + doi = {10.1145/99583.99599}, + eventtitle = {The 18th {{ACM SIGPLAN}}-{{SIGACT}} Symposium}, + isbn = {978-0-89791-419-2}, + langid = {english} +} +% == BibLateX quality report for ref:landi1991: +% ? Unsure about the formatting of the booktitle + +@inproceedings{ref:lazarescu2012, + title = {Dynamic Trace-Based Data Dependency Analysis for Parallelization of {{C}} Programs}, + booktitle = {2012 {{IEEE}} 12th {{International Working Conference}} on {{Source Code Analysis}} and {{Manipulation}}}, + author = {Lazarescu, Mihai T. and Lavagno, Luciano}, + date = {2012-09}, + pages = {126--131}, + publisher = {{IEEE}}, + location = {{Riva del Garda, Italy}}, + doi = {10.1109/SCAM.2012.15}, + eventtitle = {2012 12th {{IEEE Working Conference}} on {{Source Code Analysis}} and {{Manipulation}} ({{SCAM}})}, + isbn = {978-0-7695-4783-1} +} +% == BibLateX quality report for ref:lazarescu2012: +% ? Unsure about the formatting of the booktitle + +@article{ref:legaux2013, + title = {{{OSL}}: An Algorithmic Skeleton Library with Exceptions}, + shorttitle = {{{OSL}}}, + author = {Legaux, Joeffrey and Loulergue, Fr\'ed\'eric and Jubertie, Sylvain}, + date = {2013}, + journaltitle = {Procedia Computer Science}, + volume = {18}, + pages = {260--269}, + issn = {18770509}, + doi = {10.1016/j.procs.2013.05.189}, + langid = {english} +} + +@inproceedings{ref:lengauer1995, + title = {On the Parallelization of Loop Nests Containing While Loops}, + booktitle = {Proceedings of the {{First Aizu International Symposium}} on {{Parallel Algorithms}}/{{Architecture Synthesis}}}, + author = {Lengauer, C. and Griebl, M.}, + date = {1995}, + pages = {10--18}, + publisher = {{IEEE Comput. Soc. Press}}, + location = {{Fukushima, Japan}}, + doi = {10.1109/AISPAS.1995.401360}, + eventtitle = {The {{First Aizu International Symposium}} on {{Parallel Algorithms}}/{{Architecture Synthesis}}}, + isbn = {978-0-8186-7038-1} +} + +@inproceedings{ref:leyton2010, + title = {Skandium: Multi-Core Programming with Algorithmic Skeletons}, + shorttitle = {Skandium}, + booktitle = {2010 18th {{Euromicro Conference}} on {{Parallel}}, {{Distributed}} and {{Network}}-Based {{Processing}}}, + author = {Leyton, Mario and Piquer, Jos\'e M.}, + date = {2010-02}, + pages = {289--296}, + publisher = {{IEEE}}, + location = {{Pisa}}, + doi = {10.1109/PDP.2010.26}, + annotation = {Print ISBN: 978-1-4244-5672-7}, + eventtitle = {18th {{Euromicro International Conference}} on {{Parallel}}, {{Distributed}} and {{Network}}-{{Based Processing}} ({{PDP}} 2010)}, + isbn = {978-1-4244-5673-4} +} +% == BibLateX quality report for ref:leyton2010: +% ? Unsure about the formatting of the booktitle + +@inproceedings{ref:li2013, + title = {{{NUMA}}-Aware Shared-Memory Collective Communication for {{MPI}}}, + booktitle = {Proceedings of the 22nd {{International Symposium}} on {{High}}-{{Performance Parallel}} and {{Distributed Computing}}}, + author = {Li, Shigang and Hoefler, Torsten and Snir, Marc}, + date = {2013}, + pages = {85--96}, + publisher = {{Association for Computing Machinery}}, + location = {{New York, New York, USA}}, + doi = {10.1145/2462902.2462903}, + eventtitle = {{{HPDC}} '13}, + isbn = {978-1-4503-1910-2}, + langid = {english} +} + +@article{ref:lilis2019, + title = {A Survey of Metaprogramming Languages}, + author = {Lilis, Yannis and Savidis, Anthony}, + date = {2019-10-16}, + journaltitle = {ACM Computing Surveys}, + volume = {52}, + pages = {1--39}, + issn = {03600300}, + doi = {10.1145/3354584}, + langid = {english}, + number = {6} +} + +@article{ref:liskov1988, + title = {Promises: Linguistic Support for Efficient Asynchronous Procedure Calls in Distributed Systems}, + shorttitle = {Promises}, + author = {Liskov, B. and Shrira, L.}, + date = {1988-07-01}, + journaltitle = {ACM SIGPLAN Notices}, + volume = {23}, + pages = {260--267}, + issn = {03621340}, + doi = {10.1145/960116.54016}, + langid = {english}, + number = {7} +} + +@incollection{ref:lopez2016, + title = {Using {{C}}++ {{AMP}} to Accelerate {{HPC}} Applications on Multiple Platforms}, + booktitle = {High {{Performance Computing}}}, + author = {Lopez, M. Graham and Bergstrom, Christopher and Li, Ying Wai and Elwasif, Wael and Hernandez, Oscar}, + editor = {Taufer, Michela and Mohr, Bernd and Kunkel, Julian M.}, + date = {2016}, + volume = {9945}, + pages = {563--576}, + publisher = {{Springer International Publishing}}, + location = {{Cham}}, + doi = {10.1007/978-3-319-46079-6_38}, + isbn = {978-3-319-46078-9}, + series = {Lecture {{Notes}} in {{Computer Science}}} +} + +@incollection{ref:lourenco2003, + title = {Iterated {{Local Search}}}, + booktitle = {Handbook of {{Metaheuristics}}}, + author = {Louren\c{c}o, Helena R. and Martin, Olivier C. and St\"utzle, Thomas}, + editor = {Glover, Fred and Kochenberger, Gary A.}, + date = {2003}, + pages = {320--353}, + publisher = {{Springer US}}, + location = {{Boston, MA}}, + doi = {10.1007/0-306-48056-5_11}, + isbn = {978-0-306-48056-0}, + langid = {english}, + series = {International {{Series}} in {{Operations Research}} \& {{Management Science}}} +} +% == BibLateX quality report for ref:lourenco2003: +% ? Title looks like it was stored in title-case in Zotero + +@article{ref:loveman1993, + title = {High Performance {{Fortran}}}, + author = {Loveman, D. B.}, + date = {1993-02}, + journaltitle = {IEEE Parallel \& Distributed Technology: Systems \& Applications}, + volume = {1}, + pages = {25--42}, + issn = {1063-6552}, + doi = {10.1109/88.219857}, + langid = {english}, + number = {1} +} + +@inproceedings{ref:luebke2008, + title = {{{CUDA}}: Scalable Parallel Programming for High-Performance Scientific Computing}, + shorttitle = {{{CUDA}}}, + booktitle = {2008 5th {{IEEE International Symposium}} on {{Biomedical Imaging}}: {{From Nano}} to {{Macro}}}, + author = {Luebke, David}, + date = {2008-05}, + pages = {836--838}, + publisher = {{IEEE}}, + location = {{Paris, France}}, + doi = {10.1109/ISBI.2008.4541126}, + eventtitle = {2008 5th {{IEEE International Symposium}} on {{Biomedical Imaging}} ({{ISBI}} 2008)}, + isbn = {978-1-4244-2002-5} +} + +@article{ref:mack2011, + title = {Fifty Years of {{Moore}}'s Law}, + author = {Mack, Chris A.}, + date = {2011-05}, + journaltitle = {IEEE Transactions on Semiconductor Manufacturing}, + volume = {24}, + pages = {202--207}, + issn = {0894-6507}, + doi = {10.1109/TSM.2010.2096437}, + number = {2} +} + +@online{ref:maddock2002, + title = {A Proposal to Add Type Traits to the Standard Library}, + shorttitle = {N1345}, + author = {Maddock, John}, + date = {2002-03-07}, + url = {http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1345.html}, + urldate = {2020-09-01}, + annotation = {maddock2002}, + langid = {english} +} + +@incollection{ref:marques2013, + title = {Algorithmic Skeleton Framework for the Orchestration of {{GPU}} Computations}, + booktitle = {Euro-{{Par}} 2013 {{Parallel Processing}}}, + author = {Marques, Ricardo and Paulino, Herv\'e and Alexandre, Fernando and Medeiros, Pedro D.}, + date = {2013}, + volume = {8097}, + pages = {874--885}, + publisher = {{Springer Berlin Heidelberg}}, + location = {{Berlin, Heidelberg}}, + doi = {10.1007/978-3-642-40047-6_86}, + isbn = {978-3-642-40046-9}, + langid = {english} +} +% == BibLateX quality report for ref:marques2013: +% Missing required field 'editor' + +@thesis{ref:masliah2016, + title = {Automatic code generation methods applied to numerical linear algebra in high performance computing}, + author = {Masliah, Ian}, + date = {2016}, + institution = {{Universit\'e Paris-Saclay}}, + url = {https://tel.archives-ouvertes.fr/tel-01395496/document}, + langid = {french} +} +% == BibLateX quality report for ref:masliah2016: +% Missing required field 'type' + +@inproceedings{ref:mathews2016, + title = {Automatic Code Parallelization with {{OpenMP}} Task Constructs}, + booktitle = {2016 {{International Conference}} on {{Information Science}} ({{ICIS}})}, + author = {Mathews, Manju and Abraham, Jisha P}, + date = {2016-08}, + pages = {233--238}, + publisher = {{IEEE}}, + location = {{Kochi, India}}, + doi = {10.1109/INFOSCI.2016.7845333}, + eventtitle = {2016 {{International Conference}} in {{Information Science}} ({{ICIS}})}, + isbn = {978-1-5090-1987-8} +} +% == BibLateX quality report for ref:mathews2016: +% ? Unsure about the formatting of the booktitle + +@inproceedings{ref:matsuzaki2006a, + title = {Towards Automatic Parallelization of Tree Reductions in Dynamic Programming}, + booktitle = {Proceedings of the Eighteenth Annual {{ACM}} Symposium on {{Parallelism}} in Algorithms and Architectures - {{SPAA}} '06}, + author = {Matsuzaki, Kiminori and Hu, Zhenjiang and Takeichi, Masato}, + date = {2006}, + pages = {39}, + publisher = {{ACM Press}}, + location = {{Cambridge, Massachusetts, USA}}, + doi = {10.1145/1148109.1148116}, + eventtitle = {The Eighteenth Annual {{ACM}} Symposium}, + isbn = {978-1-59593-452-9}, + langid = {english} +} +% == BibLateX quality report for ref:matsuzaki2006a: +% ? Unsure about the formatting of the booktitle + +@book{ref:mattson2005, + title = {Patterns for Parallel Programming}, + author = {Mattson, Timothy G. and Sanders, Beverly A. and Massingill, Berna}, + date = {2005}, + publisher = {{Addison-Wesley}}, + location = {{Boston}}, + isbn = {978-0-321-22811-6}, + pagetotal = {355} +} + +@book{ref:mccool2012, + title = {Structured Parallel Programming: Patterns for Efficient Computation}, + shorttitle = {Structured {{Parallel Programming}}}, + author = {McCool, Michael and Reinders, James and Robison, Arch}, + date = {2012}, + publisher = {{Elsevier}}, + eprint = {2hYqeoO8t8IC}, + eprinttype = {googlebooks}, + isbn = {978-0-12-391443-9}, + langid = {english}, + pagetotal = {433} +} + +@online{ref:meneide2020, + title = {{{std::embed}} and {{\#depend}}}, + shorttitle = {p1040r6}, + author = {Meneide, JeanHeyd}, + date = {2020-02-29}, + url = {http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1040r6.html}, + annotation = {meneide2020}, + langid = {english} +} + +@inproceedings{ref:munshi2009, + title = {The {{OpenCL}} Specification}, + booktitle = {2009 {{IEEE Hot Chips}} 21 {{Symposium}} ({{HCS}})}, + author = {Munshi, Aaftab}, + date = {2009-08}, + pages = {1--314}, + publisher = {{IEEE}}, + location = {{Stanford, CA}}, + doi = {10.1109/HOTCHIPS.2009.7478342}, + eventtitle = {2009 {{IEEE Hot Chips}} 21 {{Symposium}} ({{HCS}})}, + isbn = {978-1-4673-8873-3} +} +% == BibLateX quality report for ref:munshi2009: +% ? Unsure about the formatting of the booktitle + +@incollection{ref:musser1989, + title = {Generic Programming}, + booktitle = {Symbolic and {{Algebraic Computation}}}, + author = {Musser, David R. and Stepanov, Alexander A.}, + editor = {Gianni, P.}, + date = {1989}, + volume = {358}, + pages = {13--25}, + publisher = {{Springer Berlin Heidelberg}}, + location = {{Berlin, Heidelberg}}, + doi = {10.1007/3-540-51084-2_2}, + editorb = {Goos, G. and Hartmanis, J. and Barstow, D. and Brauer, W. and Brinch Hansen, P. and Gries, D. and Luckham, D. and Moler, C. and Pnueli, A. and Seegm\"uller, G. and Stoer, J. and Wirth, N.}, + editorbtype = {redactor}, + isbn = {978-3-540-51084-0}, + langid = {english} +} + +@article{ref:namsungkim2003, + title = {Leakage Current: {{Moore}}'s Law Meets Static Power}, + shorttitle = {Leakage Current}, + author = {{Nam Sung Kim} and Austin, T. and Blaauw, D. and Mudge, T. and Flautner, K. and {Jie S. Hu} and Irwin, M.J. and Kandemir, M. and Narayanan, V.}, + date = {2003-12}, + journaltitle = {Computer}, + shortjournal = {Computer}, + volume = {36}, + pages = {68--75}, + issn = {0018-9162}, + doi = {10.1109/MC.2003.1250885}, + langid = {english}, + number = {12} +} + +@inproceedings{ref:neth2019, + title = {Automatic Parallelization of Irregular X86-64 Loops}, + booktitle = {2019 {{IEEE}}/{{ACM International Symposium}} on {{Code Generation}} and {{Optimization}} ({{CGO}})}, + author = {Neth, Brandon and Strout, Michelle Mills}, + date = {2019-02}, + pages = {266--266}, + publisher = {{IEEE}}, + location = {{Washington, DC, USA}}, + doi = {10.1109/CGO.2019.8661167}, + eventtitle = {2019 {{IEEE}}/{{ACM International Symposium}} on {{Code Generation}} and {{Optimization}} ({{CGO}})}, + isbn = {978-1-72811-436-1} +} +% == BibLateX quality report for ref:neth2019: +% ? Unsure about the formatting of the booktitle + +@article{ref:netzer1992, + title = {What Are Race Conditions?: {{Some}} Issues and Formalizations}, + shorttitle = {What {{Are Race Conditions}}?}, + author = {Netzer, Robert H. B. and Miller, Barton P.}, + date = {1992-03}, + journaltitle = {ACM Letters on Programming Languages and Systems}, + volume = {1}, + pages = {74--88}, + issn = {1057-4514}, + doi = {10.1145/130616.130623}, + langid = {english}, + number = {1} +} + +@book{ref:nichols1996, + title = {{{PThreads Programming}}: {{A POSIX Standard}} for {{Better Multiprocessing}}}, + shorttitle = {{{PThreads Programming}}}, + author = {Nichols, Bradford and Buttlar, Dick and Farrell, Jacqueline}, + date = {1996}, + publisher = {{O'Reilly Media, Inc.}}, + eprint = {oMtCFSnvwmoC}, + eprinttype = {googlebooks}, + isbn = {978-1-56592-115-3}, + langid = {english}, + pagetotal = {289} +} +% == BibLateX quality report for ref:nichols1996: +% ? Title looks like it was stored in title-case in Zotero + +@incollection{ref:nicolau1992, + title = {Register Allocation, Renaming and Their Impact on Fine-Grain Parallelism}, + booktitle = {Languages and {{Compilers}} for {{Parallel Computing}}}, + author = {Nicolau, A. and Potasman, R. and Wang, H.}, + editor = {Banerjee, Utpal and Gelernter, David and Nicolau, Alex and Padua, David}, + date = {1992}, + volume = {589}, + pages = {218--235}, + publisher = {{Springer-Verlag}}, + location = {{Berlin/Heidelberg}}, + doi = {10.1007/BFb0038667}, + isbn = {978-3-540-55422-6}, + langid = {english}, + series = {Lecture {{Notes}} in {{Computer Science}}} +} + +@article{ref:owens2008, + title = {{{GPU}} Computing}, + author = {Owens, J.D. and Houston, M. and Luebke, D. and Green, S. and Stone, J.E. and Phillips, J.C.}, + date = {2008-05}, + journaltitle = {Proceedings of the IEEE}, + volume = {96}, + pages = {879--899}, + issn = {0018-9219}, + doi = {10.1109/JPROC.2008.917757}, + number = {5} +} + +@thesis{ref:passerat-palmbach2013, + title = {Contributions to Parallel Stochastic Simulation: {{Application}} of Good Software Engineering Practices to the Distribution of Pseudorandom Streams in Hybrid {{Monte}}-{{Carlo}} Simulations}, + shorttitle = {Contributions to Parallel Stochastic Simulation}, + author = {Passerat-Palmbach, Jonathan}, + date = {2013-10-11}, + institution = {{Universit\'e Blaise Pascal - Clermont-Ferrand II}}, + url = {https://tel.archives-ouvertes.fr/tel-00858735/document}, + urldate = {2018-08-22}, + langid = {english}, + type = {phdthesis} +} + +@inproceedings{ref:patterson1995, + title = {Accurate Static Branch Prediction by Value Range Propagation}, + booktitle = {Proceedings of the {{ACM SIGPLAN}} 1995 Conference on {{Programming}} Language Design and Implementation - {{PLDI}} '95}, + author = {Patterson, Jason R. C.}, + date = {1995}, + pages = {67--78}, + publisher = {{ACM Press}}, + location = {{La Jolla, California, United States}}, + doi = {10.1145/207110.207117}, + eventtitle = {The {{ACM SIGPLAN}} 1995 Conference}, + isbn = {978-0-89791-697-4}, + langid = {english} +} +% == BibLateX quality report for ref:patterson1995: +% ? Unsure about the formatting of the booktitle + +@article{ref:peleg1997, + title = {Intel {{MMX}} for Multimedia {{PCs}}}, + author = {Peleg, Alex and Wilkie, Sam and Weiser, Uri}, + date = {1997-01-01}, + journaltitle = {Communications of the ACM}, + volume = {40}, + pages = {24--38}, + issn = {00010782}, + doi = {10.1145/242857.242865}, + langid = {english}, + number = {1} +} + +@article{ref:perach2018, + title = {{{SiMT}}-{{DSP}}: {{A Massively Multithreaded DSP Architecture}}}, + shorttitle = {{{SiMT}}-{{DSP}}}, + author = {Perach, Ben and Weiss, Shlomo}, + date = {2018-08}, + journaltitle = {IEEE Transactions on Very Large Scale Integration (VLSI) Systems}, + volume = {26}, + pages = {1413--1426}, + issn = {1063-8210, 1557-9999}, + doi = {10.1109/TVLSI.2018.2817564}, + number = {8} +} +% == BibLateX quality report for ref:perach2018: +% 'issn': not a valid ISSN +% ? Title looks like it was stored in title-case in Zotero + +@inproceedings{ref:pereda2018, + title = {Static Loop Parallelization Decision Using Template Metaprogramming}, + booktitle = {2018 {{International Conference}} on {{High Performance Computing}} \& {{Simulation}} ({{HPCS}})}, + author = {Pereda, Alexis and Hill, David R. C. and Mazel, Claude and Bachelet, Bruno}, + date = {2018-07}, + pages = {1015--1021}, + publisher = {{IEEE}}, + location = {{Orleans}}, + doi = {10.1109/HPCS.2018.00159}, + isbn = {978-1-5386-7878-7} +} +% == BibLateX quality report for ref:pereda2018: +% ? Unsure about the formatting of the booktitle + +@inproceedings{ref:pereda2020, + title = {Processing Algorithmic Skeletons at Compile-Time}, + booktitle = {21\`eme Congr\`es de La Soci\'et\'e Fran\c{c}aise de {{Recherche Op\'erationnelle}} et d'{{Aide}} \`a La {{D\'ecision}} ({{ROADEF}})}, + author = {Pereda, Alexis and Hill, David R. C. and Mazel, Claude and Yon, Lo\"ic and Bachelet, Bruno}, + date = {2020-02}, + location = {{Montpellier, France}}, + url = {https://hal.archives-ouvertes.fr/hal-02573660} +} +% == BibLateX quality report for ref:pereda2020: +% ? Unsure about the formatting of the booktitle + +@inproceedings{ref:philippe2019, + title = {{{PySke}}: Algorithmic Skeletons for {{Python}}}, + shorttitle = {{{PySke}}}, + booktitle = {The 2019 {{International Conference}} on {{High Performance Computing}} \& {{Simulation}} ({{HPCS}})}, + author = {Philippe, Jolan and Loulergue, Fr\'ed\'eric}, + date = {2019-07}, + pages = {40--47}, + location = {{Dublin, Ireland}} +} +% == BibLateX quality report for ref:philippe2019: +% ? Unsure about the formatting of the booktitle + +@incollection{ref:pinto2012, + title = {{{GPU}} Metaprogramming: A Case Study in Biologically-Inspired Machine Vision}, + booktitle = {{{GPU Computing Gems Jade Edition}}}, + author = {Pinto, Nicolas and Cox, David D.}, + date = {2012}, + pages = {457--471}, + publisher = {{Elsevier}}, + doi = {10.1016/B978-0-12-385963-1.00033-2}, + isbn = {978-0-12-385963-1}, + langid = {english} +} +% == BibLateX quality report for ref:pinto2012: +% Missing required field 'editor' + +@book{ref:popper2005, + title = {The Logic of Scientific Discovery}, + author = {Popper, Karl}, + date = {2005-11-04}, + publisher = {{Routledge}}, + eprint = {LWSBAgAAQBAJ}, + eprinttype = {googlebooks}, + isbn = {978-1-134-47002-0}, + langid = {english}, + pagetotal = {545} +} + +@incollection{ref:prins2009a, + title = {A {{GRASP}} \texttimes{} {{Evolutionary Local Search Hybrid}} for the {{Vehicle Routing Problem}}}, + booktitle = {Bio-Inspired {{Algorithms}} for the {{Vehicle Routing Problem}}}, + author = {Prins, Christian}, + date = {2009}, + pages = {35--53}, + publisher = {{Springer}}, + location = {{Berlin, Heidelberg}}, + doi = {10.1007/978-3-540-85152-3_2}, + isbn = {978-3-540-85152-3}, + langid = {english}, + series = {Studies in {{Computational Intelligence}}} +} +% == BibLateX quality report for ref:prins2009a: +% Missing required field 'editor' +% ? Title looks like it was stored in title-case in Zotero + +@article{ref:protic1996, + title = {Distributed Shared Memory: Concepts and Systems}, + shorttitle = {Distributed Shared Memory}, + author = {Protic, J. and Tomasevic, M. and Milutinovic, V.}, + date = {1996}, + journaltitle = {IEEE Parallel \& Distributed Technology: Systems \& Applications}, + volume = {4}, + pages = {63--71}, + issn = {10636552}, + doi = {10.1109/88.494605}, + number = {2} +} + +@book{ref:quinn2003, + title = {Parallel Programming in {{C}} with {{MPI}} and {{OpenMP}}}, + author = {Quinn, Michael Jay}, + date = {2003}, + volume = {526}, + publisher = {{McGraw-Hill}}, + annotation = {OCLC: 553844668}, + isbn = {978-0-07-123265-4}, + langid = {english}, + pagetotal = {529} +} + +@article{ref:raman2000, + title = {Implementing Streaming {{SIMD}} Extensions on the {{Pentium III}} Processor}, + author = {Raman, S.K. and Pentkovski, V. and Keshava, J.}, + date = {2000-07}, + journaltitle = {IEEE Micro}, + volume = {20}, + pages = {47--57}, + issn = {02721732}, + doi = {10.1109/40.865866}, + number = {4} +} + +@report{ref:ramon-cortes2018, + title = {{{AutoParallel}}: {{A Python}} Module for Automatic Parallelization and Distributed Execution of Affine Loop Nests}, + author = {Ramon-Cortes, Cristian and Amela, Ramon and Ejarque, Jorge and Clauss, Philippe and Badia, Rosa}, + date = {2018}, + pages = {13}, + langid = {english} +} +% == BibLateX quality report for ref:ramon-cortes2018: +% Missing required field 'type' +% Missing required field 'institution' + +@online{ref:ranns2018, + title = {Down with typename!}, + shorttitle = {p0634r2}, + author = {Ranns, Nina and Vandevoorde, Daveed}, + date = {2018-10-02}, + url = {http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0634r2.html}, + annotation = {ranns2018}, + langid = {english} +} + +@online{ref:revzin2020, + title = {If Consteval}, + shorttitle = {P1938r2}, + author = {Revzin, Barry and Smith, Richard and Sutton, Andrew and Vandevoorde, Daveed}, + date = {2020-10-09}, + url = {http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1938r2.html}, + annotation = {revzin2020}, + langid = {english} +} + +@inproceedings{ref:rieger2019, + title = {Musket: A Domain-Specific Language for High-Level Parallel Programming with Algorithmic Skeletons}, + shorttitle = {Musket}, + booktitle = {Proceedings of the 34th {{ACM}}/{{SIGAPP Symposium}} on {{Applied Computing}}}, + author = {Rieger, Christoph and Wrede, Fabian and Kuchen, Herbert}, + date = {2019-04-08}, + pages = {1534--1543}, + publisher = {{ACM}}, + location = {{Limassol Cyprus}}, + doi = {10.1145/3297280.3297434}, + eventtitle = {{{SAC}} '19: {{The}} 34th {{ACM}}/{{SIGAPP Symposium}} on {{Applied Computing}}}, + isbn = {978-1-4503-5933-7}, + langid = {english} +} + +@report{ref:robinson1949, + title = {On the {{Hamiltonian}} Game (a Traveling Salesman Problem)}, + author = {Robinson, Julia}, + date = {1949}, + institution = {{Rand project air force arlington va.}} +} +% == BibLateX quality report for ref:robinson1949: +% Missing required field 'type' + +@article{ref:roscoe1988, + title = {The Laws of {{OCCAM}} Programming}, + author = {Roscoe, Andrew William and Hoare, Charles Antony Richard}, + date = {1988-09-01}, + journaltitle = {Theoretical Computer Science}, + volume = {60}, + pages = {177--229}, + publisher = {{Elsevier}}, + issn = {0304-3975}, + doi = {10.1016/0304-3975(88)90049-7}, + langid = {english}, + number = {2} +} +% == BibLateX quality report for ref:roscoe1988: +% Unexpected field 'publisher' + +@report{ref:rudd1993, + title = {{{X3H5}} Parallel Extensions for Programming Language {{C}}}, + author = {Rudd, Walter G.}, + date = {1993}, + institution = {{Oregon State University}}, + location = {{Corvallis, OR, USA}}, + langid = {english} +} +% == BibLateX quality report for ref:rudd1993: +% Missing required field 'type' + +@inproceedings{ref:saidani2009, + title = {Algorithmic Skeletons within an {{Embedded Domain Specific Language}} for the {{CELL Processor}}}, + author = {Saidani, Tarik and Falcou, Joel and Tadonki, Claude and Lacassagne, Lionel and Etiemble, Daniel}, + date = {2009-09}, + pages = {67--76}, + publisher = {{IEEE}}, + doi = {10.1109/PACT.2009.21}, + isbn = {978-0-7695-3771-9} +} +% == BibLateX quality report for ref:saidani2009: +% Missing required field 'booktitle' + +@article{ref:schaller1997, + title = {Moore's Law: Past, Present and Future}, + shorttitle = {Moore's Law}, + author = {Schaller, R.R.}, + date = {1997-06}, + journaltitle = {IEEE Spectrum}, + volume = {34}, + pages = {52--59}, + issn = {0018-9235}, + doi = {10.1109/6.591665}, + number = {6} +} + +@article{ref:schmidt1998, + title = {Evaluating Architectures for Multithreaded Object Request Brokers}, + author = {Schmidt, Douglas C.}, + date = {1998-10-01}, + journaltitle = {Communications of the ACM}, + volume = {41}, + pages = {54--60}, + issn = {00010782}, + doi = {10.1145/286238.286248}, + number = {10} +} + +@incollection{ref:sheard2001, + title = {Accomplishments and Research Challenges in Meta-Programming}, + booktitle = {Semantics, {{Applications}}, and {{Implementation}} of {{Program Generation}}}, + author = {Sheard, Tim}, + editor = {Taha, Walid}, + date = {2001}, + volume = {2196}, + pages = {2--44}, + publisher = {{Springer Berlin Heidelberg}}, + location = {{Berlin, Heidelberg}}, + doi = {10.1007/3-540-44806-3_2}, + editorb = {Goos, Gerhard and Hartmanis, Juris and family=Leeuwen, given=Jan, prefix=van, useprefix=true}, + editorbtype = {redactor}, + isbn = {978-3-540-42558-8} +} + +@report{ref:shi1996, + title = {Reevaluating {{Amdahl}}'s Law and {{Gustafson}}'s Law}, + author = {Shi, Yuan}, + date = {1996-10}, + institution = {{Computer Sciences Department, Temple University (MS:38-24)}}, + type = {technical} +} + +@incollection{ref:shirako2008, + title = {Languages and Compilers for Parallel Computing}, + author = {Shirako, Jun and Kasahara, Hironori and Sarkar, Vivek}, + editor = {Adve, Vikram and Garzar\'an, Mar\'ia Jes\'us and Petersen, Paul}, + date = {2008}, + pages = {78--94}, + publisher = {{Springer-Verlag}}, + location = {{Berlin, Heidelberg}}, + doi = {10.1007/978-3-540-85261-2_6}, + isbn = {978-3-540-85260-5}, + langid = {english} +} +% == BibLateX quality report for ref:shirako2008: +% Missing required field 'booktitle' + +@inproceedings{ref:siek2000, + title = {Concept Checking: Binding Parametric Polymorphism in {{C}}++}, + author = {Siek, Jeremy and Lumsdaine, Andrew}, + date = {2000-10}, + eventtitle = {First Workshop on {{C}}++ {{Template Programming}}} +} +% == BibLateX quality report for ref:siek2000: +% Missing required field 'booktitle' + +@online{ref:siek2005, + title = {Concepts for C++0x}, + shorttitle = {n1758}, + author = {Siek, Jeremy and Gregor, Douglas and Garcia, Ronald and Willcock, Jeremiah and Järvi, Jaakko and Lumsdaine, Andrew}, + date = {2005-01-17}, + url = {http://www.open-std.org/JTC1/SC22/wg21/docs/papers/2005/n1758.pdf}, + annotation = {siek2005}, + langid = {english} +} +% == BibLateX quality report for ref:siek2005: +% ? Title looks like it was stored in title-case in Zotero + +@inproceedings{ref:smith1998, + title = {A Study of Branch Prediction Strategies}, + booktitle = {25 Years of the International Symposia on {{Computer}} Architecture (Selected Papers) - {{ISCA}} '98}, + author = {Smith, James E.}, + date = {1998}, + pages = {202--215}, + publisher = {{ACM Press}}, + location = {{Barcelona, Spain}}, + doi = {10.1145/285930.285980}, + eventtitle = {25 Years of the International Symposia}, + isbn = {978-1-58113-058-4}, + langid = {english} +} + +@online{ref:smith2018, + title = {Immediate Functions}, + shorttitle = {P1073r3}, + author = {Smith, Richard and Sutton, Andrew and Vandevoorde, Daveed}, + date = {2018-11-06}, + url = {http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1073r3.html}, + annotation = {smith2018}, + langid = {english} +} + +@online{ref:smith2018a, + title = {std::is\_constant\_ evaluated}, + shorttitle = {P0595r2}, + author = {Smith, Richard and Sutton, Andrew and Vandevoorde, Daveed}, + date = {2018-11-09}, + url = {http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0595r2.html}, + annotation = {smith2018}, + langid = {english} +} +% == BibLateX quality report for ref:smith2018a: +% ? Title looks like it was stored in lower-case in Zotero + +@article{ref:stallings1988, + title = {Reduced Instruction Set Computer Architecture}, + author = {Stallings, W.}, + date = {1988-01}, + journaltitle = {Proceedings of the IEEE}, + volume = {76}, + pages = {38--55}, + issn = {00189219}, + doi = {10.1109/5.3287}, + number = {1} +} + +@article{ref:stone2010, + title = {{{OpenCL}}: A Parallel Programming Standard for Heterogeneous Computing Systems}, + shorttitle = {{{OpenCL}}}, + author = {Stone, John E. and Gohara, David and Shi, Guochun}, + date = {2010-05}, + journaltitle = {Computing in science \& engineering}, + shortjournal = {Comput Sci Eng}, + volume = {12}, + pages = {66--73}, + issn = {1521-9615}, + doi = {10.1109/MCSE.2010.69}, + eprint = {21037981}, + eprinttype = {pmid}, + langid = {english}, + number = {3}, + pmcid = {PMC2964860} +} +% == BibLateX quality report for ref:stone2010: +% Unexpected field 'pmcid' + +@inproceedings{ref:striegnitz2000, + title = {Making {{C}}++ Ready for Algorithmic Skeletons}, + author = {Striegnitz, J\"org}, + date = {2000}, + pages = {10} +} +% == BibLateX quality report for ref:striegnitz2000: +% Missing required field 'booktitle' + +@book{ref:stroustrup1997, + title = {The {{C}}++ Programming Language}, + author = {Stroustrup, Bjarne}, + date = {1997}, + edition = {3rd ed}, + publisher = {{Addison-Wesley}}, + location = {{Reading, Mass}}, + isbn = {978-0-201-88954-3}, + langid = {english}, + pagetotal = {910} +} + +@online{ref:stroustrup2017, + title = {Concepts: the future of generic programming}, + shorttitle = {p0557r0}, + author = {Stroustrup, Bjarne}, + date = {2017-01-31}, + url = {http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0557r0.pdf}, + annotation = {stroustrup2017}, + langid = {english} +} + +@online{ref:sutter2019, + title = {Metaclasses: Generative {{C}}++}, + shorttitle = {P0707r4}, + author = {Sutter, Herb}, + date = {2019-06-16}, + url = {http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0707r4.pdf}, + annotation = {sutter2019}, + langid = {english} +} + +@inproceedings{ref:tamai1992, + title = {Software Lifetime and Its Evolution Process over Generations}, + booktitle = {Proceedings {{Conference}} on {{Software Maintenance}} 1992}, + author = {Tamai, T. and Torimitsu, Y.}, + date = {1992}, + pages = {63--69}, + publisher = {{IEEE Comput. Soc. Press}}, + location = {{Orlando, FL, USA}}, + doi = {10.1109/ICSM.1992.242557}, + eventtitle = {Conference on {{Software Maintenance}} 1992}, + isbn = {978-0-8186-2980-8} +} + +@article{ref:tomczak, + title = {{{GPU Ray Marching}} of {{Distance Fields}}}, + author = {Tomczak, Lukasz Jaroslaw}, + pages = {79}, + langid = {english} +} +% == BibLateX quality report for ref:tomczak: +% Exactly one of 'date' / 'year' must be present +% Missing required field 'journaltitle' +% ? Title looks like it was stored in title-case in Zotero + +@thesis{ref:tomczak2012, + title = {{{GPU}} Ray Marching of Distance Fields}, + author = {Tomczak, Lukasz Jaroslaw}, + date = {2012}, + institution = {{Technical University of Denmark}}, + location = {{Asmussens Alle, Building 305, DK-2800 Kgs. Lyngby, Denmark}}, + langid = {english}, + pagetotal = {79} +} +% == BibLateX quality report for ref:tomczak2012: +% Missing required field 'type' + +@thesis{ref:touraille2012, + title = {Application of Model-Driven Engineering and Metaprogramming to {{DEVS}} Modeling \& Simulation}, + author = {Touraille, Luc}, + date = {2012-12}, + institution = {{Universit\'e Blaise Pascal}}, + url = {https://tel.archives-ouvertes.fr/tel-00914327/}, + langid = {english}, + pagetotal = {312} +} +% == BibLateX quality report for ref:touraille2012: +% Missing required field 'type' + +@thesis{ref:toussaint2010, + title = {Algorithmique rapide pour les probl\`emes de tourn\'ees et d'ordonnancement}, + author = {Toussaint, H\'el\`ene}, + date = {2010-01-01}, + institution = {{Clermont-Ferrand 2}}, + url = {http://www.theses.fr/2010CLF22053}, + urldate = {2018-05-28}, + langid = {french} +} +% == BibLateX quality report for ref:toussaint2010: +% Missing required field 'type' + +@article{ref:turing1937, + title = {Computability and {$\lambda$}-Definability}, + author = {Turing, A. M.}, + date = {1937-12}, + journaltitle = {Journal of Symbolic Logic}, + volume = {2}, + pages = {153--163}, + issn = {0022-4812, 1943-5886}, + doi = {10.2307/2268280}, + langid = {english}, + number = {4} +} +% == BibLateX quality report for ref:turing1937: +% 'issn': not a valid ISSN + +@report{ref:unruh1994, + title = {Prime Number Computation}, + author = {Unruh, Erwin}, + date = {1994}, + institution = {{ANSI X3J16-94-0075/ISO WG21-462}} +} +% == BibLateX quality report for ref:unruh1994: +% Missing required field 'type' + +@book{ref:vandevoorde2010, + title = {C++ Templates: The Complete Guide}, + shorttitle = {C++ Templates: The Complete Guide}, + author = {Vandevoorde, Daveed and Josuttis, Nicolai M.}, + date = {2010}, + publisher = {{Addison-Wesley}}, + annotation = {OCLC: 706076856}, + isbn = {978-0-201-73484-3}, + langid = {english}, + pagetotal = {528} +} + +@book{ref:vandevoorde2017, + title = {C++ Templates: The Complete Guide}, + shorttitle = {C++ Templates: The Complete Guide}, + author = {Vandevoorde, Daveed and Josuttis, Nicolai M. and Gregor, Douglas}, + date = {2017}, + publisher = {{Addison-Wesley}}, + annotation = {OCLC: 1013589455}, + isbn = {978-0-321-71412-1}, + langid = {english}, + pagetotal = {788} +} + +@inproceedings{ref:vandierendonck2010, + title = {The Paralax Infrastructure: Automatic Parallelization with a Helping Hand}, + shorttitle = {The Paralax Infrastructure}, + booktitle = {2010 19th {{International Conference}} on {{Parallel Architectures}} and {{Compilation Techniques}} ({{PACT}})}, + author = {Vandierendonck, H. and Rul, S. and Bosschere, K. De}, + date = {2010-09}, + pages = {389--399}, + eventtitle = {2010 19th {{International Conference}} on {{Parallel Architectures}} and {{Compilation Techniques}} ({{PACT}})}, + langid = {english} +} +% == BibLateX quality report for ref:vandierendonck2010: +% ? Unsure about the formatting of the booktitle + +@article{ref:veldhuizen1995, + title = {Expression Templates}, + author = {Veldhuizen, Todd L.}, + date = {1995}, + journaltitle = {C++ Report}, + volume = {7}, + pages = {26--31}, + langid = {english} +} + +@incollection{ref:veldhuizen1996, + title = {Using {{C}}++ Template Metaprograms}, + booktitle = {C++ Gems}, + author = {Veldhuizen, Todd L.}, + editor = {Lippman, Stanley B.}, + date = {1996}, + pages = {459--473}, + publisher = {{SIGS Publications, Inc.}}, + location = {{New York, NY, USA}}, + url = {http://dl.acm.org/citation.cfm?id=260627.260748}, + urldate = {2018-08-27}, + isbn = {978-1-884842-37-5} +} + +@incollection{ref:veldhuizen1998, + title = {Arrays in {{Blitz}}++}, + booktitle = {Lecture {{Notes}} in {{Computer Science}}}, + author = {Veldhuizen, Todd L.}, + date = {1998}, + volume = {1505}, + pages = {223--230}, + publisher = {{Springer-Verlag}}, + langid = {english} +} +% == BibLateX quality report for ref:veldhuizen1998: +% Missing required field 'editor' +% ? Title looks like it was stored in title-case in Zotero + +@inproceedings{ref:veldhuizen1998a, + title = {Active Libraries: Rethinking the Roles of Compilers and Libraries}, + shorttitle = {Active {{Libraries}}}, + booktitle = {Proceedings of the {{SIAM Workshop}} on {{Object Oriented Methods}} for {{Inter}}-Operable {{Scientific}} and {{Engineering Computing}}}, + author = {Veldhuizen, Todd L. and Gannon, Dennis}, + date = {1998}, + pages = {286--295}, + publisher = {{SIAM Press}}, + langid = {english} +} + +@incollection{ref:veldhuizen2000, + title = {Blitz++: The Library That Thinks It Is a Compiler}, + shorttitle = {Blitz++}, + booktitle = {Advances in {{Software Tools}} for {{Scientific Computing}}}, + author = {Veldhuizen, Todd L.}, + date = {2000}, + volume = {10}, + pages = {57--87}, + publisher = {{Springer Berlin Heidelberg}}, + location = {{Berlin, Heidelberg}}, + doi = {10.1007/978-3-642-57172-5_2}, + isbn = {978-3-540-66557-1} +} +% == BibLateX quality report for ref:veldhuizen2000: +% Missing required field 'editor' + +@book{ref:veldhuizen2000a, + title = {Five Compilation Models for {{C}}++ Templates ({{Extended Abstract}})}, + author = {Veldhuizen, Todd L.}, + date = {2000}, + langid = {english} +} + +@report{ref:veldhuizen2003, + title = {C++ Templates Are {{Turing}} Complete}, + author = {Veldhuizen, Todd L.}, + date = {2003}, + institution = {{Indiana University Computer Science}}, + langid = {english} +} +% == BibLateX quality report for ref:veldhuizen2003: +% Missing required field 'type' + +@article{ref:videau2018, + title = {{{BOAST}}: A Metaprogramming Framework to Produce Portable and Efficient Computing Kernels for {{HPC}} Applications}, + shorttitle = {{{BOAST}}}, + author = {Videau, Brice and Pouget, Kevin and Genovese, Luigi and Deutsch, Thierry and Komatitsch, Dimitri and Desprez, Fr\'ed\'eric and M\'ehaut, Jean-Fran\c{c}ois}, + date = {2018-01}, + journaltitle = {The International Journal of High Performance Computing Applications}, + volume = {32}, + pages = {28--44}, + issn = {1094-3420, 1741-2846}, + doi = {10.1177/1094342017718068}, + langid = {english}, + number = {1} +} +% == BibLateX quality report for ref:videau2018: +% 'issn': not a valid ISSN + +@online{ref:vollmann2016, + title = {Why Joining\_thread from {{P0206}} Is a Bad Idea}, + shorttitle = {P0379r0}, + author = {Vollmann, Detlef}, + date = {2016-05-27}, + url = {http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0379r0.html}, + annotation = {vollmann2016}, + langid = {english} +} + +@inproceedings{ref:voufo2011, + title = {{{ConceptClang}}: An Implementation of {{C}}++ Concepts in {{Clang}}}, + shorttitle = {{{ConceptClang}}}, + booktitle = {Proceedings of the Seventh {{ACM SIGPLAN}} Workshop on {{Generic}} Programming - {{WGP}} '11}, + author = {Voufo, Larisse and Zalewski, Marcin and Lumsdaine, Andrew}, + date = {2011}, + pages = {71}, + publisher = {{ACM Press}}, + location = {{Tokyo, Japan}}, + doi = {10.1145/2036918.2036929}, + eventtitle = {The Seventh {{ACM SIGPLAN}} Workshop}, + isbn = {978-1-4503-0861-8}, + langid = {english} +} +% == BibLateX quality report for ref:voufo2011: +% ? Unsure about the formatting of the booktitle + +@online{ref:voutilainen2016, + title = {A Joining Thread}, + author = {Voutilainen, Ville}, + date = {2016-03-09}, + url = {http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0206r1.html}, + annotation = {voutilainen2016}, + langid = {english} +} + +@article{ref:walker1996, + title = {{{MPI}}: A Standard Message Passing Interface}, + author = {Walker, David W and Dongarra, Jack J}, + date = {1996}, + journaltitle = {Supercomputer}, + pages = {15}, + langid = {english} +} + +@inproceedings{ref:willhalm2008, + title = {Putting {{Intel}}\textregistered{} {{Threading Building Blocks}} to Work}, + booktitle = {Proceedings of the 1st {{International Workshop}} on {{Multicore Software Engineering}}}, + author = {Willhalm, Thomas and Popovici, Nicolae}, + date = {2008}, + pages = {3--4}, + publisher = {{ACM}}, + location = {{New York, NY, USA}}, + doi = {10.1145/1370082.1370085}, + isbn = {978-1-60558-031-9}, + langid = {english}, + series = {{{IWMSE}} '08} +} + +@inproceedings{ref:wolf2007, + title = {Evolutionary {{Local Search}} for the {{Super}}-{{Peer Selection Problem}} and the p-{{Hub Median Problem}}}, + booktitle = {Hybrid {{Metaheuristics}}}, + author = {Wolf, Steffen and Merz, Peter}, + editor = {Bartz-Beielstein, Thomas and Blesa Aguilera, Mar\'ia Jos\'e and Blum, Christian and Naujoks, Boris and Roli, Andrea and Rudolph, G\"unter and Sampels, Michael}, + date = {2007}, + pages = {1--15}, + publisher = {{Springer}}, + location = {{Berlin, Heidelberg}}, + doi = {10.1007/978-3-540-75514-2_1}, + isbn = {978-3-540-75514-2}, + langid = {english}, + series = {Lecture {{Notes}} in {{Computer Science}}} +} +% == BibLateX quality report for ref:wolf2007: +% ? Unsure about the formatting of the booktitle +% ? Title looks like it was stored in title-case in Zotero + +@article{ref:wrede2020, + title = {Generation of High-Performance Code Based on a Domain-Specific Language for Algorithmic Skeletons}, + author = {Wrede, Fabian and Rieger, Christoph and Kuchen, Herbert}, + date = {2020-07}, + journaltitle = {The Journal of Supercomputing}, + volume = {76}, + pages = {5098--5116}, + doi = {10.1007/s11227-019-02825-6}, + langid = {english}, + number = {7} +} + +@inproceedings{ref:zhang2009, + title = {Implementing and Testing Producer-Consumer Problem Using Aspect-Oriented Programming}, + booktitle = {2009 {{Fifth International Conference}} on {{Information Assurance}} and {{Security}}}, + author = {Zhang, Yang and Zhang, Jingjun and Zhang, Dongwen}, + date = {2009}, + pages = {749--752}, + publisher = {{IEEE}}, + location = {{Xi'An China}}, + doi = {10.1109/IAS.2009.41}, + eventtitle = {2009 {{Fifth International Conference}} on {{Information Assurance}} and {{Security}}}, + isbn = {978-0-7695-3744-3} +} +% == BibLateX quality report for ref:zhang2009: +% ? Unsure about the formatting of the booktitle + +@inproceedings{ref:zhang2018, + title = {Vectorized Parallel Sparse Matrix-Vector Multiplication in {{PETSc}} Using {{AVX}}-512}, + booktitle = {Proceedings of the 47th {{International Conference}} on {{Parallel Processing}}}, + author = {Zhang, Hong and Mills, Richard T. and Rupp, Karl and Smith, Barry F.}, + date = {2018-08-13}, + pages = {1--10}, + publisher = {{ACM}}, + location = {{Eugene OR USA}}, + doi = {10.1145/3225058.3225100}, + eventtitle = {{{ICPP}} 2018: 47th {{International Conference}} on {{Parallel Processing}}}, + isbn = {978-1-4503-6510-9}, + langid = {english} +} + +@article{ref:zhu1993, + title = {A General Descent Framework for Monotone Variational Inequalities}, + author = {Zhu, Daoli L. and Marcotte, Patrice}, + date = {1993}, + journaltitle = {Journal of optimisation theory and applications}, + entrysubtype = {newspaper} +} + +@article{ref:zima1988, + title = {{{SUPERB}}: A Tool for Semi-Automatic {{MIMD}}/{{SIMD}} Parallelization}, + shorttitle = {{{SUPERB}}}, + author = {Zima, Hans P and Bast, Heinz-J and Gerndt, Michael}, + date = {1988-01}, + journaltitle = {Parallel Computing}, + shortjournal = {Parallel Computing}, + volume = {6}, + pages = {1--18}, + issn = {0167-8191}, + doi = {10.1016/0167-8191(88)90002-6}, + langid = {english}, + number = {1} +} + + +% Required packages: +% * textcomp + diff --git a/src/tikz/alsk.tex b/src/tikz/alsk.tex new file mode 100644 index 0000000..1fad03b --- /dev/null +++ b/src/tikz/alsk.tex @@ -0,0 +1,92 @@ +%{{{ +\tikzset{alsk/label/.style={}} +%}}} + +%{{{ pack for schemes " +\tikzset{alsk/scheme/split/.style={ + common/drawfill=colStruct, + regular polygon,regular polygon sides=3, + minimum width=10mm, + inner sep=0mm +}} + +\tikzset{alsk/scheme/join/.style={ + alsk/scheme/split, + shape border rotate=180 +}} + +\tikzset{alsk/scheme/loop/.style={ + common/drawfill=colStruct, + regular polygon,regular polygon sides=4, + minimum width=8mm, + inner sep=0mm, + shape border rotate=45 +}} + +\tikzset{alsk/scheme/frame/.style={ + draw=#1, + rectangle,dotted,thick, + rounded corners=1mm, + inner sep=1mm +}} + +\tikzset{alsk/scheme/task/.style={ + common/drawfill=colMuscle, + circle, + minimum width=8mm, + inner sep=0mm +}} + +\tikzset{alsk/scheme/link/.style={ + ->, + rounded corners +}} +%}}} + +%{{{ pack for trees " +\tikzset{alsk/tree/muscle/.style={ + common/drawfill=colMuscle, + rectangle,rounded corners=.7mm, + minimum width=12mm,minimum height=6mm +}} + +\tikzset{alsk/tree/struct/.style={ + common/drawfill=colStruct, + rectangle,rounded corners=.7mm, + minimum width=16mm,minimum height=6mm +}} + +\tikzset{alsk/treestyle/.style={ + edge from parent path={(\tikzparentnode) -- (\tikzchildnode.north)}, + level distance=15mm,sibling distance=1mm, + branch/.style=alsk/tree/struct, + leaf/.style=alsk/tree/muscle, + every internal node/.style=branch, + every leaf node/.style=leaf, +}} +%}}} + +%{{{ pack for links " +\tikzset{alsk/links/muscle/.style={ + common/drawfill=colMuscle, + rectangle,rounded corners=.7mm, + minimum width=10mm,minimum height=5mm, +}} + +\tikzset{alsk/links/sig/.style={ + common/drawfill=#1, + signal,signal from=west,signal to=east, + minimum width=2mm, +}} + +\tikzset{alsk/links/link/.style={ + -,rounded corners=.8mm +}} + +\tikzset{alsk/links/fit/.style={ + draw, + dashed,rounded corners=2mm, + fit=#1, + fit margins={left=-1mm,bottom=1.5mm,right=2mm,top=1.5mm}, +}} +%}}} diff --git a/src/tikz/ast.tex b/src/tikz/ast.tex new file mode 100644 index 0000000..dcb78a5 --- /dev/null +++ b/src/tikz/ast.tex @@ -0,0 +1,11 @@ +\tikzset{ast/tree/node/.style={ + common/drawfill=black, + rectangle,minimum size=6mm,rounded corners=1mm, + align=center +}} + +\tikzset{ast/treestyle/.style={ + edge from parent path={(\tikzparentnode) -- (\tikzchildnode.north)}, + level distance=15mm,sibling distance=3mm, + every tree node/.style=ast/tree/node, +}} diff --git a/src/tikz/common.tex b/src/tikz/common.tex new file mode 100644 index 0000000..27907e8 --- /dev/null +++ b/src/tikz/common.tex @@ -0,0 +1,84 @@ +\tikzset{common/drawfillf/.style n args={2}{ + draw=#1,fill=#1!#2 +}} + +\tikzset{common/drawfill/.style={ + common/drawfillf={#1}{5} +}} + +\tikzset{common/arrow/.style={ + rounded corners +}} + +\tikzset{common/overlay/.style={overlay}} + +\tikzset{fit margins/.style={ + /tikz/afit/.cd,#1, + /tikz/.cd, + inner xsep=\pgfkeysvalueof{/tikz/afit/left}+\pgfkeysvalueof{/tikz/afit/right}, + inner ysep=\pgfkeysvalueof{/tikz/afit/top}+\pgfkeysvalueof{/tikz/afit/bottom}, + xshift=-\pgfkeysvalueof{/tikz/afit/left}+\pgfkeysvalueof{/tikz/afit/right}, + yshift=-\pgfkeysvalueof{/tikz/afit/bottom}+\pgfkeysvalueof{/tikz/afit/top} +}, afit/.cd,left/.initial=2pt,right/.initial=2pt,bottom/.initial=2pt,top/.initial=2pt +} + +%{{{ Beamer " +\tikzset{alt/.code args={<#1>#2#3}{% + \alt<#1>{\pgfkeysalso{#2}}{\pgfkeysalso{#3}} +}} + +\tikzset{ + invisible/.style={opacity=0,text opacity=0}, + visible on/.style={alt={#1{}{invisible}}} +} + +\tikzset{only on/.style args={<#1>#2}{alt={<#1>{#2}{}}}} +%}}} + +%{{{ misc " +\tikzset{pics/gear/.style n args={3}{ + code={ + \def\modu{#1} + \def\Zb{#2} + \def\AngleA{#3} + + \pgfmathsetmacro{\Rpr}{\Zb*\modu/2} + \pgfmathsetmacro{\Rb}{\Rpr*cos(\AngleA)} + \pgfmathsetmacro{\Rt}{\Rpr+\modu} + \pgfmathsetmacro{\Rp}{\Rpr-1.25*\modu} + \pgfmathsetmacro{\AngleT}{pi/180*acos(\Rb/\Rt)} + \pgfmathsetmacro{\AnglePr}{pi/180*acos(\Rb/\Rpr)} + \pgfmathsetmacro{\demiAngle}{180/\Zb} + \pgfmathsetmacro{\Angledecal}{(\demiAngle-2*\AnglePr)/2} + + \path[pic actions] foreach \zz in{1,...,\Zb}{ + \ifnum\zz=1 + (\zz/\Zb*360-\Angledecal:\Rp) + \else + -- (\zz/\Zb*360-\Angledecal:\Rp) + \fi + to[bend right=\demiAngle] + (\zz/\Zb*360+\Angledecal:\Rp) + -- + plot[domain=-0:\AngleT,smooth,variable=\t] + ({{180/pi*(-\t+tan(180/pi*\t)) +\zz/\Zb*360+\Angledecal}:\Rb/cos(180/pi*\t)}) + % + to[bend right=\demiAngle] + ({{180/pi*(\AngleT+tan(180/pi*-\AngleT)) +(\zz+1)/\Zb*360-\Angledecal}: + \Rb/cos(180/pi*-\AngleT)}) + -- + plot[domain=-\AngleT:-0,smooth,variable=\t] + ({{180/pi*(-\t+tan(180/pi*\t)) +(\zz+1)/\Zb*360-\Angledecal}:\Rb/cos(180/pi*\t)}) + } -- cycle; + } +}} + +\tikzset{common/rhl/.style={ + common/drawfillf={#1}{50}, + rectangle,rounded corners, + minimum height=3ex, + inner sep=0pt, + yshift=.5ex, + opacity=.25 +}} +%}}} diff --git a/src/tikz/et.tex b/src/tikz/et.tex new file mode 100644 index 0000000..272f366 --- /dev/null +++ b/src/tikz/et.tex @@ -0,0 +1,18 @@ +\tikzset{et/tree/node/.style={ + common/drawfill=black, + circle,minimum size=9mm, + inner sep=.5mm, + font=\strut +}} + +\tikzset{et/treestyle/.style={ + edge from parent path={(\tikzparentnode) -- (\tikzchildnode.north)}, + level distance=15mm,sibling distance=1mm, + every tree node/.style=et/tree/node, +}} + +\tikzset{et/frame/.style={ + draw,dashed, + rectangle,rounded corners=3mm, + fit=#1 +}} diff --git a/src/tikz/exec.tex b/src/tikz/exec.tex new file mode 100644 index 0000000..cf93fe8 --- /dev/null +++ b/src/tikz/exec.tex @@ -0,0 +1,21 @@ +\tikzset{exec/fifonode/.style={ + draw,fill=black!3,signal,signal from=west,signal to=east, + minimum width=12mm,minimum height=6mm,line width=.1mm +}} + +\tikzset{exec/thread/.style={ + draw=#1,fill=#1!10, + rectangle,rounded corners=2mm, + minimum width=6mm,minimum height=6mm +}} + +\tikzset{exec/pool/.style={ + draw,fill=black!2, + fit=#1, + decorate,decoration={snake,amplitude=1pt} +}} + +\tikzset{exec/fit/.style={ + draw,rounded corners,dashed, + fit=#1 +}} diff --git a/src/tikz/mp.tex b/src/tikz/mp.tex new file mode 100644 index 0000000..bfe8761 --- /dev/null +++ b/src/tikz/mp.tex @@ -0,0 +1,63 @@ +%{{{ Program " +\tikzset{pics/program/.style={ + code={ + \def\lscale{#1} + + \def\w{1.5} + \pgfmathsetmacro{\h}{\w*sqrt(2)}% A-page ratio + \def\mh{.1} + \def\mv{.08} + \def\nl{10} + \def\cl{.15} + + \coordinate (corner left) at (-\w/2,\h/2-\cl); + + \draw[rounded corners=.4,fill=black!5] (corner left) -- ++(\cl,0) -- ++(0,\cl) + -- (corner left) -- ++(0,\cl-\h) -- ++(\w,0) -- ++(0,\h) -- ++(\cl-\w,0); + \foreach \i in {1,...,\nl} { + \draw[decorate,decoration={random steps,segment length=1,amplitude=.3}] + (\mh-\w/2,{-(\h-2*\mv)*\i/\nl+\mv+\h/2-\cl}) -- +(\w-2*\mh,0); + } + } + }, + pics/program/.default=1 +} +%}}} + +%{{{ Binary " +\tikzset{pics/binary/.style={ + code={ + \def\lscale{#1} + + \def\w{1.5} + \pgfmathsetmacro{\h}{\w*sqrt(2)}% A-page ratio + \def\mh{.1} + \def\mv{.08} + \def\cl{.15} + + \coordinate (corner left) at (-\w/2,\h/2-\cl); + + \def\gteethA{23} + \def\gteethB{11} + \def\gteethC{17} + \def\gmod{.04} + \def\gangle{15} + \def\grotAB{-60} + \def\grotBC{-115} + \pgfmathsetmacro{\gdistAB}{(\gteethA+\gteethB)*\gmod/2} + \pgfmathsetmacro{\gdistBC}{(\gteethB+\gteethC)*\gmod/2} + + \coordinate (gear0) at (-.05,.475); + \coordinate (gear1) at ($(gear0)+(\grotAB:\gdistAB)$); + \coordinate (gear2) at ($(gear1)+(\grotBC:\gdistBC)$); + + \draw[rounded corners=.4,fill=black!5] (corner left) -- ++(\cl,0) -- ++(0,\cl) + -- (corner left) -- ++(0,\cl-\h) -- ++(\w,0) -- ++(0,\h) -- ++(\cl-\w,0); + \pic[draw,fill=red!20!black!20,rotate=\grotAB+90/\gteethA] at (gear0) {gear={\gmod*\lscale}{\gteethA}{\gangle}}; + \pic[draw,fill=green!20!black!20,rotate=\grotAB-90/\gteethB] at (gear1) {gear={\gmod*\lscale}{\gteethB}{\gangle}}; + \pic[draw,fill=blue!20!black!20,rotate=3] at (gear2) {gear={\gmod*\lscale}{\gteethC}{\gangle}}; + } + }, + pics/binary/.default=1 +} +%}}} diff --git a/src/tikz/orchestration.tex b/src/tikz/orchestration.tex new file mode 100644 index 0000000..2ca368b --- /dev/null +++ b/src/tikz/orchestration.tex @@ -0,0 +1,15 @@ +\tikzset{orch/task/.style={ + draw=#1,fill=#1!5, + circle, minimum width=12mm +}} + +\tikzset{orch/subtask/.style={ + draw=#1,fill=#1!15, + circle, minimum width=4mm +}} + +\tikzset{orch/taskspan/.style={ + draw=#1,fill=#1!5, + rectangle,rounded corners=1mm, + minimum width=28mm,minimum height=8mm +}} diff --git a/src/tikz/parallel.tex b/src/tikz/parallel.tex new file mode 100644 index 0000000..cd2bc0e --- /dev/null +++ b/src/tikz/parallel.tex @@ -0,0 +1,27 @@ +\tikzset{parallel/block/.style={ + thick, + minimum width=8mm,minimum height=8mm +}} + +\tikzset{parallel/task/.style={ + common/drawfill=black, + parallel/block, + rectangle,rounded corners, +}} + +\tikzset{parallel/arrow/.style={ + thick,->,>=stealth, + rounded corners +}} + +\tikzset{parallel/point/.style={ + common/drawfill=black, + circle,minimum width=2mm +}} + +\tikzset{parallel/region/.style={ + draw=black!50,fill=green!4, + rectangle,rounded corners=2mm, + dashed, + fit=#1 +}} diff --git a/src/tikz/repeat.tex b/src/tikz/repeat.tex new file mode 100644 index 0000000..e43d680 --- /dev/null +++ b/src/tikz/repeat.tex @@ -0,0 +1,13 @@ +\tikzset{prng/element/.style={ + common/drawfill=black, + signal,signal from=east,signal to=west, + minimum width=12mm +}} + +\tikzset{prng/below/.style={ + node distance=1cm,below=of #1 +}} + +\tikzset{prng/drawfill/.style={ + common/drawfillf={#1}{20} +}} diff --git a/src/tikz/tsp.tex b/src/tikz/tsp.tex new file mode 100644 index 0000000..fa2d9e2 --- /dev/null +++ b/src/tikz/tsp.tex @@ -0,0 +1,30 @@ +\newcommand{\tspnodes}{ + \coordinate (p0) at (0, 0); + \coordinate (p1) at (1, 1); + \coordinate (p2) at (2, -.5); + \coordinate (p3) at (3.5, 1.5); + \coordinate (p4) at (2.5, 2); + \coordinate (p5) at (3, 2.5); + \coordinate (p6) at (2, 3); + \coordinate (p7) at (.5, 2.75); + \coordinate (p8) at (0.75, 2.25); + \coordinate (p9) at (-.5, 1.25); + + \def\n{10} + \pgfmathtruncatemacro{\last}{\n-1} + \pgfmathtruncatemacro{\penult}{\last-1} +} + +\tikzset{tsp/node/.style={ + fill=black, + circle, + minimum size=5pt, + inner sep=0pt +}} + +\tikzset{tsp/edge/.style={ + thick +}} + +\tikzset{tsp/localbest/.style={common/drawfill=yellow!70!black}} +\tikzset{tsp/best/.style={common/drawfill=green!70!black}} diff --git a/src/usr/alg.tex b/src/usr/alg.tex new file mode 100644 index 0000000..fb5727c --- /dev/null +++ b/src/usr/alg.tex @@ -0,0 +1,28 @@ +% \renewcommand*\Call[2]{\textproc{#1}(#2)} + +\renewcommand{\listalgorithmname}{Liste des algorithmes} +\floatname{algorithm}{Algorithme} + +\algrenewcommand\algorithmicreturn{\textbf{retourner}} +\algrenewcommand\algorithmicprocedure{\textbf{procédure}} +\algrenewcommand\algorithmicfunction{\textbf{fonction}} +\algrenewcommand\algorithmicrequire{\textbf{Entrée :}} +\algrenewcommand\algorithmicensure{\textbf{Sortie :}} +\algrenewcommand\algorithmicend{\textbf{fin}} +\algrenewcommand\algorithmicif{\textbf{si}} +\algrenewcommand\algorithmicthen{\textbf{alors}} +\algrenewcommand\algorithmicelse{\textbf{sinon}} +\algrenewcommand\algorithmicfor{\textbf{pour}} +\algrenewcommand\algorithmicforall{\textbf{pour tout}} +\algrenewcommand\algorithmicdo{\textbf{faire}} +\algrenewcommand\algorithmicwhile{\textbf{tant que}} +\algrenewcommand\algorithmicrepeat{\textbf{répéter}} +\algrenewcommand\algorithmicuntil{\textbf{jusqu'à ce que}} + +% \renewcommand\Not{\textbf{non}\ } +\renewcommand\And{\textbf{et}\ } +% \renewcommand\Or{\textbf{ou}\ } + +\newcommand{\algorithmicelsif}{\algorithmicelse\ \algorithmicif} +\newcommand{\algorithmicendif}{\algorithmicend\ \algorithmicif} +\newcommand{\algorithmicendfor}{\algorithmicend\ \algorithmicfor} diff --git a/src/usr/beamer.tex b/src/usr/beamer.tex new file mode 100644 index 0000000..37ea2f7 --- /dev/null +++ b/src/usr/beamer.tex @@ -0,0 +1,101 @@ +\usepackage{pgfpages} + +\usetheme{Darmstadt}% or Frankfurt to remove subsection +\usecolortheme{seahorse} +\usefonttheme{default} + +\setbeamertemplate{navigation symbols}{} +\setbeamertemplate{footline}[title] + +\makeatletter +\def\jury{% +Alexandre \textsc{Guitton} & Professeur des universités & Université Clermont Auvergne & Président \\ +Joël \textsc{Falcou} & Maître de conférences HDR & Université Paris-Saclay & Rapporteur \\ +Françoise \textsc{Baude} & Professeur des universités & Université Côte d'Azur & Rapporteuse \\ +Éric \textsc{Innocenti} & Maître de conférences & Université de Corse & Examinateur \\ +Bruno \textsc{Bachelet} & Maître de conférences HDR & Université Clermont Auvergne & Directeur de thèse\\ +David \textsc{Hill} & Professeur des universités & Université Clermont Auvergne & Co-directeur de thèse\\ +} +\def\juryinvited{% +Claude \textsc{Mazel} & Maître de conférences & Université Clermont Auvergne & Invité \\ +Jian-Jin \textsc{Li} & Maître de conférences & Université Clermont Auvergne & Invitée \\ +} + +\setbeamertemplate{title page}{ + \begin{centering} + \begin{beamercolorbox}[rounded=true,sep=8pt,center]{title} + \usebeamerfont{title}\inserttitle\par% + \ifx\insertsubtitle\@empty% + \else% + \vskip0.25em% + { + \usebeamerfont{subtitle} + \vspace{.5em} + \usebeamercolor[fg]{subtitle} + \insertsubtitle + \par + }% + \fi% + \end{beamercolorbox}% + \vskip1em\par + \begin{beamercolorbox}[sep=6pt,center]{author} + \usebeamerfont{author}\insertauthor + \end{beamercolorbox} + \begin{beamercolorbox}[sep=4pt,center]{author} + \tiny Thèse encadrée par Bruno Bachelet, David Hill, Claude Mazel + \end{beamercolorbox} + \begin{beamercolorbox}[sep=6pt,center]{institute} + \usebeamerfont{institute}\insertinstitute + \end{beamercolorbox} + \end{centering} + \begin{centering} + \begin{beamercolorbox}[sep=6pt,center]{date} + \usebeamerfont{date}\insertdate + \end{beamercolorbox}%\vskip0.5em + \begin{columns} + \begin{column}{.9\paperwidth} + \begin{beamercolorbox}[sep=6pt,center]{jury} + Membres du jury + \vskip.2em\par + \tiny + \def\arraystretch{1.2} + \begin{tabular}{l >{\it}l l l} + \jury + % \juryinvited + \end{tabular} + \end{beamercolorbox} + \end{column} + \end{columns} + \end{centering} +} +\makeatother + +\setbeamertemplate{footline}{ + \leavevmode + \hbox{% + \begin{beamercolorbox}[wd=.20\paperwidth,ht=2.25ex,dp=1ex,center]{author in head/foot} + \usebeamerfont{author in head/foot} + \insertshortauthor + \end{beamercolorbox}% + \begin{beamercolorbox}[wd=.50\paperwidth,ht=2.25ex,dp=1ex,center]{title in head/foot} + \usebeamerfont{title in head/foot} + \insertsubtitle + \end{beamercolorbox}% + \begin{beamercolorbox}[wd=.20\paperwidth,ht=2.25ex,dp=1ex,right]{date in head/foot} + \usebeamerfont{date in head/foot} + \insertshortdate{}\hspace*{2em} + \end{beamercolorbox}% + \begin{beamercolorbox}[wd=.10\paperwidth,ht=2.25ex,dp=1ex,right]{title in head/foot} + \insertframenumber{} / \inserttotalframenumber\hspace*{2ex} + \end{beamercolorbox}% + } + \vskip0pt +} + +\newcommand\inserttoc[4]{ + % \section*{} + % \subsection*{#1} + \begin{frame}[label=current]{#2} + \tableofcontents[#3] + \end{frame} +} diff --git a/src/usr/bibstyle.tex b/src/usr/bibstyle.tex new file mode 100644 index 0000000..29246f2 --- /dev/null +++ b/src/usr/bibstyle.tex @@ -0,0 +1,58 @@ +% citations links include author +\DeclareFieldFormat{citehyperref}{% + \DeclareFieldAlias{bibhyperref}{noformat}% Avoid nested links + \bibhyperref{#1}} + +\DeclareFieldFormat{textcitehyperref}{% + \DeclareFieldAlias{bibhyperref}{noformat}% Avoid nested links + \bibhyperref{% + #1% + \ifbool{cbx:parens} + {\bibcloseparen\global\boolfalse{cbx:parens}} + {}}} + +\savebibmacro{cite} +\savebibmacro{textcite} + +\renewbibmacro*{cite}{% + \printtext[citehyperref]{% + \restorebibmacro{cite}% + \usebibmacro{cite}}} + +\renewbibmacro*{textcite}{% + \ifboolexpr{ + ( not test {\iffieldundef{prenote}} and + test {\ifnumequal{\value{citecount}}{1}} ) + or + ( not test {\iffieldundef{postnote}} and + test {\ifnumequal{\value{citecount}}{\value{citetotal}}} ) + } + {\DeclareFieldAlias{textcitehyperref}{noformat}} + {}% + \printtext[textcitehyperref]{% + \restorebibmacro{textcite}% + \usebibmacro{textcite}}} + +% replace cite by autocite +% \renewbibmacro*{cite}{\usebibmacro{autocite}} + +% disable small caps for author names +\renewcommand*{\mkbibnamefamily}[1]{#1} +\renewcommand*{\mkbibnameprefix}[1]{#1} + +% replace parenthesis by angle brackets +\makeatletter + +\newrobustcmd*{\parentexttrack}[1]{% + \begingroup + \blx@blxinit + \blx@setsfcodes + \blx@bibopenparen#1\blx@bibcloseparen + \endgroup} + +\AtEveryCite{% + \let\parentext=\parentexttrack% + \let\bibopenparen=\bibopenbracket% + \let\bibcloseparen=\bibclosebracket} + +\makeatother diff --git a/src/usr/colors.tex b/src/usr/colors.tex new file mode 100644 index 0000000..4ab56e5 --- /dev/null +++ b/src/usr/colors.tex @@ -0,0 +1,21 @@ +\colorlet{colStruct}{cyan!50!blue} +\colorlet{colMuscle}{yellow!50!red} +\definecolor{colLinkIn}{RGB}{127,66,255} +\definecolor{colLinkOut}{RGB}{127,189,0} +\colorlet{colLinkCtx}{colLinkIn!50!red!80!black} + +\definecolor{colFSr}{RGB}{0,0,0} +\definecolor{colFSp0}{RGB}{0,0,0} +\definecolor{colSr}{RGB}{0,0,0} +\definecolor{colSp0}{RGB}{0,0,0} +\definecolor{colCHr}{RGB}{0,0,0} +\definecolor{colCHp0}{RGB}{0,0,0} +\definecolor{colCHp1}{RGB}{0,0,0} +\definecolor{colLSr}{RGB}{0,0,0} +\definecolor{colLSp0}{RGB}{0,0,0} +\definecolor{colLSp1}{RGB}{0,0,0} +\definecolor{colSelr}{RGB}{0,0,0} +\definecolor{colSelp}{RGB}{0,0,0} + +\colorlet{colThread0}{red!60!green} +\colorlet{colThread1}{blue!80!green} diff --git a/src/usr/listing.tex b/src/usr/listing.tex new file mode 100644 index 0000000..e441873 --- /dev/null +++ b/src/usr/listing.tex @@ -0,0 +1,84 @@ +%{{{ current font size " +\makeatletter +\newcommand{\currentfontsize}{\fontsize{\f@size}{\f@baselineskip}\selectfont} +\makeatother +%}}} + +%{{{ configuration " +\setminted{fontsize=\small,tabsize=2,autogobble,breaklines} +\setmintedinline{fontsize=\currentfontsize} + +\newmintinline{cpp}{breaklines,breakafter=_:<>} +\newmintinline{c}{breaklines,breakafter=_:<>} +\newmintinline{asm}{} +\newmintinline{haskell}{} +\newmintinline{lisp}{} +%}}} + +%{{{ customize appearance " +% \BeforeBeginEnvironment{minted}{\begin{tcolorbox}[boxsep=-2mm]} +% \AfterEndEnvironment{minted}{\end{tcolorbox}} +%}}} + +%{{{ tcolorbox " +\newtcblisting{cppcode}{ + listing engine=minted, + minted language=cpp, + minted options={ + fontsize=\small, + tabsize=2, + autogobble, + breaklines, + escapeinside=|| + }, + listing only, + boxsep=-2mm +} + +\newtcblisting{asmcode}{ + listing engine=minted, + minted language=asm, + minted options={ + fontsize=\small, + tabsize=2, + autogobble, + breaklines, + escapeinside=|| + }, + listing only, + enhanced, + boxsep=-2mm +} + +\newtcblisting{cppcode*}[1]{ + listing engine=minted, + minted language=cpp, + minted options={ + fontsize=\small, + tabsize=2, + autogobble, + breaklines, + escapeinside=|| + }, + listing only, + boxsep=-2mm, + enhanced, + remember as={#1} +} + +\newtcblisting{minicppcode}{ + listing engine=minted, + minted language=cpp, + minted options={ + fontsize={\fontsize{4}{5}\selectfont}, + tabsize=2, + autogobble, + breaklines, + escapeinside=|| + }, + listing only, + boxsep=-2mm +} + +\newtcbox{hlbox}[1]{on line,colback=#1,size=small,frame empty,left=0pt,right=0pt} +%}}} diff --git a/src/usr/math.tex b/src/usr/math.tex new file mode 100644 index 0000000..077e7a9 --- /dev/null +++ b/src/usr/math.tex @@ -0,0 +1,18 @@ +\newtheoremstyle{thmstyle} +{}% measure of space to leave above the theorem +{}% measure of space to leave below the theorem +{}% name of font to use in the body of the theorem +{}% measure of space to indent +{}% name of head font +{~:}% punctuation between head and body +{ }% space after theorem head +{\thmname{#1}\thmnumber{ #2}\thmnote{ #3}} + +\theoremstyle{thmstyle} + +\newtheorem*{thm}{Théorème} +\newtheorem*{thmdef}{Définition} +\newtheorem*{thmlemme}{Lemme} +\newtheorem*{thmproof}{Démonstration} +\newtheorem*{thmrq}{Remarque} +\newtheorem*{thmex}{Exemple} diff --git a/src/usr/ocg.tex b/src/usr/ocg.tex new file mode 100644 index 0000000..a9670fb --- /dev/null +++ b/src/usr/ocg.tex @@ -0,0 +1,246 @@ +%{{{ +\newcommand{\ocgradio}[4]{ + \makebox[0pt][l]{\showocg[onmouseall]{{#2},,,{#2}}{#3}}% + \begin{ocg}[radiobtngrp=#1]{#2}{#2}{#4}\showocg{}{\underline{#3}}\end{ocg} +} + +\newcommand{\ocgcase}[5]{\makebox[0pt][c]{\begin{ocg}[radiobtngrp=#1]{#2}{#3}{#4}#5\end{ocg}}} +\newcommand{\ocmdcase}[2]{\makebox[0pt][c]{\begin{ocmd}{\And{#1}}#2\end{ocmd}}} +%}}} +%{{{ TikZ " +%{{{ +\newcommand{\ocgtikzrbtn}[6]{ + \node[#4,show ocg={#2}](#5){#6}; + \begin{ocg}[radiobtngrp=#1]{#2}{#2}{#3} + \node[#4,thick](#5){\textbf{#6}}; + \end{ocg} +} +%}}} +%{{{ alternative node/path " +\newcommand{\ocgnodestyle}[5]{ + \begin{ocmd}{\Not{\Or{#1}}} + \node[#2]#4{#5}; + \end{ocmd} + \begin{ocg}{#1}{#1}{0} + \node[#2,#3]#4{#5}; + \end{ocg} +} + +\newcommand{\ocgpathstyle}[4]{ + \begin{ocmd}{\Not{\Or{#1}}} + \path[#2] #4; + \end{ocmd} + \begin{ocg}{#1}{#1}{0} + \path[#2,#3] #4; + \end{ocg} +} +%}}} +%{{{ itemize " +\newcommand{\ocgitemize}[3]{ + \node#1{ + \begin{minipage}{#2} + \begin{itemize} + #3 + \end{itemize} + \end{minipage} + }; +} + +\newcommand{\ocgitem}[2]{ + \begin{ocmd}{\Or{#1}} + \item#2 + \end{ocmd} +} +%}}} +%{{{ makeprefix " +\newcommand*{\ocgmakeprefixes}[1]{% + \StrSubstitute{#1}{/}{-}[\clid]% + \edef\ocgprefix{fig-\clid}% + \edef\prefix{\ocgprefix-vars}% + \edef\prefixI{\ocgprefix-var1}% + \edef\prefixII{\ocgprefix-var2}% +} +%}}} +%{{{ dynamic figure (1 dimension) " +\newcommand{\ocgfigI}[5]{% + % #1 chapter-local path ; #2 caption ; + % #3 label I ; #4 var I ; #5 list I + \ocgmakeprefixes{#1}% + \def\listI{#5}% + + \centering + \foreach #4/\ignI in \listI {% + \ocmdcase{\prefixI-#4}{% + \input{src/fig/\chapterdir/#1}% + }% + }% + \caption{#2} + \label{fig:\chapterdir/#1} + {% + \small $\triangleright$ + #3% + \foreach \I/\state in \listI {% + \ocgradio{\prefixI}{\prefixI-\I}{\I}{\state}% + }% + }\\ +} +%}}} +%{{{ dynamic figure (2 dimensions) " +\newcommand{\ocgfigII}[8]{% + % #1 chapter-local path ; #2 caption ; + % #3 label I ; #4 var I ; #5 list I ; + % #3 label II ; #4 var II ; #5 list II + \ocgmakeprefixes{#1}% + \def\listI{#5}% + \def\listII{#8}% + + \centering + \foreach #4/\ignI in \listI {% + \foreach #7/\ignII in \listII {% + \ocmdcase{\prefixI-#4,\prefixII-#7}{% + \input{src/fig/\chapterdir/#1}% + }% + }% + }% + \caption{#2} + \label{fig:\chapterdir/#1} + {% + \small $\triangleright$ + #3% + \foreach \I/\state in \listI {% + \ocgradio{\prefixI}{\prefixI-\I}{\I}{\state}% + }% + #6% + \foreach \II/\state in \listII {% + \ocgradio{\prefixII}{\prefixII-\II}{\II}{\state}% + }% + }\\ +} +%}}} +%{{{ dynamic figure (2 bound dimensions) " +\newcommand{\ocgfigIB}[6]{% + % #1 chapter-local path ; #2 caption ; + % #3 label I/II ; #4 var I ; #5 var II ; #6 list I/II + \ocgmakeprefixes{#1}% + \def\list{#6}% + + \centering + \foreach #4/#5/\ign in \list {% + \ocmdcase{\prefix-#4-#5}{% + \input{src/fig/\chapterdir/#1}% + }% + }% + \caption{#2} + \label{fig:\chapterdir/#1} + {% + \small $\triangleright$ + #3% + \foreach \I/\II/\state in \list {% + \ocgradio{\prefix}{\prefix-\I-\II}{\I/\II}{\state}% + }% + }\\ +} +%}}} +%{{{ dynamic figure (1 dimension with remember picture) " +%{{{ ocgfigRPbuttons " +\newcommand{\ocgfigRPbuttons}[4]{% + \def\listI{#2}% + \foreach #1/\state in \listI {% + \foreach \position in {#4} {% + \tikz[remember picture,overlay]{\node[#3,trigger ocg=onmouseall,% + show ocg={{\prefixI-#1},,,{\prefixI-#1}}] at (\position) {};}% + }% + }% +} +%}}} +\newcommand{\ocgfigRP}[7]{% + % #1 local path (tikz rp) ; #2 local path ; + % #3 var I ; #4 list I ; + % #5 node style ; #6 node positions ; + % #7 OCG layer + \ocgmakeprefixes{#2}% + \def\listI{#4}% + \begin{ocg}{#7}{\prefixI}{on}% + \makebox[0pt][c]{\begin{ocg}{Boutons}{.buttons}{on}\input{src/fig/#1}\end{ocg}}% + \foreach #3/\state in \listI {% + \ocgcase{\prefixI}{#7 (#3)}{\prefixI-#3}{\state}{% + \input{src/fig/#2}% + }% + }% + \ocgfigRPbuttons{#3}{#4}{#5}{#6}% + \end{ocg} +} +%}}} +%{{{ dynamic figure (1 dimension) with includegraphics " +%{{{ ocgfigIGbuttons " +\newcommand{\ocgfigIGbuttons}[4]{% + \def\listI{#1}% + \vspace{#3}\hspace{#4}% + {% + \small $\triangleright$ + #2% + \foreach \I/\state in \listI {% + \ocgradio{\prefixI}{\prefixI-\I}{\I}{\state}% + }% + }% +} +%}}} +\newcommand{\ocgfigIG}[8]{% + % #1 chapter-local path ; #2 fn pre ; #3 fn post ; + % #4 label I ; #5 var I ; #6 list I ; + % #7 OCG layer ; #8 hspace ; + % #9 btn vspace ; #10 btn hspace + \ocgmakeprefixes{#1}% + \def\listI{#6}% + \begin{ocg}{#7}{\prefixI}{on}% + \foreach #5/\ignI in \listI {% + \ocmdcase{\prefixI-#5}{% + \hspace{#8}\includegraphics{img/#1/#2#5#3}% + }% + }% + \end{ocg} + + \ocgfigIGbuttons{#6}{#4} +} +%}}} +%}}} +%{{{ Specific for chapter par " +\newcommand*{\ocgpdfonly}[1]{% +\begin{ocg}[printocg=never,exportocg=never]{}{}{1} +#1 +\end{ocg} +} + +\newcommand{\ocgalt}[4]{% +\makebox[0pt][l]{% +\begin{ocg}[printocg=never,exportocg=never]{#1 (alt)}{#2-alt}{0} +#4 +\end{ocg} +} +\begin{ocg}[printocg=always,exportocg=always]{#1}{#2}{1} +#3 +\end{ocg} +} + +\newcommand{\ocgtikzalt}[4][n]{% +\ifstrequal{#1}{n} +{\def\status{visible}\def\altstatus{invisible}} +{\def\status{invisible}\def\altstatus{visible}} +\begin{scope}[ocg={ref=#2,status=\status}] +#3 +\end{scope} +\begin{scope}[ocg={ref=#2-alt,status=\altstatus}] +#4 +\end{scope} +} + +\newcommand*{\switchocgalt}[2]{\switchocg{#1 #1-alt}{#2}} + +\newcommand*{\ocgtogglestaticdynamic}[1]{% +\ocgpdfonly{% +\switchocgalt{#1}{% +\small $\triangleright$ basculer entre la version statique et la version dynamique +} +} +} +%}}} diff --git a/src/usr/silence.tex b/src/usr/silence.tex new file mode 100644 index 0000000..a46db3d --- /dev/null +++ b/src/usr/silence.tex @@ -0,0 +1,5 @@ +\makeatletter +\renewcommand{\PackageInfo}[2]{}% Remove package information +\renewcommand{\@font@info}[1]{}% Remove font information +\renewcommand{\@latex@info}[1]{}% Remove LaTeX information +\makeatother diff --git a/src/usr/tikz.tex b/src/usr/tikz.tex new file mode 100644 index 0000000..e00e89b --- /dev/null +++ b/src/usr/tikz.tex @@ -0,0 +1,3 @@ +\makeatletter +\newcommand\curcoord{\the\tikz@lastxsaved,\the\tikz@lastysaved} +\makeatother diff --git a/sty/acref.sty b/sty/acref.sty new file mode 100644 index 0000000..5260ab6 --- /dev/null +++ b/sty/acref.sty @@ -0,0 +1,132 @@ +\ProvidesPackage{sty/acref} + +\RequirePackage{etoolbox} +\RequirePackage{listofitems} + +%{{{ +\def\acref@instring#1#2{TT\fi\begingroup + \edef\x{\endgroup\noexpand\in@{#1}{#2}}\x\ifin@} +%}}} + +%{{{ cleveref bindings " +\def\acref@cleveref@getname#1#2{\csname #1@#2@name\endcsname} +%}}} + +%{{{ acref " +\let\acref@cref\cref +\renewcommand*{\cref}[1]{\begin{otherlanguage}{english}\acref@cref{#1}\end{otherlanguage}\xspace} + +\newcommand*{\acref@error@article}[2]{% + \PackageError{acref}{undefined article for '#1' (type: '#2', page: \thepage) (possible solution is to add: + \string\acrefarticle{#2}{}{})}{}% +} + +\newcommand*{\acref@error@type}[2]{% + \PackageError{acref}{undefined type for '#1' (type: '#2', page: \thepage) (require changes in + package in \string\acref@article and \string\acref@Article: add + \string\acref@printarticle{\#1}{#2}{\string\acref@art@#2}}{} +} + +\newcommand*{\acref@warning@prefix}[1]{% + \ClassWarning{acref}{Reference '#1' on page \thepage\space has unknown prefix}% +} + +\newcommand*{\acref@printarticle}[3]{\expandafter\ifstrequal\expandafter{#1}{#2}{% + \csname acref@#3@#2\endcsname\def\acref@article@isset{1}}{}% +} + +\newcommand*{\acref@prefixtotype}[1]{\csname acref@prefix@#1\endcsname} +\newcommand*{\acref@crefname}[1]{\acref@cleveref@getname{cref}{#1}} + +\newcommand*{\acref@article}[2]{% + \acref@printarticle{#1}{algorithm}{#2}% + \acref@printarticle{#1}{chapter}{#2}% + \acref@printarticle{#1}{enumi}{#2}% + \acref@printarticle{#1}{equation}{#2}% + \acref@printarticle{#1}{figure}{#2}% + \acref@printarticle{#1}{listing}{#2}% + \acref@printarticle{#1}{section}{#2}% + \acref@printarticle{#1}{subfigure}{#2}% + \acref@printarticle{#1}{subsection}{#2}% + \acref@printarticle{#1}{subsubsection}{#2}% + \acref@printarticle{#1}{table}{#2}% + \acref@printarticle{#1}{theorem}{#2}% + \acref@printarticle{#1}{plural}{#2}% +} + +\newcommand*{\acref@acref}[2]{% + \if\acref@instring{,}{#1}% + \acref@article{plural}{#2}% + \else + \begin{otherlanguage}{english} + \ifcsname r@#1@cref\endcsname + \cref@gettype{#1}{\acref@type}% + \ifcsname acref@art@\acref@type\endcsname + \def\acref@article@isset{}% + \acref@article{\acref@type}{#2}% + \expandafter\ifstrequal\expandafter{\acref@article@isset}{1}{}{\acref@error@type{#1}{\acref@type}}% + \else + \acref@error@article{#1}{\acref@type} + \fi + \else + {% invalid reference + \setsepchar{:}% + \edef\@arg{#1}% + \readlist*\@tmp{\@arg}% + \edef\@prefix{\@tmp[1]}% + \ifcsname acref@prefix@\@prefix\endcsname + \edef\acref@type{\acref@prefixtotype{\@prefix}}% + \acref@article{\acref@type}{#2}% + \acref@crefname{\acref@type}% + \else + \textbf{\@prefix}% + \acref@warning@prefix{#1}% + \fi + } + \fi + \end{otherlanguage} + \fi + \cref{#1}% +} + +\newcommand*{\acrefarticle}[3]{% + \expandafter\def\csname acref@art@#1\endcsname{#2} + \expandafter\def\csname acref@Art@#1\endcsname{#3} +} + +\newcommand*{\acrefprefix}[2]{% + \expandafter\def\csname acref@prefix@#1\endcsname{#2} +} + +\newcommand*{\acref}[2][n]{\acref@acref{#2}{art}} +\newcommand*{\Acref}[2][n]{\acref@acref{#2}{Art}} +%}}} + +%{{{ " default configuration +\acrefarticle{algorithm}{l'}{L'} +\acrefarticle{chapter}{le }{Le } +\acrefarticle{enumi}{le }{Le } +\acrefarticle{equation}{l'}{L'} +\acrefarticle{figure}{la }{La } +\acrefarticle{listing}{la }{La } +\acrefarticle{section}{la }{La } +\acrefarticle{subfigure}{la }{La } +\acrefarticle{subsection}{la }{La } +\acrefarticle{subsubsection}{la }{La } +\acrefarticle{table}{le }{Le } +\acrefarticle{theorem}{le }{Le } + +\acrefarticle{plural}{les }{Les } + +\acrefprefix{alg}{algorithm} +\acrefprefix{ch}{chapter} +\acrefprefix{enumi}{enumi} +\acrefprefix{eq}{equation} +\acrefprefix{fig}{figure} +\acrefprefix{lst}{listing} +\acrefprefix{sec}{section} +\acrefprefix{subsec}{subsection} +\acrefprefix{subsubsec}{subsubsection} +\acrefprefix{tab}{table} +\acrefprefix{th}{theorem} +%}}}