[Pkg-ocaml-maint-commits] [parmap] 01/06: Imported Upstream version 1.0~rc7

Mehdi Dogguy mehdi at moszumanska.debian.org
Sun Jan 17 23:51:32 UTC 2016


This is an automated email from the git hooks/post-receive script.

mehdi pushed a commit to branch master
in repository parmap.

commit b288fed1d6f9f2016896fecec327fd996d2752cc
Author: Mehdi Dogguy <mehdi at debian.org>
Date:   Mon Jan 18 00:42:09 2016 +0100

    Imported Upstream version 1.0~rc7
---
 Makefile.in          |   8 ++--
 README.md            | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++
 _tags                |   1 +
 configure            |  89 ++++++++++++++++++++++----------------
 configure.ac         |   5 +--
 example/Makefile.OSX |  20 +++++++++
 m4/ocaml.m4          | 105 ++++++++++++++++++++++++--------------------
 parmap.ml            |  32 +++++++-------
 parmap.mli           |   8 ++++
 setcore_stubs.c      |   3 +-
 10 files changed, 285 insertions(+), 106 deletions(-)

diff --git a/Makefile.in b/Makefile.in
index 7ae9cfd..6c0ee0b 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -46,11 +46,13 @@ CMXSLIBS=
 ALIBS=
 
 ifeq ("@OCAMLBEST@","opt")
+  ALIBS = $(BYTELIBS:%.cma=%.a)
   OPTLIBS += $(BYTELIBS:%.cma=%.cmxa)
-  CMXSLIBS += $(BYTELIBS:%.cma=%.cmxs)
 endif
 
-ALIBS = $(BYTELIBS:%.cma=%.a)
+ifeq ("@OCAMLNATDYNLINK@", "yes")
+  CMXSLIBS += $(BYTELIBS:%.cma=%.cmxs)
+endif
 
 all:
 	$(OCAMLBUILD) $(OBFLAGS) $(BYTELIBS) $(OPTLIBS) $(CMXSLIBS) $(ALIBS)
@@ -86,7 +88,7 @@ install: $(LIBS) META
 	$(INSTALL) -patch-version $(VERSION) $(NAME) $(INSTALL_STUFF)
 	(cd _build; ocamldoc -man -man-mini parmap.ml parmap.mli)
 	test -d $(MANDIR) || mkdir -p $(MANDIR)
