Parallel Programming with OCaml: A Tutorial Victor Allombert, Mathias Bourgoin, Frédéric Loulergue To cite this version: Victor Allombert, Mathias Bourgoin, Frédéric Loulergue. Parallel Programming with OCaml: A Tutorial. International Conference on High Performance Computing and Simulation (HPCS 2018), Jul 2018, Orléans, France. hal-01941231 HAL Id: hal-01941231 https://hal.archives-ouvertes.fr/hal-01941231 Submitted on 30 Nov 2018 HAL is a multi-disciplinary open access L’archive ouverte pluridisciplinaire HAL, est archive for the deposit and dissemination of sci- destinée au dépôt et à la diffusion de documents entific research documents, whether they are pub- scientifiques de niveau recherche, publiés ou non, lished or not. The documents may come from émanant des établissements d’enseignement et de teaching and research institutions in France or recherche français ou étrangers, des laboratoires abroad, or from public or private research centers. publics ou privés. Parallel Programming with OCaml: A Tutorial Victor Allombert Mathias Bourgoin Fred´ eric´ Loulergue Univ Orleans, INSA Centre Val-de-Loire, Univ Orleans, INSA Centre Val-de-Loire, SICCS LIFO EA 4022 LIFO EA 4022 Northern Arizona University Orleans,´ France Orleans,´ France Flagstaf, USA [email protected] [email protected] [email protected] INVITED TUTORIAL PAPER Abstract—OCaml is a multi-paradigm (functional, imperative, I. AN OVERVIEW OF OCAML object-oriented) high level sequential language. Types are stati- cally inferred by the compiler and the type system is expressive In this section we describe the OCaml language and the and strong. These features make OCaml a very productive features of the OCaml library that are necessary for a good language for developing efficient and safe programs. In this understanding of this tutorial. tutorial we present three frameworks for using OCaml to program scalable parallel architectures: BSML, Multi-ML and A. What is OCaml? Spoc. OCaml [3] is a functional programming language [4] from Keywords— Parallel programming; functional programming; the ML (Meta Language) family. It is the main implementation bulk synchronous parallelism; Multi-BSP; GPGPU of Caml, a general-purposes language developed at Inria. As parallel architectures are now the norm, it is necessary OCaml relies on a powerful static type system allowing type to consider programming languages and libraries that offer a inference, as well as parametric and generalized algebraic data trade-off between execution efficiency and programming pro- types polymorphism. It also proposes a system of modules ductivity. While languages and libraries for high performance and an object oriented approach. The code generated by the computing, such as MPI [1], favor efficiency over productivity, compiler is thus safe, thanks to the type checker. a lot of application domains require that mainstream program- The OCaml language offers a bytecode compiler to allow mers develop parallel applications without huge knowledge code portability on various architectures. The quality of the about parallel programming. native compilation allows performances close to the highest standards of modern compilers. OCaml also provides auto- Big Data is an area where productivity is also considered matic memory management thanks to its embedded garbage as important. MapReduce [2] is a well-known programming collector. A toplevel that permits interactive use of OCaml model where it is only possible to express a parallel through and interactive loop is also available. algorithm in a very structured and specific way. The creators OCaml is supported by a widespread community and has a of MapReduce indicate functional programming as an rich set of libraries and development tools [5], [6] inspiration for their framework. Moreover, there is a recent trend to include functional features in mainstream languages, B. Introduction to the OCaml Syntax such as Java or C++. As OCaml provides type inference, it is not necessary to This tutorial is an introduction to parallel programming specify the type of a variable. Variables are defined using let using a modern functional programming language: OCaml, a let-bindings. For example, x = 1 declares that x is a statically and strongly typed language, with a type inference variable of type int with the value of 1. Although unneces- system. This allows detecting errors very early in the develop- sary, it is possible to annotate an expression with a type, so let ment of applications. OCaml offers high-level features yet it x : int = 1 is valid too. We use type annotations in is efficient. While the style of an OCaml application is mainly the next sections as types provide valuable information to the functional, OCaml is a multi paradigm language: it provides reader. imperative and object-oriented features that can be used for To declare a function in OCaml it is also possible to use efficiency or modularity reasons. a let-binding as following: let prod x y = x *. y. Here, we define the function prod which takes two arguments (x and The three presented frameworks leverage OCaml for scal- y) and returns the product of them. Notice the usage of the *. able parallel programming of homogeneous clusters (Sec- operator which stands for floating point addition. The usage tion II), hierarchical architectures (Section III), and GPUs of this operators forces the types of x and y to be float. The (Section IV). We use, as a running example, a parallel map prod function is typed prod:float → float → float and reduce implementations on distributed lists or distributed as it takes as argument two floats and returns a float. The arrays. We begin with a short presentation of OCaml in application of the function prod can be written as follows: Section I and discuss further reading in Section V. f 1.0 2.0. When there is no type constraints on values, the type ● hd::tl a list composed of the head element hd and the system generates forall types. For example, let f x = x is tail tl (the rest of the list). In this case, we return the a function taking an argument x and returning the exact same result of the application of f on h concatenated with the value. Here, the f can be applied on any value of x. Thus, it result of the recursive call on the tail. → is typed f : α α where α stands for any types. It is also possible to define arrays in OCaml as follows: Because of its functional capabilities, high-order functions let a = [|1;2;3|]. Thus, a is typed int array. Unlike are common in OCaml programs. For example, we can write a lists, arrays are mutable data structures. Updating the cell at square function as following: let square x = prod x x. index i of an array a with a value v is written a.(i)←v. Anonymous function are also often used and are identi- In OCaml, it is simple to define its own types using records. fied by the fun keyword. Thus, the following code al- A record is a data structure holding multiple values. For lows the definition of the square function using anony- example, the definition of a point of a Cartesian coordinate mous function instead of using the prod function: system can be written: let square x = (fun x y → x *. y) x x. Lists are one of the most common data structure used in the type point = { context of functional programming. In Ocaml, a list is imple- name : string; mented as an immutable singly linked list. A list of integers x : float; y : float; let l1 = [1;2;3] in OCaml can be defined as following: . } The type of the l1 is int list. The brackets delimits the list and elements are separated with the semicolon. The Here, the record point is made of three fields: the name empty list is written [] and the concatenation of two lists of the point and the x and y coordinates. An instance of is written l1 @ [4;5;6]. The infix operator :: adds an a point is written: let a = {name="A";x=3.0;y=5.0}. elements at the beginning of a list. Therefore l1 can also Records can have mutable fields that can be set using the be written 1::2::3::[]. Actually [] and :: are the two list ← operator. For example, annotating the field x as follows constructors, i.e. any list value can be described in terms of mutable x : float allows one to write a.x←4.0. this constant and this operation. The definition of recursive functions using the let-binding must be annotated by the rec keyword. For example, we can C. Some Features of OCaml Libraries write a (non tail-)recursive function that builds a list containing To manipulate common data structures such as lists or arrays the values from n1 to n2 as follows: it is possible to use the List and Array modules from the let rec from_to n1 n2 = standard library. if n1>n2 map then [] Regarding lists, the function is very useful to else n1::(from_to (n1+1) n2) apply a function on each element of a list. List.map is typed map : (α→β)→α list→β list. The code This function returns [] if the lower bound is greater than List.map f l applies function f on each elements of the upper bound. Otherwise, it returns the value of n1 con- the list l. Thus, List.map (fun x → x*x) [0;1;2;3] catenated with the recursive call of from_to on n1+1 and n2 produces list [0;1;4;9]. using the operator ::. Folding on lists is a common operation that can be done Pattern matching is a powerfully control structure used using List.fold_left : (α→β→α)→α→β list→α. to match values or expressions (patterns) to computations.
Details
-
File Typepdf
-
Upload Time-
-
Content LanguagesEnglish
-
Upload UserAnonymous/Not logged-in
-
File Pages10 Page
-
File Size-