浏览代码

merge trunk@6651:6700

Nathalie Furmento 12 年之前
父节点
当前提交
6f01391744

+ 3 - 0
ChangeLog

@@ -20,6 +20,9 @@ StarPU 1.1.0 (svn revision xxxx)
 New features:
   * OpenGL interoperability support.
 
+Changes:
+  * The FxT code can now be used on systems other than Linux.
+
 StarPU 1.0.0 (svn revision 6306)
 ==============================================
 The extensions-again release

+ 1 - 1
Makefile.am

@@ -105,7 +105,7 @@ else
 txtdir = ${docdir}
 endif
 txt_DATA = AUTHORS COPYING.LGPL README
-EXTRA_DIST = AUTHORS COPYING.LGPL README STARPU-VERSION
+EXTRA_DIST = AUTHORS COPYING.LGPL README STARPU-VERSION build-aux/svn2cl.xsl
 
 include starpu-top/extradist
 

+ 457 - 0
build-aux/svn2cl.xsl

@@ -0,0 +1,457 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+
+   svn2cl.xsl - xslt stylesheet for converting svn log to a normal
+                changelog
+
+   version 0.13
+
+   Usage (replace ++ with two minus signs which aren't allowed
+   inside xml comments):
+     svn ++verbose ++xml log | \
+       xsltproc ++stringparam strip-prefix `basename $(pwd)` \
+                ++stringparam linelen 75 \
+                ++stringparam groupbyday yes \
+                ++stringparam separate-daylogs yes \
+                ++stringparam include-rev yes \
+                ++stringparam include-actions yes \
+                ++stringparam breakbeforemsg yes/2 \
+                ++stringparam reparagraph yes \
+                ++stringparam authorsfile FILE \
+                ++stringparam ignore-message-starting \
+                svn2cl.xsl - > ChangeLog
+
+   This file is based on several implementations of this conversion
+   that I was not completely happy with and some other common
+   xslt constructs found on the web.
+
+   Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Arthur de Jong.
+
+   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. The name of the author may not be used to endorse or promote
+      products derived from this software without specific prior
+      written permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+
+-->
+
+<xsl:stylesheet
+  version="1.0"
+  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+ <xsl:output
+   method="text"
+   encoding="utf-8"
+   media-type="text/plain"
+   omit-xml-declaration="yes"
+   standalone="yes"
+   indent="no" />
+
+ <xsl:strip-space elements="*" />
+
+ <!-- the prefix of pathnames to strip -->
+ <xsl:param name="strip-prefix" select="'/'" />
+
+ <!-- the length of a line to wrap messages at -->
+ <xsl:param name="linelen" select="75" />
+
+ <!-- whether entries should be grouped by day -->
+ <xsl:param name="groupbyday" select="'no'" />
+
+ <!-- whether to seperate log messages by empty lines -->
+ <xsl:param name="separate-daylogs" select="'no'" />
+
+ <!-- whether a revision number should be included -->
+ <xsl:param name="include-rev" select="'no'" />
+
+ <!-- whether aaction labels should be added to files -->
+ <xsl:param name="include-actions" select="'no'" />
+
+ <!-- whether the log message should start on a new line -->
+ <xsl:param name="breakbeforemsg" select="'no'" />
+
+ <!-- whether the message should be rewrapped within one paragraph -->
+ <xsl:param name="reparagraph" select="'no'" />
+
+ <!-- whether certain messages should be ignored -->
+ <xsl:param name="ignore-message-starting" select="''" />
+
+ <!-- location of authors file if any -->
+ <xsl:param name="authorsfile" select="''" />
+ <xsl:key name="author-lookup" match="author" use="@uid" />
+ <xsl:variable name="authors-top" select="document($authorsfile)/authors" />
+
+ <!-- determin the path part to strip -->
+ <xsl:variable name="strip-path">
+  <!-- if strip-prefix does not start with a slash, prepend it -->
+  <xsl:if test="not(starts-with($strip-prefix,'/'))">
+   <xsl:text>/</xsl:text>
+  </xsl:if>
+  <!-- the prefix itself -->
+  <xsl:value-of select="$strip-prefix" />
+  <!-- if strip-prefix does not start with a slash, append it -->
+  <xsl:if test="substring($strip-prefix,string-length($strip-prefix),1)!='/'">
+   <xsl:text>/</xsl:text>
+  </xsl:if>
+ </xsl:variable>
+
+ <!-- match the topmost log entry -->
+ <xsl:template match="log">
+  <xsl:choose>
+   <xsl:when test="$ignore-message-starting != ''">
+    <!-- only handle logentries with don't contain the string -->
+    <xsl:apply-templates select="logentry[not(starts-with(msg,$ignore-message-starting))]" />
+   </xsl:when>
+   <xsl:otherwise>
+    <xsl:apply-templates select="logentry" />
+   </xsl:otherwise>
+  </xsl:choose>
+  <!-- add newlines at the end of the changelog -->
+  <xsl:text>&#10;</xsl:text>
+ </xsl:template>
+
+ <!-- format one entry from the log -->
+ <xsl:template match="logentry">
+  <xsl:choose>
+   <!-- if we're grouping we should omit some headers -->
+   <xsl:when test="$groupbyday='yes'">
+    <!-- fetch previous entry's date -->
+    <xsl:variable name="prevdate">
+     <xsl:apply-templates select="preceding-sibling::logentry[position()=1]/date" />
+    </xsl:variable>
+    <!-- fetch previous entry's author -->
+    <xsl:variable name="prevauthor">
+     <xsl:value-of select="normalize-space(preceding-sibling::logentry[position()=1]/author)" />
+    </xsl:variable>
+    <!-- fetch this entry's date -->
+    <xsl:variable name="date">
+     <xsl:apply-templates select="date" />
+    </xsl:variable>
+    <!-- fetch this entry's author -->
+    <xsl:variable name="author">
+     <xsl:value-of select="normalize-space(author)" />
+    </xsl:variable>
+    <!-- check if header is changed -->
+    <xsl:if test="($prevdate!=$date) or ($prevauthor!=$author)">
+     <!-- add newline -->
+     <xsl:if test="not(position()=1)">
+      <xsl:text>&#10;</xsl:text>
+     </xsl:if>
+     <!-- date -->
+     <xsl:value-of select="$date" />
+     <!-- two spaces -->
+     <xsl:text>&#32;&#32;</xsl:text>
+     <!-- author's name -->
+     <xsl:apply-templates select="author" />
+     <!-- two newlines -->
+     <xsl:text>&#10;</xsl:text>
+     <xsl:if test="$separate-daylogs!='yes'"><xsl:text>&#10;</xsl:text></xsl:if>
+    </xsl:if>
+   </xsl:when>
+   <!-- write the log header -->
+   <xsl:otherwise>
+    <!-- add newline -->
+    <xsl:if test="not(position()=1)">
+     <xsl:text>&#10;</xsl:text>
+    </xsl:if>
+    <!-- date -->
+    <xsl:apply-templates select="date" />
+    <!-- two spaces -->
+    <xsl:text>&#32;&#32;</xsl:text>
+    <!-- author's name -->
+    <xsl:apply-templates select="author" />
+    <!-- two newlines -->
+    <xsl:text>&#10;&#10;</xsl:text>
+   </xsl:otherwise>
+  </xsl:choose>
+  <!-- get paths string -->
+  <xsl:variable name="paths">
+   <xsl:apply-templates select="paths" />
+  </xsl:variable>
+  <!-- get revision number -->
+  <xsl:variable name="rev">
+   <xsl:if test="$include-rev='yes'">
+    <xsl:text>[r</xsl:text>
+    <xsl:value-of select="@revision" />
+    <xsl:text>]&#32;</xsl:text>
+   </xsl:if>
+  </xsl:variable>
+  <!-- trim trailing newlines -->
+  <xsl:variable name="msg">
+   <!-- add a line break before the log message -->
+   <xsl:choose>
+    <xsl:when test="$breakbeforemsg='yes'">
+     <xsl:text>&#10;</xsl:text>
+    </xsl:when>
+    <xsl:when test="number($breakbeforemsg)&gt;0">
+     <xsl:call-template name="newlines">
+      <xsl:with-param name="count" select="number($breakbeforemsg)" />
+     </xsl:call-template>
+    </xsl:when>
+   </xsl:choose>
+   <xsl:call-template name="trim-newln">
+    <xsl:with-param name="txt" select="msg" />
+   </xsl:call-template>
+  </xsl:variable>
+  <!-- add newline here if separate-daylogs is in effect -->
+  <xsl:if test="$groupbyday='yes' and $separate-daylogs='yes'"><xsl:text>&#10;</xsl:text></xsl:if>
+  <!-- first line is indented (other indents are done in wrap template) -->
+  <xsl:text>&#9;*&#32;</xsl:text>
+  <!-- set up the text to wrap -->
+  <xsl:variable name="txt">
+   <xsl:value-of select="$rev" />
+   <xsl:if test="$paths!=''">
+    <xsl:value-of select="concat($paths,':&#32;')" />
+   </xsl:if>
+   <xsl:value-of select="$msg" />
+  </xsl:variable>
+  <!-- print the paths and message nicely wrapped -->
+  <xsl:call-template name="wrap">
+   <xsl:with-param name="txt" select="$txt" />
+  </xsl:call-template>
+ </xsl:template>
+
+ <!-- format date -->
+ <xsl:template match="date">
+  <xsl:variable name="date" select="normalize-space(.)" />
+  <!-- output date part -->
+  <xsl:value-of select="substring($date,1,10)" />
+  <!-- output time part -->
+  <xsl:if test="$groupbyday!='yes'">
+   <xsl:text>&#32;</xsl:text>
+   <xsl:value-of select="substring($date,12,5)" />
+  </xsl:if>
+ </xsl:template>
+
+ <!-- format author -->
+ <xsl:template match="author">
+  <xsl:variable name="uid" select="normalize-space(.)" />
+  <!-- try to lookup author in authorsfile -->
+  <xsl:choose>
+   <xsl:when test="$authorsfile!=''">
+    <xsl:for-each select="$authors-top">
+     <xsl:variable name="author" select="key('author-lookup',$uid)" />
+     <!-- present result -->
+     <xsl:choose>
+      <xsl:when test="string($author/.)">
+       <xsl:apply-templates select="$author/node()" mode="copy" />
+      </xsl:when>
+      <xsl:otherwise>
+       <xsl:value-of select="$uid" />
+      </xsl:otherwise>
+     </xsl:choose>
+    </xsl:for-each>
+   </xsl:when>
+   <xsl:otherwise>
+    <xsl:value-of select="$uid" />
+   </xsl:otherwise>
+  </xsl:choose>
+ </xsl:template>
+
+ <!-- copy but normalize text -->
+ <xsl:template match="text()" mode="copy">
+  <xsl:value-of select="normalize-space(.)" />
+ </xsl:template>
+
+ <!-- simple copy template -->
+ <xsl:template match="@*|node()" mode="copy">
+  <xsl:copy>
+   <xsl:apply-templates select="@*|node()" mode="copy" />
+  </xsl:copy>
+ </xsl:template>
+
+ <!-- present a list of paths names -->
+ <xsl:template match="paths">
+  <xsl:choose>
+   <!-- only handle paths that begin with the path and strip the path -->
+   <xsl:when test="$strip-prefix != ''">
+    <!-- filter on all entries within directory -->
+    <xsl:for-each select="path[starts-with(concat(normalize-space(.),'/'),$strip-path)]">
+     <xsl:sort select="normalize-space(.)" data-type="text" />
+     <!-- unless we are the first entry, add a comma -->
+     <xsl:if test="not(position()=1)">
+      <xsl:text>,&#32;</xsl:text>
+     </xsl:if>
+     <!-- get path part -->
+     <xsl:variable name="path" select="substring(normalize-space(.),string-length($strip-path)+1)" />
+     <!-- translate empty string to dot and print result -->
+     <xsl:if test="$path = ''">
+      <xsl:text>.</xsl:text>
+     </xsl:if>
+     <xsl:value-of select="$path" />
+     <!-- add the action flag -->
+     <xsl:if test="$include-actions='yes'">
+      <xsl:apply-templates select="." mode="action"/>
+     </xsl:if>
+    </xsl:for-each>
+   </xsl:when>
+   <!-- print a simple list of all paths -->
+   <xsl:otherwise>
+    <xsl:for-each select="path">
+     <xsl:sort select="normalize-space(.)" data-type="text" />
+     <!-- unless we are the first entry, add a comma -->
+     <xsl:if test="not(position()=1)">
+      <xsl:text>,&#32;</xsl:text>
+     </xsl:if>
+     <!-- print the path name -->
+     <xsl:value-of select="normalize-space(.)" />
+     <!-- add the action flag -->
+     <xsl:if test="$include-actions='yes'">
+      <xsl:apply-templates select="." mode="action"/>
+     </xsl:if>
+    </xsl:for-each>
+   </xsl:otherwise>
+  </xsl:choose>
+ </xsl:template>
+
+ <xsl:template match="path" mode="action">
+  <xsl:choose>
+   <xsl:when test="@action='D'">
+    <xsl:text>[DEL]</xsl:text>
+   </xsl:when>
+   <xsl:when test="@copyfrom-path">
+    <xsl:text>[CPY]</xsl:text>
+   </xsl:when>
+   <xsl:when test="@action='A'">
+    <xsl:text>[ADD]</xsl:text>
+   </xsl:when>
+  </xsl:choose>
+ </xsl:template>
+
+ <!-- string-wrapping template -->
+ <xsl:template name="wrap">
+  <xsl:param name="txt" />
+  <xsl:variable name="normtxt" select="normalize-space($txt)" />
+  <xsl:choose>
+   <xsl:when test="contains($txt,'&#10;')">
+     <!-- text contains newlines, do the first line -->
+     <xsl:call-template name="wrap">
+      <xsl:with-param name="txt" select="substring-before($txt,'&#10;')" />
+     </xsl:call-template>
+     <!-- print tab -->
+     <xsl:text>&#9;&#32;&#32;</xsl:text>
+     <!-- wrap the rest of the text -->
+     <xsl:call-template name="wrap">
+      <xsl:with-param name="txt" select="substring-after($txt,'&#10;')" />
+     </xsl:call-template>
+   </xsl:when>
+   <xsl:when test="(string-length($normtxt) &lt; (($linelen)-9)) or not(contains($normtxt,' '))">
+    <!-- this is easy, nothing to do -->
+    <xsl:value-of select="$normtxt" />
+    <!-- add newline -->
+    <xsl:text>&#10;</xsl:text>
+   </xsl:when>
+   <xsl:otherwise>
+    <!-- find the first line -->
+    <xsl:variable name="tmp" select="substring($normtxt,1,(($linelen)-9))" />
+    <xsl:variable name="line">
+     <xsl:choose>
+      <!-- if our attempt contains spaces wrap on that -->
+      <xsl:when test="contains($tmp,' ')">
+       <xsl:call-template name="find-line">
+        <xsl:with-param name="txt" select="$tmp" />
+       </xsl:call-template>
+      </xsl:when>
+      <!-- otherwise use the first non-space characters from the text -->
+      <xsl:otherwise>
+       <xsl:value-of select="substring-before($normtxt,' ')" />
+      </xsl:otherwise>
+     </xsl:choose>
+    </xsl:variable>
+    <!-- print line -->
+    <xsl:value-of select="$line" />
+    <!-- print newline and tab -->
+    <xsl:text>&#10;&#9;&#32;&#32;</xsl:text>
+    <!-- wrap the rest of the text -->
+    <xsl:call-template name="wrap">
+     <xsl:with-param name="txt" select="normalize-space(substring($normtxt,string-length($line)+1))" />
+    </xsl:call-template>
+   </xsl:otherwise>
+  </xsl:choose>
+ </xsl:template>
+
+ <!-- template to trim line to contain space as last char -->
+ <xsl:template name="find-line">
+  <xsl:param name="txt" />
+  <xsl:choose>
+   <xsl:when test="substring($txt,string-length($txt),1)=' '">
+    <xsl:value-of select="substring($txt,1,string-length($txt)-1)" />
+   </xsl:when>
+   <xsl:otherwise>
+    <xsl:call-template name="find-line">
+     <xsl:with-param name="txt" select="substring($txt,1,string-length($txt)-1)" />
+    </xsl:call-template>
+   </xsl:otherwise>
+  </xsl:choose>
+ </xsl:template>
+
+ <!-- template to trim trailing and starting newlines -->
+ <xsl:template name="trim-newln">
+  <xsl:param name="txt" />
+  <xsl:choose>
+   <!-- find starting newlines -->
+   <xsl:when test="substring($txt,1,1) = '&#10;'">
+    <xsl:call-template name="trim-newln">
+     <xsl:with-param name="txt" select="substring($txt,2)" />
+    </xsl:call-template>
+   </xsl:when>
+   <!-- find trailing newlines -->
+   <xsl:when test="substring($txt,string-length($txt),1) = '&#10;'">
+    <xsl:call-template name="trim-newln">
+     <xsl:with-param name="txt" select="substring($txt,1,string-length($txt)-1)" />
+    </xsl:call-template>
+   </xsl:when>
+   <!-- if the message has paragraphs, find the first one -->
+   <xsl:when test="$reparagraph='yes' and contains($txt,'&#10;&#10;')">
+     <!-- remove newlines from first paragraph -->
+     <xsl:value-of select="normalize-space(substring-before($txt,'&#10;&#10;'))" />
+     <!-- paragraph separator -->
+     <xsl:text>&#10;&#10;</xsl:text>
+     <!-- do the rest of the text -->
+     <xsl:call-template name="trim-newln">
+      <xsl:with-param name="txt" select="substring-after($txt,'&#10;&#10;')" />
+     </xsl:call-template>
+   </xsl:when>
+   <!-- remove more single newlines -->
+   <xsl:when test="$reparagraph='yes'">
+    <xsl:value-of select="normalize-space($txt)" />
+   </xsl:when>
+   <!-- no newlines found, we're done -->
+   <xsl:otherwise>
+    <xsl:value-of select="$txt" />
+   </xsl:otherwise>
+  </xsl:choose>
+ </xsl:template>
+
+ <!-- insert a number of newlines -->
+ <xsl:template name="newlines">
+  <xsl:param name="count" />
+  <xsl:text>&#10;</xsl:text>
+  <xsl:if test="$count&gt;1">
+   <xsl:call-template name="newlines">
+    <xsl:with-param name="count" select="($count)-1" />
+   </xsl:call-template>
+  </xsl:if>
+ </xsl:template>
+
+</xsl:stylesheet>