-	cp -a _build/Parmap.3o $(MANDIR)
+	cp -p _build/Parmap.3o $(MANDIR)
 
 uninstall:
 	$(UNINSTALL) $(NAME)
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..fc74a9f
--- /dev/null
+++ b/README.md
@@ -0,0 +1,120 @@
+# Parmap in a nutshell
+
+Parmap is a minimalistic library allowing  to exploit multicore architecture for
+OCaml programs with minimal modifications: if you want to use your many cores to
+accelerate an   operation  which  happens   to be   a  map,  fold    or map/fold
+(map-reduce),  just use  Parmap's  `parmap`, `parfold`  and `parmapfold` primitives in
+place  of the standard   `List.map`   and friends,  and  specify  the  number   of
+subprocesses to use by the optional parameter `~ncores`.
+
+See the `example` directory for a couple of running programs.
+
+## DO'S and DONT'S
+
+Parmap is *not*  meant to be a replacement  for a full fledged implementation of
+parallelism skeletons  (map, reduce, pipe, and the  many others described in the
+scientific literature   since the end   of the  1980's,   much earlier  than the
+specific   implementation by Google   engineers  that popularised them).  It  is
+meant,  instead, to allow you to  quickly leverage the  idle processing power of
+your extra cores, when handling some heavy computational load.
+
+The principle of parmap is very simple: when you call one of the three available
+primitives, map, fold, and  mapfold , your OCaml  sequential program forks  in n
+subprocesses (you choose the n), and each subprocess performs the computation on
+the 1/n of the data, in chunks  of a size you  can choose, returning the results
+through a shared memory area to the  parent process, that resumes execution once
+all the children have terminated, and the data has been recollected.
+
+You *need*  to run your  program *on a single multicore  machine*;  repeat after me:
+`Parmap`  _is   not meant_ to   run  on a cluster,  see   one of the  many available
+(re)implementations of the map-reduce schema for that.
+
+By forking the parent process  on a sigle  machine, the children get access, for
+free, to all the data structures already built, even the imperative ones, and as
+far as your computation  inside the map/fold  does not produce side effects that
+need  to be  preserved, the  final result will   be the same  as  performing the
+sequential operation, the only difference is that you might get it faster.
+
+The OCaml  code is reasonably  simple and  only marginally relies  on external C
+libraries: most of the magic is done by your operating  system's fork and memory
+mapping   mechanisms.    One    could gain  some      speed  by implementing   a
+marshal/unmarshal operation directly on bigarrays, but we did not do this yet.
+
+Of course, if you happen  to have open  channels, or files, or other connections
+that should only be  used by the parent  process, your program  may behave in  a
+very wierd way: as an example, *do  not* open a  graphic window before calling a
+Parmap primitive, and   *do   not*  use  this  library   if  your  program    is
+multi-threaded!
+
+## Pinning processes to physical CPUs
+
+To obtain maximum  speed,  Parmap tries to  pin  the worker processes to  a CPU,
+using  the scheduler  affinity  interface  that is  available   in recent  Linux
+kernels.   Similar functionality may be  obtained  on different platforms  using
+slightly different API. Contributions  are welcome to  support those other APIs,
+just make sure that you use autoconf properly.
+
+## Using Parmap with Ocamlnat
+
+You can use Parmap in a native toplevel  (it may be quite useful  if you use the
+native toplevel to perform fast interactive computations), but remember that you
+need to load the `.cmxs` modules in it; an example is given in `example/topnat.ml`
+
+## Preservation of output order in Parmap
+
+If the number of chunks is equal to the number of cores, it is easy to preserve
+the order of the elements of the sequence passed to the map/fold operations, so
+the result will be a list with the same order as if the sequential function would
+be applied to the input. This is what the `parmap`, `parmafold` and `parfold` functions
+do when the chunksize argument is not used.
+
+If the user specifies a chunksize that is different from the number of cores,
+there is no general way to preserve the ordering, so the result of calling
+`Parmap.parmap f l` are not necessarily in the same order as `List.map f l`.
+
+In general, using little chunksize helps in balancing the load among the workers,
+and provides better speed, at the price of losing the ordering: there is a
+tradeoff, and it is up to the user to choose the solution that better suits him/her.
+
+## Fast map on arrays and on float arrays
+
+Visiting an array is much faster than visiting a list, and conversion of an array
+to and from a list is expensive, on large data structures, so we provide a specialised
+version of map on arrays, that beaves exactly like parmap.
+
+We also provide a highly optimised specialised parmap version that is targeted
+to float arrays, `array_float_parmap`, that allows you to perform parallel
+computation on very large float arrays efficiently, without the boxing/unboxing
+overhead introduced by the other primitives, including `array_parmap`.
+
+To understand the efficiency issues involved in the case of large arrays of float,
+here is a short summary of the steps that any implementation of a parallel map
+function must perform.
+
+ 1. create a float array to hold the result of the computation.
+    This operation is expensive: on an Intel i7, creating a 10M float array
+    takes 50 milliseconds
+    ```ocaml
+        ocamlnat
+             Objective Caml version 3.12.0 - native toplevel
+
+        # #load "unix.cmxs";;
+        # let d = Unix.gettimeofday() in ignore(Array.create 10000000 0.); Unix.gettimeofday() -. d;;
+        - : float = 0.0501301288604736328
+    ```
+ 2. create a shared memory area 
+
+ 3. possibly copy the result array to the shared memory area
+
+ 4. perform the computation in the children writing the result in the shared memory area
+
+ 5. possibly copy the result back to the OCaml array
+
+All implementations need to do 1, 2 and 4; steps 3 and/or 5 may be omitted depending on
+what the user wants to do with the result.
+
+The `array_float_parmap` performs steps 1, 2, 4 and 5. It is possible to share steps
+1 and 2 among subsequent calls to the parallel function by preallocating the result
+array and the shared memory buffer, and passing them as optional parameters to the
+`array_float_parmap` function: this may save a significant amount of time if the
+array is very large.
\ No newline at end of file
diff --git a/_tags b/_tags
index 1e44c0a..432bf06 100644
--- a/_tags
+++ b/_tags
@@ -6,3 +6,4 @@
 
 
 <*sdl.*>: package(bigarray), package(sdl)
+<*.{ml,mli}>: warn(Ae)
diff --git a/configure b/configure
index f3e682e..25ffda4 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for parmap 1.0-rc3.
+# Generated by GNU Autoconf 2.69 for parmap 1.0-rc7.
 #
 # Report bugs to <roberto at dicosmo.org>.
 #
@@ -580,8 +580,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='parmap'
 PACKAGE_TARNAME='parmap'
