[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