+ 2 - 1
configure.ac

@@ -1292,7 +1292,8 @@ fi
 AM_MISSING_PROG([YACC], [bison])
 
 AM_CONDITIONAL([BUILD_GCC_PLUGIN], [test "x$build_gcc_plugin" = "xyes"])
-AM_CONDITIONAL([HAVE_GUILE], [test "x$GUILE" != "x"])
+AM_CONDITIONAL([RUN_GCC_PLUGIN_TESTS],
+  [test "x$run_gcc_plugin_test_suite" = "xyes"])
 
 ###############################################################################
 #                                                                             #

+ 19 - 6
doc/chapters/advanced-api.texi

@@ -805,18 +805,31 @@ static struct starpu_sched_policy dummy_sched_policy = @{
 @subsection Driver API
 
 @deftypefun int starpu_driver_init (struct starpu_driver *@var{d})
-Initialize the given driver. Returns 0 on success, -EINVAL if d->type is not
-STARPU_CUDA_WORKER.
+Initialize the given driver. Returns 0 on success, -EINVAL if
+@code{d->type} is not a valid StarPU device type (STARPU_CPU_WORKER,
+STARPU_CUDA_WORKER or STARPU_OPENCL_WORKER).
+@end deftypefun
+
+@deftypefun int starpu_driver_run ({struct starpu_driver *}@var{d})
+Run the driver until it receives a request to terminate, then returns 0 on success, -EINVAL if
+@code{d->type} is not a valid StarPU device type (STARPU_CPU_WORKER,
+STARPU_CUDA_WORKER or STARPU_OPENCL_WORKER).
 @end deftypefun
 
 @deftypefun int starpu_driver_run_once (struct starpu_driver *@var{d})
-Runs the driver for a while, then returns 0 on success, -EINVAL if d->type is
-not STARPU_CUDA_WORKER.
+Run the driver once, then returns 0 on success, -EINVAL if
+@code{d->type} is not a valid StarPU device type (STARPU_CPU_WORKER,
+STARPU_CUDA_WORKER or STARPU_OPENCL_WORKER).
 @end deftypefun
 
 @deftypefun int starpu_driver_deinit (struct starpu_driver *@var{d})
-Deinitialize the given driver. Returns 0 on success, -EINVAL if d->type is not
-STARPU_CUDA_WORKER.
+Deinitialize the given driver. Returns 0 on success, -EINVAL if
+@code{d->type} is not a valid StarPU device type (STARPU_CPU_WORKER,
+STARPU_CUDA_WORKER or STARPU_OPENCL_WORKER).
+@end deftypefun
+
+@deftypefun void starpu_drivers_request_termination (void)
+Notify all running drivers they should terminate.
 @end deftypefun
 
 @node Running drivers Example

+ 4 - 2
doc/chapters/basic-api.texi

@@ -39,10 +39,12 @@ indicates that no worker was available (so that StarPU was not initialized).
 @deftp {Data Type} {struct starpu_driver}
 @table @asis
 @item @code{enum starpu_archtype type}
-The type of the driver. Only STARPU_CUDA_DRIVER and STARPU_OPENCL_DRIVER are
-currently supported.
+The type of the driver. Only STARPU_CPU_DRIVER, STARPU_CUDA_DRIVER and
+STARPU_OPENCL_DRIVER are currently supported.
 @item @code{union id} Anonymous union
 @table @asis
+@item @code{unsigned cpu_id}
+Should only be used if type is STARPU_CPU_WORKER.
 @item @code{unsigned cuda_id}
 Should only be used if type is STARPU_CUDA_WORKER.
 @item @code{cl_device_id opencl_id}

+ 2 - 1
examples/basic_examples/vector_scal.c

@@ -1,7 +1,7 @@
 /* StarPU --- Runtime system for heterogeneous multicore architectures.
  *
  * Copyright (C) 2010, 2011, 2012  Centre National de la Recherche Scientifique
- * Copyright (C) 2010, 2011  Université de Bordeaux 1
+ * Copyright (C) 2010-2012  Université de Bordeaux 1
  *
  * StarPU is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by
@@ -66,6 +66,7 @@ static struct starpu_codelet cl =
 		, scal_sse_func_icc
 #endif
 #endif
+		, NULL
 	},
 #ifdef STARPU_USE_CUDA
 	/* CUDA implementation of the codelet */

+ 1 - 1
examples/gl_interop/gl_interop.c

@@ -70,7 +70,7 @@ void callback_func(void *foo) {
 	printf("rendering done\n");
 
 	/* Tell it was already the last submitted task */
-	starpu_set_end_of_submissions();
+	starpu_drivers_request_termination();
 }
 
 int main(int argc, char **argv)

+ 2 - 0
gcc-plugin/ChangeLog

@@ -0,0 +1,2 @@
+This file should be generated when making a tarball from a Subversion
+checkout.  If it's not, please refer to the output "svn log".

+ 24 - 2
gcc-plugin/Makefile.am

@@ -1,6 +1,6 @@
 # StarPU --- Runtime system for heterogeneous multicore architectures.
 #
-# Copyright (C) 2011 Institut National de Recherche en Informatique et Automatique
+# Copyright (C) 2011, 2012 Institut National de Recherche en Informatique et Automatique
 #
 # StarPU is free software; you can redistribute it and/or modify
 # it under the terms of the GNU Lesser General Public License as published by
@@ -15,9 +15,31 @@
 
 SUBDIRS = src tests examples
 
-EXTRA_DIST = COPYING README
+EXTRA_DIST = COPYING README ChangeLog
 
 showcheck:
 	for i in $(SUBDIRS) ; do \
 		make -C $$i showcheck ; \
 	done
+
+# Generate a GNU-style ChangeLog for inclusion in the tarball.
+# It requires network access and may be slow.
+gen-ChangeLog:
+	if test "x$$CHANGELOG" = "xno"; then					\
+	   echo "ChangeLog not built, per user request" >&2;			\
+	elif ! xsltproc --version > /dev/null 2>&1; then			\
+	   echo "xsltproc not found, ChangeLog not generated" >&2;		\
+	elif ! test -d "$(srcdir)/.svn"; then					\
+	   echo "Subversion meta-data not found, ChangeLog not generated" >&2;	\
+	elif ! svn --version > /dev/null 2>&1; then				\
+	   echo "Subversion not found, ChangeLog not generated" >&2;		\
+	else									\
+	   ( cd "$(srcdir)";							\
+	     svn log --xml --verbose ) |					\
+	   xsltproc "$(top_srcdir)/build-aux/svn2cl.xsl" - > "ChangeLog.tmp";	\
+	   mv "ChangeLog.tmp" "$(distdir)/ChangeLog";				\
+	fi
+
+dist-hook: gen-ChangeLog
+
+.PHONY: showcheck dist-hook gen-ChangeLog

+ 21 - 12
gcc-plugin/src/starpu.c

@@ -634,7 +634,7 @@ handle_pragma_initialize (struct cpp_reader *reader)
 			      error_var, integer_zero_node),
 		      build_error_statements (loc, error_var,
 					      build_starpu_error_string,
-					      "failed to initialize StarPU"), 
+					      "failed to initialize StarPU"),
 		      NULL_TREE);
 
   tree stmts = NULL_TREE;