-PACKAGE_VERSION='1.0-rc3'
-PACKAGE_STRING='parmap 1.0-rc3'
+PACKAGE_VERSION='1.0-rc7'
+PACKAGE_STRING='parmap 1.0-rc7'
 PACKAGE_BUGREPORT='roberto at dicosmo.org'
 PACKAGE_URL=''
 
@@ -640,6 +640,7 @@ OCAMLMKLIB
 OCAMLMKTOP
 OCAMLDEP
 OCAML
+OCAMLNATDYNLINK
 OCAMLOPTDOTOPT
 OCAMLCDOTOPT
 OCAMLBEST
@@ -1238,7 +1239,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures parmap 1.0-rc3 to adapt to many kinds of systems.
+\`configure' configures parmap 1.0-rc7 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1299,7 +1300,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of parmap 1.0-rc3:";;
+     short | recursive ) echo "Configuration of parmap 1.0-rc7:";;
    esac
   cat <<\_ACEOF
 
@@ -1379,7 +1380,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-parmap configure 1.0-rc3
+parmap configure 1.0-rc7
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1681,7 +1682,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by parmap $as_me 1.0-rc3, which was
+It was created by parmap $as_me 1.0-rc7, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2130,7 +2131,7 @@ fi
 $as_echo "OCaml version is $OCAMLVERSION" >&6; }
      # If OCAMLLIB is set, use it
      if test "$OCAMLLIB" = ""; then
-        OCAMLLIB=`$OCAMLC -where 2>/dev/null || $OCAMLC -v|tail -1|cut -d ' ' -f 4`
+        OCAMLLIB=`$OCAMLC -where 2>/dev/null | tr -d '\015' || $OCAMLC -v|tail -1|cut -d ' ' -f 4`
      else
         { $as_echo "$as_me:${as_lineno-$LINENO}: result: OCAMLLIB previously set; preserving it." >&5
 $as_echo "OCAMLLIB previously set; preserving it." >&6; }
@@ -2236,17 +2237,17 @@ fi
 
      OCAMLBEST=byte
      if test "$OCAMLOPT" = "no"; then
-	{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Cannot find ocamlopt; bytecode compilation only." >&5
+        { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Cannot find ocamlopt; bytecode compilation only." >&5
 $as_echo "$as_me: WARNING: Cannot find ocamlopt; bytecode compilation only." >&2;}
      else
-	TMPVERSION=`$OCAMLOPT -v | sed -n -e 's|.*version* *\(.*\)$|\1|p' `
-	if test "$TMPVERSION" != "$OCAMLVERSION" ; then
-	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: versions differs from ocamlc; ocamlopt discarded." >&5
+        TMPVERSION=`$OCAMLOPT -v | sed -n -e 's|.*version* *\(.*\)$|\1|p' `
+        if test "$TMPVERSION" != "$OCAMLVERSION" ; then
+           { $as_echo "$as_me:${as_lineno-$LINENO}: result: versions differs from ocamlc; ocamlopt discarded." >&5
 $as_echo "versions differs from ocamlc; ocamlopt discarded." >&6; }
-	    OCAMLOPT=no
-	else
-	    OCAMLBEST=opt
-	fi
+           OCAMLOPT=no
+        else
+           OCAMLBEST=opt
+        fi
      fi
 
 
@@ -2345,18 +2346,18 @@ else
 fi
 
      if test "$OCAMLCDOTOPT" != "no"; then
-	TMPVERSION=`$OCAMLCDOTOPT -v | sed -n -e 's|.*version* *\(.*\)$|\1|p' `
-	if test "$TMPVERSION" != "$OCAMLVERSION" ; then
-	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: versions differs from ocamlc; ocamlc.opt discarded." >&5
+        TMPVERSION=`$OCAMLCDOTOPT -v | sed -n -e 's|.*version* *\(.*\)$|\1|p' `
+        if test "$TMPVERSION" != "$OCAMLVERSION" ; then
+           { $as_echo "$as_me:${as_lineno-$LINENO}: result: versions differs from ocamlc; ocamlc.opt discarded." >&5
 $as_echo "versions differs from ocamlc; ocamlc.opt discarded." >&6; }
-	else
-	    OCAMLC=$OCAMLCDOTOPT
-	fi
+        else
+           OCAMLC=$OCAMLCDOTOPT
+        fi
      fi
 
      # checking for ocamlopt.opt
      if test "$OCAMLOPT" != "no" ; then
-	if test -n "$ac_tool_prefix"; then
+        if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}ocamlopt.opt", so it can be a program name with args.
 set dummy ${ac_tool_prefix}ocamlopt.opt; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
@@ -2448,15 +2449,15 @@ else
   OCAMLOPTDOTOPT="$ac_cv_prog_OCAMLOPTDOTOPT"
 fi
 
-	if test "$OCAMLOPTDOTOPT" != "no"; then
-	   TMPVERSION=`$OCAMLOPTDOTOPT -v | sed -n -e 's|.*version* *\(.*\)$|\1|p' `
-	   if test "$TMPVERSION" != "$OCAMLVERSION" ; then
-	      { $as_echo "$as_me:${as_lineno-$LINENO}: result: version differs from ocamlc; ocamlopt.opt discarded." >&5
+        if test "$OCAMLOPTDOTOPT" != "no"; then
+           TMPVERSION=`$OCAMLOPTDOTOPT -v | sed -n -e 's|.*version* *\(.*\)$|\1|p' `
+           if test "$TMPVERSION" != "$OCAMLVERSION" ; then
+              { $as_echo "$as_me:${as_lineno-$LINENO}: result: version differs from ocamlc; ocamlopt.opt discarded." >&5
 $as_echo "version differs from ocamlc; ocamlopt.opt discarded." >&6; }
-	   else
-	      OCAMLOPT=$OCAMLOPTDOTOPT
-	   fi
-        fi
+           else
+              OCAMLOPT=$OCAMLOPTDOTOPT
+           fi
+       fi
      fi
 
 
@@ -2464,6 +2465,21 @@ $as_echo "version differs from ocamlc; ocamlopt.opt discarded." >&6; }
 
 
 
+  # checking for native dynlink
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dynlink.cmxa" >&5
+$as_echo_n "checking for dynlink.cmxa... " >&6; }
+  if test -f "$OCAMLLIB/dynlink.cmxa" ; then
+     OCAMLNATDYNLINK=yes
+     { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+  else
+     OCAMLNATDYNLINK=no
+     { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+  fi
+
+
+
   # checking for ocaml toplevel
   if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}ocaml", so it can be a program name with args.
@@ -4379,8 +4395,7 @@ _ACEOF
 ac_config_headers="$ac_config_headers config.h"
 
 
-t=`$OCAMLBUILD -use-ocamlfind &> /dev/null; echo $?`
-if test $t == 0 ; then
+if $OCAMLBUILD -use-ocamlfind >/dev/null 2>&1 ; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: ocaml version $OCAMLVERSION. Use standard Makefile" >&5
 $as_echo "ocaml version $OCAMLVERSION. Use standard Makefile" >&6; }
   ac_config_files="$ac_config_files Makefile"
@@ -4891,7 +4906,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by parmap $as_me 1.0-rc3, which was
+This file was extended by parmap $as_me 1.0-rc7, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -4953,7 +4968,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-parmap config.status 1.0-rc3
+parmap config.status 1.0-rc7
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
@@ -6168,7 +6183,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by parmap $as_me 1.0-rc3, which was
+This file was extended by parmap $as_me 1.0-rc7, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -6230,7 +6245,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-parmap config.status 1.0-rc3
+parmap config.status 1.0-rc7
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
diff --git a/configure.ac b/configure.ac
index 1af0fb5..d0ee512 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-AC_INIT(parmap, 1.0-rc4, roberto at dicosmo.org)
+AC_INIT(parmap, 1.0-rc7, roberto at dicosmo.org)
 
 AC_PROG_OCAML
 if test "$OCAMLC" = "no"; then
@@ -26,8 +26,7 @@ AC_CHECK_DECLS([thread_policy_set], [], [], [[
 
 AC_CONFIG_HEADERS([config.h])
 
-t=`$OCAMLBUILD -use-ocamlfind &> /dev/null; echo $?`
-if test $t == 0 ; then
+if $OCAMLBUILD -use-ocamlfind >/dev/null 2>&1 ; then
   AC_MSG_RESULT(ocaml version $OCAMLVERSION. Use standard Makefile)
   AC_CONFIG_FILES([Makefile])
   AC_OUTPUT
diff --git a/example/Makefile.OSX b/example/Makefile.OSX
new file mode 100644
index 0000000..cc407b7
--- /dev/null
+++ b/example/Makefile.OSX
@@ -0,0 +1,20 @@
+# to build the sdl version, you will need at least the command line tools from Xcode, 
+# also, sdl. brew install sdl sdl_gfx sdl_image should be (more than) enough
+
+OCAMLBUILD=ocamlbuild
+OBFLAGS := -j 10 -use-ocamlfind
+OCAMLBEST=native
+
+TARGETS = \
+  mandels.$(OCAMLBEST)
+
+all:
+	$(OCAMLBUILD) $(OBFLAGS) $(TARGETS)
+
+mandels_sdl.native: mandels_sdl.ml
+	ocamlfind ocamlopt -ccopt "-framework CoreFoundation -framework Cocoa" -linkpkg -package bigarray -package graphics -package parmap -package unix -package sdl mandels_sdl.ml -o mandels_sdl.native
+
+.PHONY: clean
+clean:
+	$(OCAMLBUILD) -clean
+
diff --git a/m4/ocaml.m4 b/m4/ocaml.m4
index e0eec61..1d3b657 100644
--- a/m4/ocaml.m4
+++ b/m4/ocaml.m4
@@ -1,10 +1,11 @@
 dnl autoconf macros for OCaml
 dnl
-dnl Copyright � 2009      Richard W.M. Jones
-dnl Copyright � 2009      Stefano Zacchiroli
-dnl Copyright � 2000-2005 Olivier Andrieu
-dnl Copyright � 2000-2005 Jean-Christophe Filli�tre
-dnl Copyright � 2000-2005 Georges Mariano
+dnl Copyright © 2013      Gabriel Kerneis
+dnl Copyright © 2009      Richard W.M. Jones
+dnl Copyright © 2009      Stefano Zacchiroli
+dnl Copyright © 2000-2005 Olivier Andrieu
+dnl Copyright © 2000-2005 Jean-Christophe Filliâtre
+dnl Copyright © 2000-2005 Georges Mariano
 dnl
 dnl For documentation, please read the ocaml.m4 man page.
 
@@ -18,7 +19,7 @@ AC_DEFUN([AC_PROG_OCAML],
      AC_MSG_RESULT([OCaml version is $OCAMLVERSION])
      # If OCAMLLIB is set, use it
      if test "$OCAMLLIB" = ""; then
-        OCAMLLIB=`$OCAMLC -where 2>/dev/null || $OCAMLC -v|tail -1|cut -d ' ' -f 4`
+        OCAMLLIB=`$OCAMLC -where 2>/dev/null | tr -d '\015' || $OCAMLC -v|tail -1|cut -d ' ' -f 4`
      else
         AC_MSG_RESULT([OCAMLLIB previously set; preserving it.])
      fi
@@ -31,15 +32,15 @@ AC_DEFUN([AC_PROG_OCAML],
      AC_CHECK_TOOL([OCAMLOPT],[ocamlopt],[no])
      OCAMLBEST=byte
      if test "$OCAMLOPT" = "no"; then
-	AC_MSG_WARN([Cannot find ocamlopt; bytecode compilation only.])
+        AC_MSG_WARN([Cannot find ocamlopt; bytecode compilation only.])
      else
-	TMPVERSION=`$OCAMLOPT -v | sed -n -e 's|.*version* *\(.*\)$|\1|p' `
-	if test "$TMPVERSION" != "$OCAMLVERSION" ; then
-	    AC_MSG_RESULT([versions differs from ocamlc; ocamlopt discarded.])
-	    OCAMLOPT=no
-	else
-	    OCAMLBEST=opt
-	fi
+        TMPVERSION=`$OCAMLOPT -v | sed -n -e 's|.*version* *\(.*\)$|\1|p' `
+        if test "$TMPVERSION" != "$OCAMLVERSION" ; then
+           AC_MSG_RESULT([versions differs from ocamlc; ocamlopt discarded.])
+           OCAMLOPT=no
+        else
+           OCAMLBEST=opt
+        fi
      fi
 
      AC_SUBST([OCAMLBEST])
@@ -47,25 +48,25 @@ AC_DEFUN([AC_PROG_OCAML],
      # checking for ocamlc.opt
      AC_CHECK_TOOL([OCAMLCDOTOPT],[ocamlc.opt],[no])
      if test "$OCAMLCDOTOPT" != "no"; then
-	TMPVERSION=`$OCAMLCDOTOPT -v | sed -n -e 's|.*version* *\(.*\)$|\1|p' `
-	if test "$TMPVERSION" != "$OCAMLVERSION" ; then
-	    AC_MSG_RESULT([versions differs from ocamlc; ocamlc.opt discarded.])
-	else
-	    OCAMLC=$OCAMLCDOTOPT
-	fi
+        TMPVERSION=`$OCAMLCDOTOPT -v | sed -n -e 's|.*version* *\(.*\)$|\1|p' `
+        if test "$TMPVERSION" != "$OCAMLVERSION" ; then
+           AC_MSG_RESULT([versions differs from ocamlc; ocamlc.opt discarded.])
+        else
+           OCAMLC=$OCAMLCDOTOPT
+        fi
      fi
 
      # checking for ocamlopt.opt
      if test "$OCAMLOPT" != "no" ; then
-	AC_CHECK_TOOL([OCAMLOPTDOTOPT],[ocamlopt.opt],[no])
-	if test "$OCAMLOPTDOTOPT" != "no"; then
-	   TMPVERSION=`$OCAMLOPTDOTOPT -v | sed -n -e 's|.*version* *\(.*\)$|\1|p' `
-	   if test "$TMPVERSION" != "$OCAMLVERSION" ; then
-	      AC_MSG_RESULT([version differs from ocamlc; ocamlopt.opt discarded.])
-	   else
-	      OCAMLOPT=$OCAMLOPTDOTOPT
-	   fi
-        fi
+        AC_CHECK_TOOL([OCAMLOPTDOTOPT],[ocamlopt.opt],[no])
+        if test "$OCAMLOPTDOTOPT" != "no"; then
+           TMPVERSION=`$OCAMLOPTDOTOPT -v | sed -n -e 's|.*version* *\(.*\)$|\1|p' `
+           if test "$TMPVERSION" != "$OCAMLVERSION" ; then
+              AC_MSG_RESULT([version differs from ocamlc; ocamlopt.opt discarded.])
+           else
+              OCAMLOPT=$OCAMLOPTDOTOPT
+           fi
+       fi
      fi
 
      AC_SUBST([OCAMLOPT])
@@ -73,6 +74,18 @@ AC_DEFUN([AC_PROG_OCAML],
 
   AC_SUBST([OCAMLC])
 
+  # checking for native dynlink
+  AC_MSG_CHECKING([for dynlink.cmxa])
+  if test -f "$OCAMLLIB/dynlink.cmxa" ; then
+     OCAMLNATDYNLINK=yes
+     AC_MSG_RESULT([yes])
+  else
+     OCAMLNATDYNLINK=no
+     AC_MSG_RESULT([no])
+  fi
+
+  AC_SUBST([OCAMLNATDYNLINK])
+
   # checking for ocaml toplevel
   AC_CHECK_TOOL([OCAML],[ocaml],[no])
 
@@ -98,10 +111,10 @@ AC_DEFUN([AC_PROG_OCAMLLEX],
   # checking for ocamllex
   AC_CHECK_TOOL([OCAMLLEX],[ocamllex],[no])
   if test "$OCAMLLEX" != "no"; then
-    AC_CHECK_TOOL([OCAMLLEXDOTOPT],[ocamllex.opt],[no])
-    if test "$OCAMLLEXDOTOPT" != "no"; then
-	OCAMLLEX=$OCAMLLEXDOTOPT
-    fi
+     AC_CHECK_TOOL([OCAMLLEXDOTOPT],[ocamllex.opt],[no])
+     if test "$OCAMLLEXDOTOPT" != "no"; then
+        OCAMLLEX=$OCAMLLEXDOTOPT
+     fi
   fi
   AC_SUBST([OCAMLLEX])
 ])
@@ -122,7 +135,7 @@ AC_DEFUN([AC_PROG_CAMLP4],
   if test "$CAMLP4" != "no"; then
      TMPVERSION=`$CAMLP4 -v 2>&1| sed -n -e 's|.*version *\(.*\)$|\1|p'`
      if test "$TMPVERSION" != "$OCAMLVERSION" ; then
-	AC_MSG_RESULT([versions differs from ocamlc])
+        AC_MSG_RESULT([versions differs from ocamlc])
         CAMLP4=no
      fi
   fi
@@ -172,15 +185,15 @@ AC_DEFUN([AC_CHECK_OCAML_PKG],
   found=no
   for pkg in $1 $2 ; do
     if $OCAMLFIND query $pkg >/dev/null 2>/dev/null; then
-      AC_MSG_RESULT([found])
-      AS_TR_SH([OCAML_PKG_$1])=$pkg
-      found=yes
-      break
+       AC_MSG_RESULT([found])
+       AS_TR_SH([OCAML_PKG_$1])=$pkg
+       found=yes
+       break
     fi
   done
   if test "$found" = "no" ; then
-    AC_MSG_RESULT([not found])
-    AS_TR_SH([OCAML_PKG_$1])=no
+     AC_MSG_RESULT([not found])
+     AS_TR_SH([OCAML_PKG_$1])=no
   fi
 
   AC_SUBST(AS_TR_SH([OCAML_PKG_$1]))
@@ -197,16 +210,16 @@ EOF
   unset found
   for $1 in $$1 $4 ; do
     if $OCAMLC -c -I "$$1" conftest.ml >&5 2>&5 ; then
-      found=yes
-      break
+       found=yes
+       break
     fi
   done
 
   if test "$found" ; then
-    AC_MSG_RESULT([$$1])
+     AC_MSG_RESULT([$$1])
   else
-    AC_MSG_RESULT([not found])
-    $1=no
+     AC_MSG_RESULT([not found])
+     $1=no
   fi
   AC_SUBST([$1])
 ])
@@ -219,7 +232,7 @@ AC_DEFUN([AC_CHECK_OCAML_WORD_SIZE],
   AC_MSG_CHECKING([for OCaml compiler word size])
   cat > conftest.ml <<EOF
   print_endline (string_of_int Sys.word_size)
-  EOF
+EOF
   OCAML_WORD_SIZE=`$OCAML conftest.ml`
   AC_MSG_RESULT([$OCAML_WORD_SIZE])
   AC_SUBST([OCAML_WORD_SIZE])
diff --git a/parmap.ml b/parmap.ml
index 6f4b491..74f3669 100644
--- a/parmap.ml
+++ b/parmap.ml
@@ -41,7 +41,7 @@ let can_redirect path =
   if not(Sys.file_exists path) then
     try
       Unix.mkdir path 0o777; true
-    with Unix.Unix_error(e,s,s') ->
+    with Unix.Unix_error(e,_s,_s') ->
       (Printf.eprintf "[Pid %d]: Error creating %s : %s; proceeding without \
                        stdout/stderr redirection\n%!"
 	 (Unix.getpid ()) path (Unix.error_message e));
@@ -150,10 +150,10 @@ let simplemapper (init:int -> unit) (finalize: unit -> unit) ncores compute opid
           exit 0
 	end
     | -1  -> Utils.log_error "fork error: pid %d; i=%d" (Unix.getpid()) i;
-    | pid -> ()
+    | _pid -> ()
   done;
   (* wait for all children *)
-  for i = 0 to ncores-1 do
+  for _i = 0 to ncores-1 do
     try ignore(Unix.wait())
     with Unix.Unix_error (Unix.ECHILD, _, _) -> ()
   done;
@@ -200,10 +200,10 @@ let simpleiter init finalize ncores compute al =
           exit 0
 	end
     | -1  -> Utils.log_error "fork error: pid %d; i=%d" (Unix.getpid()) i;
-    | pid -> ()
+    | _pid -> ()
   done;
   (* wait for all children *)
-  for i = 0 to ncores-1 do
+  for _i = 0 to ncores-1 do
     try ignore(Unix.wait())
     with Unix.Unix_error (Unix.ECHILD, _, _) -> ()
   done
@@ -215,7 +215,7 @@ let simpleiter init finalize ncores compute al =
 type msg_to_master = Ready of int | Error of int * string
 type msg_to_worker = Finished | Task of int
 
-let setup_children_chans oc pipedown finalize ?fdarr i =
+let setup_children_chans oc pipedown ?fdarr i =
   Setcore.setcore i;
   (* close the other ends of the pipe and convert my ends to ic/oc *)
   Unix.close (snd pipedown.(i));
@@ -274,7 +274,7 @@ let mapper (init:int -> unit) (finalize:unit -> unit) ncores ~chunksize compute
                (* primitives for communication *)
                Unix.close pipeup_rd;
                let receive,signal,return,finish,pid =
-                 setup_children_chans oc_up pipedown finalize ~fdarr i in
+                 setup_children_chans oc_up pipedown ~fdarr i in
                let reschunk=ref opid in
                let computetask n = (* compute chunk number n *)
          	let lo=n*chunksize in
@@ -305,7 +305,7 @@ let mapper (init:int -> unit) (finalize:unit -> unit) ncores ~chunksize compute
                done;
              end
          | -1  -> Utils.log_error "fork error: pid %d; i=%d" (Unix.getpid()) i;
-         | pid -> ()
+         | _pid -> ()
        done;
 
        (* close unused ends of the pipes *)
@@ -336,7 +336,7 @@ let mapper (init:int -> unit) (finalize:unit -> unit) ncores ~chunksize compute
        ) ocs;
 
        (* wait for all children to terminate *)
-       for i = 0 to ncores-1 do
+       for _i = 0 to ncores-1 do
          try ignore(Unix.wait())
          with Unix.Unix_error (Unix.ECHILD, _, _) -> ()
        done;
@@ -385,7 +385,7 @@ let geniter init finalize ncores ~chunksize compute al =
                (* primitives for communication *)
                Unix.close pipeup_rd;
                let receive,signal,return,finish,pid =
-                 setup_children_chans oc_up pipedown finalize i in
+                 setup_children_chans oc_up pipedown i in
                let computetask n = (* compute chunk number n *)
  		let lo=n*chunksize in
  		let hi=if n=ntasks-1 then ln-1 else (n+1)*chunksize-1 in
@@ -415,7 +415,7 @@ let geniter init finalize ncores ~chunksize compute al =
  	      done;
  	    end
  	| -1  -> Utils.log_error "fork error: pid %d; i=%d" (Unix.getpid()) i;
- 	| pid -> ()
+ 	| _pid -> ()
        done;
 
        (* close unused ends of the pipes *)
@@ -445,7 +445,7 @@ let geniter init finalize ncores ~chunksize compute al =
        ) ocs;
 
        (* wait for all children to terminate *)
-       for i = 0 to ncores-1 do
+       for _i = 0 to ncores-1 do
  	try ignore(Unix.wait())
  	with Unix.Unix_error (Unix.ECHILD, _, _) -> ()
        done
@@ -489,7 +489,7 @@ let parmapfold
     (op:'b->'c->'c)
     (opid:'c)
     (concat:'c->'c->'c) : 'c=
-  parmapifold ?ncores ?chunksize (fun _ x -> f x) s op opid concat
+  parmapifold ~init ~finalize ?ncores ?chunksize (fun _ x -> f x) s op opid concat
 
 (* the parallel map function *)
 
@@ -530,7 +530,7 @@ let parfold
     (s:'a sequence)
     (opid:'b)
     (concat:'b->'b->'b) : 'b=
-    parmapfold ~ncores ?chunksize (fun x -> x) s op opid concat
+    parmapfold ~init ~finalize ~ncores ?chunksize (fun x -> x) s op opid concat
 
 (* the parallel map function, on arrays *)
 
@@ -637,7 +637,7 @@ let array_float_parmapi
        done
      with e -> exc_handler e lo
    in
-   mapper init finalize ncores ~chunksize compute () al (fun r -> ());
+   mapper init finalize ncores ~chunksize compute () al (fun _r -> ());
    let res =
      match result with
        None -> Bytearray.to_floatarray barr_out size
@@ -662,7 +662,7 @@ let array_float_parmap
     (f:'a -> float)
     (al:'a array) : float array =
   array_float_parmapi
-    ?ncores ?chunksize ?result ?sharedbuffer (fun _ x -> f x) al
+    ~init ~finalize ?ncores ?chunksize ?result ?sharedbuffer (fun _ x -> f x) al
 
 (* the parallel iteration function *)
 
diff --git a/parmap.mli b/parmap.mli
index 0353cfc..2a08377 100644
--- a/parmap.mli
+++ b/parmap.mli
@@ -40,6 +40,14 @@ type 'a sequence = L of 'a list | A of 'a array;;
     If you want to perform a parallel map operation on an array, use [array_parmap] or [array_float_parmap] instead.
     *)
 
+(** {6 Optional init and finalize functions} *)
+
+(** The optional [init] (resp. [finalize]) function is called once by each child process just after creation
+    (resp. just before exit).
+    [init] and [finalize] both default to doing nothing.
+    [init i] takes the child rank [i] as parameter (first forked child has rank 0, next 1, etc.).
+*)
+
 (** {6 Parallel mapfold} *)
 
 val parmapfold : ?init:(int -> unit) -> ?finalize:(unit -> unit) -> ?ncores:int -> ?chunksize:int -> ('a -> 'b) -> 'a sequence -> ('b-> 'c -> 'c) -> 'c -> ('c->'c->'c) -> 'c
diff --git a/setcore_stubs.c b/setcore_stubs.c
index 50df8a7..d9f977f 100644
--- a/setcore_stubs.c
+++ b/setcore_stubs.c
@@ -40,6 +40,7 @@ CAMLprim value setcore(value which) {
 	fprintf(stderr,"Failed pinning to cpu %d, trying %d/2\n",w, w); 
 	w=w/2;
       }
+      else
 #endif
 #if HAVE_MACH_THREAD_POLICY_H
       affinityData.affinity_tag = w;
@@ -51,8 +52,8 @@ CAMLprim value setcore(value which) {
         fprintf(stderr,"MAC OS X: Failed pinning to cpu %d, trying %d/2\n",w, w);
         w=w/2;
       }
-#endif
       else 
+#endif
 	{ //fprintf(stderr,"Succeeded pinning to cpu %d\n",w); 
 	  finished=1;
 	}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ocaml-maint/packages/parmap.git



More information about the Pkg-ocaml-maint-commits mailing list