@@ -1273,11 +1273,13 @@ build_opencl_set_kernel_arg_calls (location_t loc, tree task_impl,
 
 static void
 define_opencl_task_implementation (location_t loc, tree task_impl,
-				   const char *file, const_tree kernel)
+				   const char *file, const_tree kernel,
+				   const_tree groupsize)
 {
   gcc_assert (task_implementation_p (task_impl)
 	      && task_implementation_where (task_impl) == STARPU_OPENCL);
   gcc_assert (TREE_CODE (kernel) == STRING_CST);
+  gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (groupsize)));
 
   local_define (tree, local_var, (tree type))
   {
@@ -1447,8 +1449,7 @@ define_opencl_task_implementation (location_t loc, tree task_impl,
 
       /* TODO: Support user-provided values.  */
       append_to_statement_list (build2 (INIT_EXPR, TREE_TYPE (group_size_var),
-					group_size_var,
-					build_int_cst (integer_type_node, 1)),
+					group_size_var, (tree)groupsize),
 				&stmts);
       append_to_statement_list (build2 (INIT_EXPR, TREE_TYPE (ngroups_var),
 					ngroups_var,
@@ -1527,8 +1528,8 @@ handle_pragma_opencl (struct cpp_reader *reader)
   if (args == NULL_TREE)
     return;
 
-  /* TODO: Add "group size" and "number of groups" arguments.  */
-  if (list_length (args) < 3)
+  /* TODO: Add "number of groups" arguments.  */
+  if (list_length (args) < 4)
     {
       error_at (loc, "wrong number of arguments for %<starpu opencl%> pragma");
       return;
@@ -1547,13 +1548,21 @@ handle_pragma_opencl (struct cpp_reader *reader)
   	      if (TREE_CODE (TREE_VALUE (args)) == STRING_CST)
   		{
   		  tree kernel = TREE_VALUE (args);
+		  args = TREE_CHAIN (args);
 
-  		  if (TREE_CHAIN (args) == NULL_TREE)
-		    define_opencl_task_implementation (loc, task_impl,
-						       TREE_STRING_POINTER (file),
-						       kernel);
-  		  else
-  		    error_at (loc, "junk after %<starpu opencl%> pragma");
+		  if (TREE_TYPE (TREE_VALUE (args)) != NULL_TREE &&
+		      INTEGRAL_TYPE_P (TREE_TYPE (TREE_VALUE (args))))
+		    {
+		      tree groupsize = TREE_VALUE (args);
+		      if (TREE_CHAIN (args) == NULL_TREE)
+			define_opencl_task_implementation (loc, task_impl,
+							   TREE_STRING_POINTER (file),
+							   kernel, groupsize);
+		      else
+			error_at (loc, "junk after %<starpu opencl%> pragma");
+		    }
+		  else
+		    error_at (loc, "%<groupsize%> argument must be an integral type");
   		}
   	      else
   		error_at (loc, "%<kernel%> argument must be a string constant");

+ 4 - 7
gcc-plugin/tests/Makefile.am

@@ -85,20 +85,17 @@ EXTRA_DIST += ./run-test.in			\
   $(gcc_tests)
 
 # The test suite assumes that the CPU back-end is available.
-if STARPU_USE_CPU
+if RUN_GCC_PLUGIN_TESTS
 
 TESTS = $(gcc_tests)
-
-endif
-
 TESTS_ENVIRONMENT = ./run-test
 
-if !HAVE_GUILE
+else !RUN_GCC_PLUGIN_TESTS
 
 check-hook:
-	-@echo "GNU Guile not available, test suite not run."
+	-@echo "GNU Guile or CPU back-end not available, test suite not run."
 
-endif !HAVE_GUILE
+endif !RUN_GCC_PLUGIN_TESTS
 
 showcheck:
 	-cat $(TEST_LOGS) /dev/null

+ 12 - 1
gcc-plugin/tests/mocks.h

@@ -469,6 +469,15 @@ struct load_opencl_arguments
 /* Expected arguments.  */
 static struct load_opencl_arguments expected_load_opencl_arguments;
 
+struct cl_enqueue_kernel_arguments
+{
+  size_t * global_work_size;
+};
+
+/* Variable describing the expected `clEnqueueNDRangeKernel' arguments. */
+static struct cl_enqueue_kernel_arguments expected_cl_enqueue_kernel_arguments;
+
+
 int
 starpu_opencl_load_opencl_from_string (const char *source,
 				       struct starpu_opencl_program *program,
@@ -551,7 +560,9 @@ clEnqueueNDRangeKernel(cl_command_queue command_queue,
                        const cl_event * event_wait_list,
                        cl_event *       event)
 {
-  assert (*global_work_size == 1 && *local_work_size == 1);
+  assert (*local_work_size == 1);
+  assert (*global_work_size == *expected_cl_enqueue_kernel_arguments.global_work_size);
+
   opencl_enqueue_calls++;
   return 0;
 }

+ 9 - 8
gcc-plugin/tests/opencl-errors.c

@@ -35,19 +35,20 @@ my_task_cpu (int x, float a[x])
 }
 
 
-#pragma starpu opencl my_task "test.cl" "kern" /* (error "not a.* task impl") */
+#pragma starpu opencl my_task "test.cl" "kern" 1 /* (error "not a.* task impl") */
 #pragma starpu opencl my_task_cpu  /* (error "not a.* task impl") */	\
-                      "test.cl" "kern"
-#pragma starpu opencl my_task_opencl "/dev/null" "kern" /* (error "empty") */
-#pragma starpu opencl my_task_opencl "/does-not-exist/" "kern" /* (error "failed to access") */
+                      "test.cl" "kern" 1
+#pragma starpu opencl my_task_opencl "/dev/null" "kern" 1 /* (error "empty") */
+#pragma starpu opencl my_task_opencl "/does-not-exist/" "kern" 1 /* (error "failed to access") */
 
 #pragma starpu opencl my_task_opencl	  /* (error "wrong number of arg") */
-#pragma starpu opencl my_task_opencl 123 "kern" /* (error "string constant") */
-#pragma starpu opencl my_task_opencl "test.cl" 123 /* (error "string constant") */
-#pragma starpu opencl my_task_opencl "test.cl" "kern" "foo" /* (error "junk after") */
+#pragma starpu opencl my_task_opencl 123 "kern" 1 /* (error "string constant") */
+#pragma starpu opencl my_task_opencl "test.cl" 123 1 /* (error "string constant") */
+#pragma starpu opencl my_task_opencl "test.cl" "kern" "a" /* (error "integral type") */
+#pragma starpu opencl my_task_opencl "test.cl" "kern" 1 "foo" /* (error "junk after") */
 
 void
 foo (void)
 {
-#pragma starpu opencl my_task_opencl "test.cl" "kern" /* (error "top-level") */
+#pragma starpu opencl my_task_opencl "test.cl" "kern" 1 /* (error "top-level") */
 }

+ 2 - 1
gcc-plugin/tests/opencl.c

@@ -29,7 +29,7 @@ static void my_task (int x, float a[x])
 static void my_task_opencl (int x, float a[x])
   __attribute__ ((task_implementation ("opencl", my_task)));
 
-#pragma starpu opencl my_task_opencl "test.cl" "kern"
+#pragma starpu opencl my_task_opencl "test.cl" "kern" 8
 
 int
 main ()
@@ -55,6 +55,7 @@ main ()
 
   expected_insert_task_arguments = expected;
   expected_insert_task_targets = STARPU_OPENCL;
+  size_t y = 8; expected_cl_enqueue_kernel_arguments.global_work_size = &y;
 
   my_task (123, a);
   my_task (123, a);

+ 2 - 2
include/starpu.h

@@ -203,8 +203,8 @@ void starpu_worker_get_name(int id, char *dst, size_t maxlen);
 int starpu_worker_get_devid(int id);
 void starpu_profiling_init();
 	void starpu_display_stats();
-int starpu_driver_run(struct starpu_driver *);
-void starpu_set_end_of_submissions(void);
+int starpu_driver_run(struct starpu_driver *d);
+void starpu_drivers_request_termination(void);
 
 int starpu_driver_init(struct starpu_driver *d);
 int starpu_driver_run_once(struct starpu_driver *d);

+ 5 - 0
include/starpu_data.h

@@ -52,6 +52,11 @@ struct starpu_data_interface_ops;
 void starpu_data_unregister(starpu_data_handle_t handle);
 void starpu_data_unregister_no_coherency(starpu_data_handle_t handle);
 
+/* Destroy the data handle once it is not needed anymore by any submitted task.
+ * No coherency is assumed.
+ */
+void starpu_data_unregister_lazy(starpu_data_handle_t handle);
+
 /* Destroy all data replicates. After data invalidation, the first access to
  * the handle must be performed in write-only mode. */
 void starpu_data_invalidate(starpu_data_handle_t handle);

+ 1 - 11
src/core/sched_policy.c

@@ -88,17 +88,7 @@ static void load_sched_policy(struct starpu_sched_policy *sched_policy, struct _
 #endif
         struct starpu_sched_policy *policy = sched_ctx->sched_policy;
 
-	policy->init_sched = sched_policy->init_sched;
-	policy->deinit_sched = sched_policy->deinit_sched;
-	policy->push_task = sched_policy->push_task;
-	policy->pop_task = sched_policy->pop_task;
-	policy->pre_exec_hook = sched_policy->pre_exec_hook;
-	policy->post_exec_hook = sched_policy->post_exec_hook;
-	policy->pop_every_task = sched_policy->pop_every_task;
-	policy->push_task_notify = sched_policy->push_task_notify;
-	policy->policy_name = sched_policy->policy_name;
-	policy->add_workers = sched_policy->add_workers;
-	policy->remove_workers = sched_policy->remove_workers;
+	memcpy(&policy, sched_policy, sizeof(policy));
 }
 
 static struct starpu_sched_policy *find_sched_policy_from_name(const char *policy_name)

+ 1 - 1
src/core/task.c

@@ -650,7 +650,7 @@ void _starpu_decrement_nsubmitted_tasks(void)
 }
 
 void
-starpu_set_end_of_submissions(void)
+starpu_drivers_request_termination(void)
 {
 	struct _starpu_machine_config *config = _starpu_get_machine_config();
 

+ 7 - 0
src/datawizard/interfaces/data_interface.c

@@ -586,6 +586,13 @@ void starpu_data_unregister_no_coherency(starpu_data_handle_t handle)
 	_starpu_data_unregister(handle, 0);
 }
 
+void starpu_data_unregister_lazy(starpu_data_handle_t handle) {
+	_starpu_spin_lock(&handle->header_lock);
+	handle->lazy_unregister = 1;
+	_starpu_spin_unlock(&handle->header_lock);
+	_starpu_data_unregister(handle, 0);
+}
+
 void starpu_data_invalidate(starpu_data_handle_t handle)
 {
 	STARPU_ASSERT(handle);

+ 1 - 1
src/drivers/cuda/driver_cuda.c

@@ -120,7 +120,7 @@ void starpu_cuda_set_device(int devid)
 #ifdef HAVE_CUDA_MEMCPY_PEER
 	if (conf->n_cuda_opengl_interoperability) {
 		fprintf(stderr, "OpenGL interoperability was requested, but StarPU was built with multithread GPU control support, please reconfigure with --disable-cuda-memcpy-peer but that will disable the memcpy-peer optimizations\n");
-		STARPU_ASSERT(0);
+		STARPU_ABORT();
 	}
 #else
 	for (i = 0; i < conf->n_cuda_opengl_interoperability; i++)

+ 1 - 1
src/drivers/opencl/driver_opencl.c

@@ -568,7 +568,7 @@ void *_starpu_opencl_worker(void *arg)
 
 	starpu_opencl_get_device(args->devid, &id);
 	struct starpu_driver d = {
-		.type         = STARPU_CUDA_WORKER,
+		.type         = STARPU_OPENCL_WORKER,
 		.id.opencl_id = id
 	};
 

+ 2 - 0
tests/Makefile.am

@@ -116,6 +116,7 @@ noinst_PROGRAMS =				\
 	main/deprecated_func			\
 	main/deprecated_buffer			\
 	main/driver_api/init_run_deinit         \
+	main/driver_api/run_driver              \
 	main/restart				\
 	main/execute_on_a_specific_worker	\
 	main/insert_task			\
@@ -176,6 +177,7 @@ noinst_PROGRAMS =				\
 	datawizard/increment_redux_lazy		\
 	datawizard/handle_to_pointer		\
 	datawizard/lazy_allocation		\
+	datawizard/lazy_unregister		\
 	datawizard/interfaces/copy_interfaces	\
 	datawizard/interfaces/block/block_interface \
 	datawizard/interfaces/bcsr/bcsr_interface \

+ 77 - 0
tests/datawizard/lazy_unregister.c

@@ -0,0 +1,77 @@
+/* StarPU --- Runtime system for heterogeneous multicore architectures.
+ *
+ * Copyright (C) 2010, 2011, 2012  Centre National de la Recherche Scientifique
+ *
+ * StarPU is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * StarPU is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * See the GNU Lesser General Public License in COPYING.LGPL for more details.
+ */
+
+#include <config.h>
+#include <starpu.h>
+
+#include "../helper.h"
+
+static void dummy_func(void ** buffers, void * args)
+{
+	(void) buffers;
+	(void) args;
+}
+
+static struct starpu_codelet dummy_cl =
+{
+	.modes = { STARPU_RW },
+	.cpu_funcs = { dummy_func, NULL },
+	.nbuffers = 1
+};
+
+int main(void)
+{
+	int ret;
+	int buffer[1024];
+	starpu_data_handle_t handle;
+	struct starpu_task *t1, *t2;
+
+	ret = starpu_init(NULL);
+	if (ret == -ENODEV)
+		return STARPU_TEST_SKIPPED;
+	STARPU_CHECK_RETURN_VALUE(ret, "starpu_init");
+
+	starpu_variable_data_register(&handle, 0, (uintptr_t)buffer, 1024*sizeof(int));
+
+	t1 = starpu_task_create();
+	t2 = starpu_task_create();
+	t1->cl = &dummy_cl;
+	t2->cl = &dummy_cl;
+	t1->handles[0] = handle;
+	t2->handles[0] = handle;
+
+	starpu_task_declare_deps_array(t2, 1, &t1);
+
+	ret = starpu_task_submit(t2);
+	STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_submit");
+	starpu_data_unregister_lazy(handle);
+
+	if (starpu_data_lookup(buffer) == NULL)
+		return EXIT_FAILURE;
+
+	ret = starpu_task_submit(t1);
+	STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_submit");
+
+	ret = starpu_task_wait(t2);
+	STARPU_CHECK_RETURN_VALUE(ret, "starpu_task_submit");
+
+	if (starpu_data_lookup(buffer) != NULL)
+		return EXIT_FAILURE;
+
+	starpu_shutdown();
+
+	return EXIT_SUCCESS;
+}

+ 14 - 0
tests/main/combined_workers/bfs/Makefile

@@ -0,0 +1,14 @@
+CFLAGS += $(shell pkg-config --cflags starpu-1.0) -g -O0 -Wall -Werror
+LDFLAGS += $(shell pkg-config --libs starpu-1.0) -g -O0 -Wall -Werror
+ 
+all: bfs
+ 
+bfs : bfs.o bfs_omp_func.o
+	g++ bfs.o bfs_omp_func.o $(CFLAGS) $(LDFLAGS) -fopenmp -O3 -o bfs
+bfs.o : bfs.cpp
+	g++ bfs.cpp $(CFLAGS) -fopenmp -O3 -c -o bfs.o
+bfs_omp_func.o : ./bfs_func/bfs_omp_func.cpp
+	g++ ./bfs_func/bfs_omp_func.cpp $(CFLAGS) -fopenmp -O3 -c -o bfs_omp_func.o
+ 
+clean:
+	rm -f bfs *.o *~

+ 249 - 0
tests/main/combined_workers/bfs/bfs.cpp

@@ -0,0 +1,249 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <limits.h>
+#include <starpu.h>
+#include "common.h"
+#include "timer.h"
+
+#define NB_ITERATION 10
+
+
+extern void omp_bfs_func(void *buffers[], void *_args);
+
+void Usage(int argc, char**argv){
+	fprintf(stderr,"Usage: %s <input_file>\n", argv[0]);
+}
+
+void read_file(char *input_f, unsigned int *nb_nodes, unsigned int *nb_edges,
+	       Node **origin_graph_nodes, bool **origin_graph_mask,
+	       bool **origin_updating_graph_mask, bool **origin_graph_visited,
+	       int **origin_graph_edges, int **origin_cost)
+{
+	FILE *fp;
+	int source = 0;
+
+	printf("Reading File\n");
+
+	//Read in Graph from a file
+	fp = fopen(input_f,"r");
+	if(!fp)
+	{
+		printf("Error Reading graph file\n");
+		exit(1);
+	}
+
+	fscanf(fp, "%u", nb_nodes);
+	
+	// allocate host memory
+	*origin_graph_nodes = (Node *) malloc(sizeof(Node) * (*nb_nodes));
+	*origin_graph_mask = (bool *) malloc(sizeof(bool) * (*nb_nodes));
+	*origin_updating_graph_mask = (bool *) malloc(sizeof(bool) * (*nb_nodes));
+	*origin_graph_visited = (bool *) malloc(sizeof(bool) * (*nb_nodes));
+
+	int start, edgeno;   
+	// initalize the memory
+	for( unsigned int i = 0; i < *nb_nodes; i++) 
+	{
+		fscanf(fp,"%d %d",&start,&edgeno);
+		(*origin_graph_nodes)[i].starting = start;
+		(*origin_graph_nodes)[i].no_of_edges = edgeno;
+		(*origin_graph_mask)[i]=false;
+		(*origin_updating_graph_mask)[i]=false;
+		(*origin_graph_visited)[i]=false;
+	}
+
+	//read the source node from the file
+	fscanf(fp, "%d", &source);
+	source=0;
+
+	//set the source node as true in the mask
+	(*origin_graph_mask)[source]=true;
+	(*origin_graph_visited)[source]=true;
+
+	fscanf(fp, "%u", nb_edges);
+
+	int id, cost;
+	*origin_graph_edges = (int*) malloc(sizeof(int) * (*nb_edges));
+	for(unsigned int i=0; i < *nb_edges ; i++)
+	{
+		fscanf(fp,"%d",&id);
+		fscanf(fp,"%d",&cost);
+		(*origin_graph_edges)[i] = id;
+	}
+    
+
+	// allocate mem for the result on host side
+	*origin_cost = (int*) malloc( sizeof(int)* (*nb_nodes));
+	for(unsigned int i = 0; i < (*nb_nodes); i++)
+		(*origin_cost)[i]=-1;
+	(*origin_cost)[source]=0;
+
+	fclose(fp);
+}
+
+//extern void omp_bfs_func(Node* h_graph_nodes, int* h_graph_edges, bool *h_graph_mask, bool *h_updating_graph_mask, bool *h_graph_visited, int* h_cost, int nb_nodes, int nb_edges);
+//extern void cuda_bfs_func(Node* h_graph_nodes, int* h_graph_edges, bool *h_graph_mask, bool *h_updating_graph_mask, bool *h_graph_visited, int* h_cost, int nb_nodes, int nb_edges);
+////////////////////////////////////////////////////////////////////////////////
+// Main Program
+////////////////////////////////////////////////////////////////////////////////
+int main( int argc, char** argv) 
+{
+	int ret;
+	char *input_f;
+	Timer timer;
+
+	unsigned int nb_nodes = 0, nb_edges = 0;
+
+	Node *origin_graph_nodes, *graph_nodes;
+	bool *origin_graph_mask, *graph_mask;
+	bool *origin_updating_graph_mask, *updating_graph_mask;
+	bool *origin_graph_visited, *graph_visited;
+	int *origin_graph_edges, *graph_edges;
+	int *origin_cost, *cost;
+
+	static struct starpu_perfmodel bfs_model;
+	static struct starpu_codelet bfs_cl;
+
+	bfs_model.type = STARPU_HISTORY_BASED;
+	bfs_model.symbol = "omp_bfs";
+
+	bfs_cl.modes[0] = STARPU_R;
+	bfs_cl.modes[1] = STARPU_R;
+	bfs_cl.modes[2] = STARPU_RW;
+	bfs_cl.modes[3] = STARPU_RW;
+	bfs_cl.modes[4] = STARPU_RW;
+	bfs_cl.modes[5] = STARPU_RW;
+	bfs_cl.where = STARPU_CPU;
+	bfs_cl.type = STARPU_FORKJOIN;
+	bfs_cl.max_parallelism = INT_MAX;
+	bfs_cl.cpu_funcs[0] = omp_bfs_func;
+	bfs_cl.cpu_funcs[1] = NULL;
+	bfs_cl.nbuffers = 6;
+	bfs_cl.model = &bfs_model;
+
+	starpu_data_handle_t graph_nodes_handle;
+	starpu_data_handle_t graph_edges_handle;
+	starpu_data_handle_t graph_mask_handle;
+	starpu_data_handle_t updating_graph_mask_handle;
+	starpu_data_handle_t graph_visited_handle;
+	starpu_data_handle_t cost_handle;
+
+	if(argc != 2){
+		Usage(argc, argv);
+		exit(1);
+	}
+    
+	input_f = argv[1];
+	read_file(input_f, &nb_nodes, &nb_edges, &origin_graph_nodes,
+		  &origin_graph_mask, &origin_updating_graph_mask,
+		  &origin_graph_visited, &origin_graph_edges, &origin_cost);
+
+	graph_nodes = (Node *) malloc(sizeof(Node)*nb_nodes);
+	graph_mask = (bool *) malloc(sizeof(bool)*nb_nodes);
+	updating_graph_mask = (bool *) malloc(sizeof(bool)*nb_nodes);
+	graph_visited = (bool *) malloc(sizeof(bool)*nb_nodes);
+	graph_edges = (int*) malloc(sizeof(int)*nb_edges);
+	cost = (int*) malloc( sizeof(int)*nb_nodes);
+
+	memcpy(graph_nodes, origin_graph_nodes, nb_nodes*sizeof(Node));
+	memcpy(graph_edges, origin_graph_edges, nb_edges*sizeof(int));
+
+	ret = starpu_init(NULL);
+	STARPU_CHECK_RETURN_VALUE(ret, "starpu_init");
+	
+	starpu_vector_data_register(&graph_nodes_handle, 0,
+				    (uintptr_t) graph_nodes, nb_nodes,
+				    sizeof(graph_nodes[0] ));
+	starpu_vector_data_register(&graph_edges_handle, 0,
+				    (uintptr_t)graph_edges, nb_edges,
+				    sizeof(graph_edges[0]));
+	starpu_vector_data_register(&graph_mask_handle, 0,
+				    (uintptr_t)graph_mask, nb_nodes,
+				    sizeof(graph_mask[0] ));
+	starpu_vector_data_register(&updating_graph_mask_handle, 0,
+				    (uintptr_t)updating_graph_mask,
+				    nb_nodes,
+				    sizeof(updating_graph_mask[0]));
+	starpu_vector_data_register(&graph_visited_handle, 0,
+				    (uintptr_t)graph_visited, nb_nodes,
+				    sizeof(graph_visited[0]));
+	starpu_vector_data_register(&cost_handle, 0, (uintptr_t)cost,
+				    nb_nodes, sizeof(cost[0]));
+	
+	for(int it=0; it < NB_ITERATION; it++)
+	{
+		starpu_data_acquire(graph_mask_handle, STARPU_W);
+		starpu_data_acquire(updating_graph_mask_handle, STARPU_W);
+		starpu_data_acquire(graph_visited_handle, STARPU_W);
+		starpu_data_acquire(cost_handle, STARPU_W);
+
+		memcpy(graph_mask, origin_graph_mask, nb_nodes * sizeof(bool));
+		memcpy(updating_graph_mask, origin_updating_graph_mask, nb_nodes * sizeof(bool));
+		memcpy(graph_visited, origin_graph_visited, nb_nodes * sizeof(bool));
+		memcpy(cost, origin_cost, nb_nodes * sizeof(int));
+
+		starpu_data_release(graph_mask_handle);
+		starpu_data_release(updating_graph_mask_handle);
+		starpu_data_release(graph_visited_handle);
+		starpu_data_release(cost_handle);
+
+		struct starpu_task *task = starpu_task_create();
+
+		task->cl = &bfs_cl;
+
+		task->handles[0] = graph_nodes_handle;
+		task->handles[1] = graph_edges_handle;
+		task->handles[2] = graph_mask_handle;
+		task->handles[3] = updating_graph_mask_handle;
+		task->handles[4] = graph_visited_handle;
+		task->handles[5] = cost_handle;
+
+		task->synchronous = 1;
+
+		printf("Start traversing the tree\n");
+
+		timer.start();
+
+		ret = starpu_task_submit(task);
+		STARPU_CHECK_RETURN_VALUE(ret, "starpu_init");
+
+		timer.stop();
+	}
+
+	starpu_data_unregister(graph_nodes_handle);
+	starpu_data_unregister(graph_edges_handle);
+	starpu_data_unregister(graph_mask_handle);
+	starpu_data_unregister(updating_graph_mask_handle);
+	starpu_data_unregister(graph_visited_handle);
+	starpu_data_unregister(cost_handle);
+
+	starpu_shutdown();
+
+	printf("File: %s, Avergae Time: %f, Total time: %f\n", input_f,
+	       timer.getAverageTime(), timer.getTotalTime());
+
+	//Store the result into a file
+	FILE *fpo = fopen("result.txt","w");
+	for(unsigned int i=0;i<nb_nodes;i++)
+		fprintf(fpo,"%d) cost:%d\n", i, cost[i]);
+	fclose(fpo);
+	printf("Result stored in result.txt\n");
+
+
+	// cleanup memory
+	free(graph_nodes);
+	free(graph_edges);
+	free(graph_mask);
+	free(updating_graph_mask);
+	free(graph_visited);
+	free(cost);
+	free(origin_graph_nodes);
+	free(origin_graph_edges);
+	free(origin_graph_mask);
+	free(origin_updating_graph_mask);
+	free(origin_graph_visited);
+	free(origin_cost);
+
+}

+ 63 - 0
tests/main/combined_workers/bfs/bfs_func/bfs_omp_func.cpp

@@ -0,0 +1,63 @@
+#include "../common.h"
+#include <starpu.h>
+#include <omp.h>
+
+#include <stdio.h>
+
+void omp_bfs_func(void *buffers[], void *_args)
+{
+	Node* graph_nodes = (Node *) STARPU_VECTOR_GET_PTR(buffers[0]);
+	int no_of_nodes = STARPU_VECTOR_GET_NX(buffers[0]);
+	int* graph_edges = (int *) STARPU_VECTOR_GET_PTR(buffers[1]);
+	bool *graph_mask = (bool *) STARPU_VECTOR_GET_PTR(buffers[2]);
+	bool *updating_graph_mask = (bool *) STARPU_VECTOR_GET_PTR(buffers[3]);
+	bool *graph_visited = (bool *) STARPU_VECTOR_GET_PTR(buffers[4]);
+	int* cost = (int *) STARPU_VECTOR_GET_PTR(buffers[5]);
+	int k=0;
+    
+	bool stop;
+	do
+	{
+		//if no thread changes this value then the loop stops
+		stop=false;
+
+#ifdef OPEN
+		#pragma omp parallel for num_threads(starpu_combined_worker_get_size())
+#endif 
+		for(int tid = 0; tid < no_of_nodes; tid++ )
+		{
+			if (graph_mask[tid] == true)
+			{ 
+				graph_mask[tid]=false;
+				for(int i=graph_nodes[tid].starting; i<(graph_nodes[tid].no_of_edges + graph_nodes[tid].starting); i++)
+				{
+					int id = graph_edges[i];
+					if(!graph_visited[id])
+						{
+						cost[id]=cost[tid]+1;
+						updating_graph_mask[id]=true;
+						}
+				}
+			}
+		}
+
+  		for(int tid=0; tid< no_of_nodes ; tid++ )
+		{
+			if (updating_graph_mask[tid] == true){
+			graph_mask[tid]=true;
+			graph_visited[tid]=true;
+			stop=true;
+			updating_graph_mask[tid]=false;
+			}
+		}
+		k++;
+	}
+	while(stop);
+	
+	printf("Kernel Executed %d times, threads: %d\n",k, starpu_combined_worker_get_size());
+	//printf("graph_edges = %d, %d, %d\n",graph_edges[0], graph_edges[1], graph_edges[2]);
+	//printf("graph_mask = %d, %d, %d\n",graph_mask[0], graph_mask[1], graph_mask[2]);
+	//printf("updating_graph_mask = %d, %d, %d\n",updating_graph_mask[0], updating_graph_mask[1], updating_graph_mask[2]);
+	//printf("graph_visited = %d, %d, %d\n",graph_visited[0], graph_visited[1], graph_visited[2]);
+	//printf("Cost = %d, %d, %d\n",cost[0], cost[1], cost[2]);
+}

+ 17 - 0
tests/main/combined_workers/bfs/common.h

@@ -0,0 +1,17 @@
+#ifndef COMMON_BFS_H
+#define COMMON_BFS_H
+
+
+#define MAX_THREADS_PER_BLOCK 512
+
+#define OPEN
+
+
+//Structure to hold a node information
+struct Node
+{
+	int starting;
+	int no_of_edges;
+};
+
+#endif

文件差异内容过多而无法显示
+ 458757 - 0
tests/main/combined_workers/bfs/data/graph65536.txt


+ 13 - 0
tests/main/combined_workers/bfs/run.sh

@@ -0,0 +1,13 @@
+#export STARPU_GENERATE_TRACE=1
+#export GOMP_CPU_AFFINITY="0 6 1 7 2 8 3 9 4 10 5 11"
+#export OMP_WAIT_POLICY=PASSIVE
+export STARPU_SCHED=pheft
+export STARPU_NCPUS=12
+export STARPU_SINGLE_COMBINED_WORKER=1
+export STARPU_MIN_WORKERSIZE=12
+export STARPU_MAX_WORKERSIZE=12
+export STARPU_NCUDA=0
+export STARPU_NOPENCL=0
+export STARPU_WORKER_STATS=1
+export STARPU_CALIBRATE=1
+./bfs data/graph65536.txt

+ 20 - 0
tests/main/combined_workers/bfs/temp.patch

@@ -0,0 +1,20 @@
+Index: src/core/topology.c
+===================================================================
+--- src/core/topology.c	(revision 6542)
++++ src/core/topology.c	(working copy)
+@@ -682,10 +682,13 @@
+ 	support = hwloc_topology_get_support(config->topology.hwtopology);
+ 	if (support->cpubind->set_thisthread_cpubind)
+ 	{
+-		hwloc_cpuset_t set = combined_worker->hwloc_cpu_set;
++		hwloc_cpuset_t set = hwloc_bitmap_alloc();
++		hwloc_bitmap_zero(set);
++		hwloc_bitmap_set_range(set, 0, 12);
++		//hwloc_cpuset_t set = combined_worker->hwloc_cpu_set;
+ 		int ret;
+ 
+-		ret = hwloc_set_cpubind(config->topology.hwtopology, set, HWLOC_CPUBIND_THREAD);
++		ret = hwloc_set_cpubind(config->topology.hwtopology, set, HWLOC_CPUBIND_PROCESS | HWLOC_CPUBIND_NOMEMBIND);
+ 		if (ret)
+ 		{
+ 			perror("binding thread");

+ 216 - 0
tests/main/combined_workers/bfs/timer.h

@@ -0,0 +1,216 @@
+/*! \file timer_linux.h
+ *  \brief Contains timer class that can be used by Linux systems.
+ */
+
+#ifndef TIMER_LINUX_H
+#define TIMER_LINUX_H
+
+#include <sys/time.h>
+#include <iostream>
+#include <vector>
+
+
+class Timer
+{
+
+private:
+    timeval timerStart;
+    timeval timerEnd;
+
+
+    
+    std::vector<double> multi_time; // used for estimating multi backends.
+    std::vector<double> time;
+    bool record_multi;
+    
+    
+    void addMultiMaxTime() // used to estimate when using multi-Backend
+    {
+	double max = 0.0f; 
+	//std::cout<<"AddMultiMaxTime call before"<<time.size()<<"\n";
+	if(multi_time.empty())
+	  return;
+	for(std::vector<double>::iterator it = multi_time.begin(); it != multi_time.end(); ++it)
+        {
+	  if (max < *it) 
+	      max = *it;
+	}
+        time.push_back( max );
+	//std::cout<<"MAXXX:"<<max<<" ";
+	
+	multi_time.clear();  // clear it in both cases.
+	//std::cout<<"AddMultiMaxTime call after reset"<<time.size()<<"\n";
+    }
+    
+    void addMultiMinTime() // used to estimate when using multi-Backend
+    {
+	double min = 0.0f; 
+	if(multi_time.empty())
+	  return;
+	for(std::vector<double>::iterator it = multi_time.begin(); it != multi_time.end(); ++it)
+        {
+	  if (min > *it) 
+	      min = *it;
+	}
+        time.push_back( min );
+	
+	multi_time.clear();  // clear it in both cases.
+    }
+    
+public:
+
+      
+     void start_record_multi()
+     {
+       record_multi=true;
+       multi_time.clear();  // clear it in both cases.
+     }
+     
+     void stop_record_multi()
+     {
+       addMultiMaxTime();
+       record_multi=false;
+     }
+  
+    Timer() {record_multi=false;}
+
+    /*!
+     *  Starts the timimg.
+     */
+    void start()
+    {
+        gettimeofday(&timerStart, NULL);
+	//std::cout<<"start_\n";
+    }
+
+    /*!
+     *  Stops the timimg and stores time in a vector.
+     */
+    void stop()
+    {
+        gettimeofday(&timerEnd, NULL);
+	if(record_multi)
+	  multi_time.push_back( (timerEnd.tv_sec - timerStart.tv_sec + (timerEnd.tv_usec - timerStart.tv_usec) / 1000000.0) * 1000 );
+	else 
+	  time.push_back( (timerEnd.tv_sec - timerStart.tv_sec + (timerEnd.tv_usec - timerStart.tv_usec) / 1000000.0) * 1000 );
+	//std::cout<<"stop_\n";
+    }
+
+    /*!
+     *  Clears all timings taken.
+     */
+    void reset()
+    {
+      if(!record_multi)
+      {
+//	std::cout<<"Time reset:\n";
+        time.clear();
+      }
+      
+      multi_time.clear();  // clear it in both cases.
+      
+    }
+    
+    
+    
+
+    /*!
+     *  \param run The run to get timing of.
+     *
+     *  \return Time for a certain run.
+     */
+    double getTime(int run = 0)
+    {
+        return time.at(run);
+    }
+
+    /*!
+     *  \return Total time of all stored runs.
+     */
+    double getTotalTime()
+    {
+        double totalTime = 0.0f;
+
+        for(std::vector<double>::iterator it = time.begin(); it != time.end(); ++it)
+        {
+            totalTime += *it;
+        }
+
+        return totalTime;
+    }
+
+    /*!
+     *  \return Average time of all stored runs.
+     */
+    double getAverageTime()
+    {
+        double totalTime = 0.0f;
+
+        for(std::vector<double>::iterator it = time.begin(); it != time.end(); ++it)
+        {
+            totalTime += *it;
+        }
+
+        return (double)(totalTime/time.size());
+    }
+    
+    double getMaxTime()
+    {
+        double max = 0.0f; 
+	for(std::vector<double>::iterator it = time.begin(); it != time.end(); ++it)
+        {
+	  if (max < *it) 
+	      max = *it;
+	}
+	return max;
+    }
+    
+    double getMinTime()
+    {
+        double min = 0.0f; 
+	for(std::vector<double>::iterator it = time.begin(); it != time.end(); ++it)
+        {
+	  if (min > *it) 
+	      min = *it;
+	}
+	
+	return min;
+    }
+
+    /*!
+     *  \return The resolution of the timer in micro seconds.
+     */
+    double getResolutionUs()
+    {
+        double result = 0.0f;
+        timeval tStart;
+        timeval tEnd;
+        gettimeofday(&tStart, NULL);
+        gettimeofday(&tEnd, NULL);
+        int delay = 0;
+
+        do
+        {
+            delay++;
+            gettimeofday(&tStart, NULL);
+            for(int i = 0; i < delay; ++i) ;
+            gettimeofday(&tEnd, NULL);
+
+            result = ((((double)tEnd.tv_sec)*1000000.0) + ((double)tEnd.tv_usec)) - ((((double)tStart.tv_sec)*1000000.0) + ((double)tStart.tv_usec));
+
+        } while(result == 0);
+
+        return result;
+    }
+
+    /*!
+     *  \return Number of runs stored in timer.
+     */
+    int getNumTimings()
+    {
+        return time.size();
+    }
+};
+
+
+#endif

+ 37 - 16
tests/main/driver_api/init_run_deinit.c

@@ -1,3 +1,19 @@
+/* StarPU --- Runtime system for heterogeneous multicore architectures.
+ *
+ * Copyright (C) 2012 Inria
+ *
+ * StarPU is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * StarPU is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * See the GNU Lesser General Public License in COPYING.LGPL for more details.
+ */
+
 #include <starpu.h>
 #include <starpu_opencl.h>
 
@@ -42,7 +58,7 @@ run(struct starpu_task *task, struct starpu_driver *d)
 static void
 deinit_driver(struct starpu_driver *d)
 {
-	int ret; 
+	int ret;
 	ret = starpu_driver_deinit(d);
 	STARPU_CHECK_RETURN_VALUE(ret, "starpu_driver_deinit");
 }
@@ -58,7 +74,7 @@ test_cpu(void)
 	ret = starpu_conf_init(&conf);
 	if (ret == -EINVAL)
 		return 1;
-	
+
 
 	struct starpu_driver d =
 	{
@@ -74,7 +90,7 @@ test_cpu(void)
 		return STARPU_TEST_SKIPPED;
 
 	init_driver(&d);
-	int i;	
+	int i;
 	for (i = 0; i < NTASKS; i++)
 	{
 		struct starpu_task *task;
@@ -90,7 +106,7 @@ test_cpu(void)
 	starpu_task_wait_for_all();
 	starpu_shutdown();
 
-	fprintf(stderr, "[CPU] Var is %d\n", var);
+	FPRINTF(stderr, "[CPU] Var is %d\n", var);
 	return !!(var != NTASKS);
 }
 #endif /* STARPU_USE_CPU */
@@ -99,13 +115,13 @@ test_cpu(void)
 static int
 test_cuda(void)
 {
-	int var = 0, ret;
+	int var = 0, ret, ncuda;
 	struct starpu_conf conf;
 
 	ret = starpu_conf_init(&conf);
 	if (ret == -EINVAL)
 		return 1;
-	
+
 
 	struct starpu_driver d =
 	{
@@ -122,9 +138,12 @@ test_cuda(void)
 	if (ret == -ENODEV)
 		return STARPU_TEST_SKIPPED;
 
+	ncuda = starpu_cuda_worker_get_count();
+	if (ncuda == 0)
+		return STARPU_TEST_SKIPPED;
 
 	init_driver(&d);
-	int i;	
+	int i;
 	for (i = 0; i < NTASKS; i++)
 	{
 		struct starpu_task *task;
@@ -140,7 +159,7 @@ test_cuda(void)
 	starpu_task_wait_for_all();
 	starpu_shutdown();
 
-	fprintf(stderr, "[CUDA] Var is %d\n", var);
+	FPRINTF(stderr, "[CUDA] Var is %d\n", var);
 	return !!(var != NTASKS);
 }
 #endif /* STARPU_USE_CUDA */
@@ -152,20 +171,19 @@ test_opencl(void)
         cl_int err;
         cl_platform_id platform;
         cl_uint dummy;
+	int nopencl;
 
         err = clGetPlatformIDs(1, &platform, &dummy);
         if (err != CL_SUCCESS)
-        {   
-                fprintf(stderr, "%s:%d\n", __func__, __LINE__);
-		return 1;
+        {
+		return STARPU_TEST_SKIPPED;
 	}
 
 	cl_device_id device_id;
         err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device_id, NULL);
         if (err != CL_SUCCESS)
-        {   
-                fprintf(stderr, "%s:%d\n", __func__, __LINE__);
-		return 1;
+        {
+		return STARPU_TEST_SKIPPED;
 	}
 
 	int var = 0, ret;
@@ -174,7 +192,7 @@ test_opencl(void)
 	ret = starpu_conf_init(&conf);
 	if (ret == -EINVAL)
 		return 1;
-	
+
 	struct starpu_driver d =
 	{
 		.type = STARPU_OPENCL_WORKER,
@@ -190,9 +208,12 @@ test_opencl(void)
 	if (ret == -ENODEV)
 		return STARPU_TEST_SKIPPED;
 
+	nopencl = starpu_opencl_worker_get_count();
+	if (nopencl == 0)
+		return STARPU_TEST_SKIPPED;
 
 	init_driver(&d);
-	int i;	
+	int i;
 	for (i = 0; i < NTASKS; i++)
 	{
 		struct starpu_task *task;

+ 258 - 0
tests/main/driver_api/run_driver.c

@@ -0,0 +1,258 @@
+/* StarPU --- Runtime system for heterogeneous multicore architectures.
+ *
+ * Copyright (C) 2012 Inria
+ *
+ * StarPU is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * StarPU is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * See the GNU Lesser General Public License in COPYING.LGPL for more details.
+ */
+
+#include <starpu.h>
+#include <pthread.h>
+#ifdef STARPU_USE_OPENCL
+#include <starpu_opencl.h>
+#endif
+
+#include "../../helper.h"
+
+/*
+ * Users can directly control drivers by using the starpu_driver* functions.
+ * 
+ * This test makes sure that the starpu_driver_run function works for CPU, CUDA
+ * and OpenCL drivers, and that the starpu_drivers_request_termination function
+ * correctly shuts down all drivers.
+ *
+ * The test_* functions can return:
+ * - 0 (success)
+ * - 1 (failure)
+ * - STARPU_TEST_SKIPPED (non-critical errors)
+ */
+
+#if defined(STARPU_USE_CPU) || defined(STARPU_USE_CUDA) || defined(STARPU_USE_OPENCL)
+static void
+dummy(void *buffers[], void *args)
+{
+	(void) buffers;
+	(*(int *)args)++;
+}
+
+static struct starpu_codelet cl =
+{
+	.cpu_funcs    = { dummy, NULL },
+	.cuda_funcs   = { dummy, NULL },
+	.opencl_funcs = { dummy, NULL },
+	.nbuffers     = 0
+};
+
+static void *
+run_driver(void *arg)
+{
+	struct starpu_driver *d = (struct starpu_driver *) arg;
+	int ret = starpu_driver_run(d);
+	STARPU_CHECK_RETURN_VALUE(ret, "starpu_driver_run");
+	return NULL;
+}
+#endif /* STARPU_USE_CPU || STARPU_USE_CUDA || STARPU_USE_OPENCL */
+
+#ifdef STARPU_USE_CPU
+static int
+test_cpu(void)
+{
+	int ret, var = 0;
+	static pthread_t driver_thread;
+	struct starpu_conf conf;
+	struct starpu_driver d =
+	{
+		.type = STARPU_CPU_WORKER,
+		.id.cpu_id = 0
+	};
+
+	starpu_conf_init(&conf);
+	conf.n_not_launched_drivers = 1;
+	conf.not_launched_drivers = &d;
+	conf.ncpus = 1;
+	ret = starpu_init(&conf);
+	if (ret == -ENODEV || starpu_cpu_worker_get_count() == 0)
+		return STARPU_TEST_SKIPPED;
+
+	ret = pthread_create(&driver_thread, NULL, run_driver, &d);
+	if (ret != 0)
+	{
+		ret = 1;
+		goto out;
+	}
+
+	struct starpu_task *task;
+	task = starpu_task_create();
+	cl.where = STARPU_CPU;
+	task->cl = &cl;
+	task->cl_arg = &var;
+	task->synchronous = 1;
+	ret = starpu_task_submit(task);
+	if (ret == -ENODEV)
+	{
+		ret = STARPU_TEST_SKIPPED;
+		goto out;
+	}
+
+	FPRINTF(stderr, "[CPU] Var = %d\n", var);
+	ret = !!(var != 1);
+
+out:
+	starpu_drivers_request_termination();
+	if (pthread_join(driver_thread, NULL) != 0)
+		return 1;
+	starpu_shutdown();
+	return ret;
+}
+#endif /* STARPU_USE_CPU */
+
+#ifdef STARPU_USE_CUDA
+static int
+test_cuda(void)
+{
+	int ret, var = 0;
+	static pthread_t driver_thread;
+	struct starpu_conf conf;
+	struct starpu_driver d =
+	{
+		.type = STARPU_CUDA_WORKER,
+		.id.cuda_id = 0
+	};
+
+	starpu_conf_init(&conf);
+	conf.n_not_launched_drivers = 1;
+	conf.not_launched_drivers = &d;
+	conf.ncuda = 1;
+	ret = starpu_init(&conf);
+	if (ret == -ENODEV || starpu_cuda_worker_get_count() == 0)
+		return STARPU_TEST_SKIPPED;
+
+	ret = pthread_create(&driver_thread, NULL, run_driver, &d);
+	if (ret == -1)
+	{
+		ret = 1;
+		goto out;
+	}
+
+	struct starpu_task *task;
+	task = starpu_task_create();
+	cl.where = STARPU_CUDA;
+	task->cl = &cl;
+	task->cl_arg = &var;
+	task->synchronous = 1;
+	ret = starpu_task_submit(task);
+	if (ret == -ENODEV)
+	{
+		ret = STARPU_TEST_SKIPPED;
+		goto out;
+	}
+
+	FPRINTF(stderr, "[CUDA] Var = %d\n", var);
+	ret = !!(var != 1);
+
+out:
+	starpu_drivers_request_termination();
+	if (pthread_join(driver_thread, NULL) != 0)
+		return 1;
+	starpu_shutdown();
+	return ret;
+}
+#endif /* STARPU_USE_CUDA */
+
+#ifdef STARPU_USE_OPENCL
+static int
+test_opencl(void)
+{
+	int ret, var = 0;
+	static pthread_t driver_thread;
+	struct starpu_conf conf;
+
+	cl_int err;
+        cl_uint dummy;
+        cl_platform_id platform;
+        err = clGetPlatformIDs(1, &platform, &dummy);
+        if (err != CL_SUCCESS)
+		return STARPU_TEST_SKIPPED;
+
+	cl_device_id device_id;
+	int device_type = CL_DEVICE_TYPE_GPU; /* TODO Support CPU */
+        err = clGetDeviceIDs(platform, device_type, 1, &device_id, NULL);
+        if (err != CL_SUCCESS)
+		return STARPU_TEST_SKIPPED;
+
+	struct starpu_driver d =
+	{
+		.type = STARPU_OPENCL_WORKER,
+		.id.opencl_id = device_id
+	};
+
+	starpu_conf_init(&conf);
+	conf.n_not_launched_drivers = 1;
+	conf.not_launched_drivers = &d;
+	conf.ncuda = 0;
+	conf.nopencl = 1;
+	ret = starpu_init(&conf);
+	if (ret == -ENODEV || starpu_opencl_worker_get_count() == 0)
+		return STARPU_TEST_SKIPPED;
+
+	ret = pthread_create(&driver_thread, NULL, run_driver, &d);
+	if (ret == -1)
+	{
+		ret = 1;
+		goto out;
+	}
+
+	struct starpu_task *task;
+	task = starpu_task_create();
+	cl.where = STARPU_OPENCL;
+	task->cl = &cl;
+	task->cl_arg = &var;
+	task->synchronous = 1;
+	ret = starpu_task_submit(task);
+	if (ret == -ENODEV)
+	{
+		ret = STARPU_TEST_SKIPPED;
+		goto out;
+	}
+
+	FPRINTF(stderr, "[OpenCL] Var = %d\n", var);
+	ret = !!(var != 1);
+
+out:
+	starpu_drivers_request_termination();
+	if (pthread_join(driver_thread, NULL) != 0)
+		return 1;
+	starpu_shutdown();
+	return ret;
+}
+#endif /* STARPU_USE_OPENCL */
+
+int
+main(void)
+{
+	int ret = STARPU_TEST_SKIPPED;
+#ifdef STARPU_USE_CPU
+	ret = test_cpu();
+	if (ret == 1)
+		return 1;
+#endif
+#ifdef STARPU_USE_CUDA
+	ret = test_cuda();
+	if (ret == 1)
+		return 1;
+#endif
+#ifdef STARPU_USE_OPENCL
+	ret = test_opencl();
+	if (ret == 1)
+		return 1;
+#endif
+	return ret;
+}

+ 4 - 4
tests/sched_policies/simple_deps.c

@@ -72,15 +72,15 @@ run(struct starpu_sched_policy *policy)
 
 	starpu_task_wait_for_all();
 
-	double t1, t2;
-	t1 = starpu_timing_timespec_to_us(&task1->profiling_info->end_time);
-	t2 = starpu_timing_timespec_to_us(&task0->profiling_info->start_time);
+	double task1_end, task0_start;
+	task1_end   = starpu_timing_timespec_to_us(&task1->profiling_info->end_time);
+	task0_start = starpu_timing_timespec_to_us(&task0->profiling_info->start_time);
 
 	starpu_task_destroy(task0);
 	starpu_task_destroy(task1);
 	starpu_shutdown();
 
-	return t1 < t2 ? 0:1;
+	return !!(task1_end > task0_start);
 
 enodev:
 	starpu_shutdown();

+ 1 - 1
tools/dev/starpu_check_undocumented.sh

@@ -26,7 +26,7 @@ functions=$(spatch -very_quiet -sp_file tools/dev/starpu_funcs.cocci $(find incl
 for func in $functions ; do
 	fname=$(echo $func|awk -F ',' '{print $1}')
 	location=$(echo $func|awk -F ',' '{print $2}')
-	x=$(grep $fname doc/starpu.texi doc/chapters/*texi | grep deftypefun)
+	x=$(grep "$fname (" doc/starpu.texi doc/chapters/*texi | grep deftypefun)
 	if test "$x" == "" ; then
 		echo "function ${redcolor}${fname}${stcolor} at location ${redcolor}$location${stcolor} is not (or incorrectly) documented"
 #	else