From patchwork Fri Jan 17 20:22:21 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Norris X-Patchwork-Id: 312202 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id E72D22C0092 for ; Sat, 18 Jan 2014 07:22:42 +1100 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:subject:content-type; q= dns; s=default; b=VJ0wG4gSf8PXoW37/dedWuoBVjQd4X8hlJ5EIB8uijUtb1 WuBrROMWS+e7rKRyDr7N7i9yXTb8TXKh5AVov1kLGxADaFhrFSJHTtKccY2sHQRP csMzL9N7U3XS9ZL9yndDR0ga7CFq/QNteX7gh1teL9gtlyYL2wtJjpY7k5ClM= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:subject:content-type; s= default; bh=lD+itgEyod8tC1SXnWWMrcRTHpM=; b=mg6vG6/Wk5vLf45zsRO2 o9j+/03NkLgi1MNTb9S9/whakErGOGcYN6KYNvymOqwy2zm4II3HSq2PoasbPPeM 9o+/QEyAnOumisaNoPR+A5jdSOZFRXqWRD2pU4qu9n/C2cL/J3iYXPVF8l+0yRfq 5W23zsPFohvaMn0beldQgOY= Received: (qmail 1898 invoked by alias); 17 Jan 2014 20:22:34 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 1884 invoked by uid 89); 17 Jan 2014 20:22:33 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.4 required=5.0 tests=AWL, BAYES_00 autolearn=ham version=3.3.2 X-HELO: relay1.mentorg.com Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 17 Jan 2014 20:22:30 +0000 Received: from svr-orw-exc-10.mgc.mentorg.com ([147.34.98.58]) by relay1.mentorg.com with esmtp id 1W4Fvu-00022W-1A from James_Norris@mentor.com for gcc-patches@gcc.gnu.org; Fri, 17 Jan 2014 12:22:26 -0800 Received: from SVR-ORW-FEM-02.mgc.mentorg.com ([147.34.96.206]) by SVR-ORW-EXC-10.mgc.mentorg.com with Microsoft SMTPSVC(6.0.3790.4675); Fri, 17 Jan 2014 12:22:24 -0800 Received: from jupiter.gateway.2wire.net (147.34.91.1) by svr-orw-fem-02.mgc.mentorg.com (147.34.96.168) with Microsoft SMTP Server id 14.2.247.3; Fri, 17 Jan 2014 12:22:22 -0800 Message-ID: <52D990FD.3010502@codesourcery.com> Date: Fri, 17 Jan 2014 14:22:21 -0600 From: James Norris User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130625 Thunderbird/17.0.7 MIME-Version: 1.0 To: Subject: [gomp4] Generalize mapping functions for future OpenACC runtime library usage. X-IsSubscribed: yes Hi! Here is a patch that changes the mapping functions to use functions defined with the device descriptor. These changes generalize the mapping functions so that they can be used by the soon to be added OpenACC Runtime functions. These changes assume that the previous set of changes described in: http://gcc.gnu.org/ml/gcc-patches/2013-12/msg00527.html, have been applied. Would appreciate a review of the changes. Thanks! Change mapping functionality to use handlers defined by device descriptor. These changes are required for the addition of the OpenACC Runtime Library. * ialias.h: New file * libgomp.h: Remove definitions and include file from where definitions now reside. * splay-tree.c: Add forward reference to splay_compare, replace call to abort with call to gomp_fatal, and fix comment formatting. * splay-tree.h: Remove inclusion of header file, add definition for splay_tree_key_s, remove splay_compare definition, and fix a typo. * target.c: Remove inclusion of unused header files, add inclusion of header file target.h, remove definition of structures: target_mem_desc and gomp_device_desc, and fix comment formatting. (gomp_map_vars, gomp_unmap_tgt, gomp_update): Replace calls with corresponding calls defined by device descriptor (gomp_device_descr). (gomp_find_available_plugins): Replace call to realloc with call to gomp_realloc and add assignments for new device descriptor operations. * target.h: Remove structure definiton splay_tree_key_s, add structure definition target_mem_desc and gomp_device_desc, add new function handlers to gomp_device_descr. diff --git a/libgomp/ialias.h b/libgomp/ialias.h new file mode 100644 index 0000000..167907b --- /dev/null +++ b/libgomp/ialias.h @@ -0,0 +1,52 @@ +/* Copyright (C) 2013 Free Software Foundation, Inc. + Contributed by Jakub Jelinek . + + This file is part of the GNU OpenMP Library (libgomp). + + Libgomp is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + Libgomp 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 General Public License for + more details. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + . */ + +/* Defines shared between OpenACC and OpenMP */ + +#ifndef IALIAS_H +#define IALIAS_H 1 + +#ifdef HAVE_ATTRIBUTE_VISIBILITY +# define attribute_hidden __attribute__ ((visibility ("hidden"))) +#else +# define attribute_hidden +#endif + +#ifdef HAVE_ATTRIBUTE_ALIAS +# define ialias_ulp ialias_str1(__USER_LABEL_PREFIX__) +# define ialias_str1(x) ialias_str2(x) +# define ialias_str2(x) #x +# define ialias(fn) \ + extern __typeof (fn) goacc_ialias_##fn \ + __attribute__ ((alias (#fn))) attribute_hidden; +# define ialias_redirect(fn) \ + extern __typeof (fn) fn __asm__ (ialias_ulp "goacc_ialias_" #fn) attribute_hidden; +# define ialias_call(fn) goacc_ialias_ ## fn +#else +# define ialias(fn) +# define ialias_redirect(fn) +# define ialias_call(fn) fn +#endif + +#endif /* IALIAS_H */ diff --git a/libgomp/libgomp.h b/libgomp/libgomp.h index bdc0486..933ed23 100644 --- a/libgomp/libgomp.h +++ b/libgomp/libgomp.h @@ -675,26 +675,6 @@ extern int gomp_test_nest_lock_25 (omp_nest_lock_25_t *) __GOMP_NOTHROW; # define gomp_test_nest_lock_30 omp_test_nest_lock #endif -#ifdef HAVE_ATTRIBUTE_VISIBILITY -# define attribute_hidden __attribute__ ((visibility ("hidden"))) -#else -# define attribute_hidden -#endif - -#ifdef HAVE_ATTRIBUTE_ALIAS -# define ialias_ulp ialias_str1(__USER_LABEL_PREFIX__) -# define ialias_str1(x) ialias_str2(x) -# define ialias_str2(x) #x -# define ialias(fn) \ - extern __typeof (fn) gomp_ialias_##fn \ - __attribute__ ((alias (#fn))) attribute_hidden; -# define ialias_redirect(fn) \ - extern __typeof (fn) fn __asm__ (ialias_ulp "gomp_ialias_" #fn) attribute_hidden; -# define ialias_call(fn) gomp_ialias_ ## fn -#else -# define ialias(fn) -# define ialias_redirect(fn) -# define ialias_call(fn) fn -#endif +#include "ialias.h" #endif /* LIBGOMP_H */ diff --git a/libgomp/splay-tree.c b/libgomp/splay-tree.c index fc929f9..fe5596d 100644 --- a/libgomp/splay-tree.c +++ b/libgomp/splay-tree.c @@ -43,11 +43,12 @@ typedef struct splay_tree_key_s *splay_tree_key; The major feature of splay trees is that all basic tree operations are amortized O(log n) time for a tree with n nodes. */ -/* Forward declaration for a node in the tree. */ typedef struct splay_tree_node_s *splay_tree_node; typedef struct splay_tree_s *splay_tree; typedef struct splay_tree_key_s *splay_tree_key; +extern int splay_compare (splay_tree_key, splay_tree_key); + #include "libgomp.h" #include "splay-tree.h" @@ -155,7 +156,7 @@ splay_tree_insert (splay_tree sp, splay_tree_node node) comparison = splay_compare (&sp->root->key, &node->key); if (sp->root && comparison == 0) - abort (); + gomp_fatal ("Duplicate node"); else { /* Insert it at the root. */ diff --git a/libgomp/splay-tree.h b/libgomp/splay-tree.h index 3a5d23e..db36419 100644 --- a/libgomp/splay-tree.h +++ b/libgomp/splay-tree.h @@ -43,10 +43,23 @@ typedef struct splay_tree_key_s *splay_tree_key; The major feature of splay trees is that all basic tree operations are amortized O(log n) time for a tree with n nodes. */ -#include "target.h" - #ifndef _SPLAY_TREE_H -#define _SPLAY_TREE_H +#define _SPLAY_TREE_H 1 + +struct splay_tree_key_s { + /* Address of the host object. */ + uintptr_t host_start; + /* Address immediately after the host object. */ + uintptr_t host_end; + /* Descriptor of the target memory. */ + struct target_mem_desc *tgt; + /* Offset from tgt->tgt_start to the start of the target object. */ + uintptr_t tgt_offset; + /* Reference count. */ + uintptr_t refcount; + /* True if data should be copied from device to host at the end. */ + bool copy_from; +}; /* The nodes in the splay tree. */ struct splay_tree_node_s { @@ -64,6 +77,5 @@ struct splay_tree_s { attribute_hidden splay_tree_key splay_tree_lookup (splay_tree, splay_tree_key); attribute_hidden void splay_tree_insert (splay_tree, splay_tree_node); attribute_hidden void splay_tree_remove (splay_tree, splay_tree_key); -attribute_hidden int splay_compare (splay_tree_key, splay_tree_key); #endif /* _SPLAY_TREE_H */ diff --git a/libgomp/target.c b/libgomp/target.c index 14ec3d0..37929b8 100644 --- a/libgomp/target.c +++ b/libgomp/target.c @@ -26,9 +26,6 @@ creation and termination. */ #include "libgomp.h" -#include -#include -#include #include #ifdef PLUGIN_SUPPORT @@ -40,41 +37,16 @@ static void gomp_target_init (void); static pthread_once_t gomp_is_initialized = PTHREAD_ONCE_INIT; -/* Forward declaration for a node in the tree. */ typedef struct splay_tree_node_s *splay_tree_node; typedef struct splay_tree_s *splay_tree; typedef struct splay_tree_key_s *splay_tree_key; -struct target_mem_desc { - /* Reference count. */ - uintptr_t refcount; - /* All the splay nodes allocated together. */ - splay_tree_node array; - /* Start of the target region. */ - uintptr_t tgt_start; - /* End of the targer region. */ - uintptr_t tgt_end; - /* Handle to free. */ - void *to_free; - /* Previous target_mem_desc. */ - struct target_mem_desc *prev; - /* Number of items in following list. */ - size_t list_count; - - /* Corresponding target device descriptor. */ - struct gomp_device_descr *device_descr; - - /* List of splay keys to remove (or decrease refcount) - at the end of region. */ - splay_tree_key list[]; -}; - -#include "target.h" +#include "splay-tree.h" -/* Array of descriptors of all available devices. */ +/* Array of descriptors of all available devices. */ static struct gomp_device_descr *devices; -/* Total number of available devices. */ +/* Total number of available devices. */ static int num_devices; /* The comparison function. */ @@ -92,30 +64,7 @@ splay_compare (splay_tree_key x, splay_tree_key y) return 0; } -#include "splay-tree.h" - -/* This structure describes accelerator device. - It contains name of the corresponding libgomp plugin, function handlers for - interaction with the device, ID-number of the device, and information about - mapped memory. */ -struct gomp_device_descr -{ - /* This is the ID number of device. It could be specified in DEVICE-clause of - TARGET construct. */ - int id; - - /* Plugin file handler. */ - void *plugin_handle; - - /* Function handlers. */ - bool (*device_available_func) (void); - - /* Splay tree containing information about mapped memory regions. */ - struct splay_tree_s dev_splay_tree; - - /* Mutex for operating with the splay tree and other shared structures. */ - gomp_mutex_t dev_env_lock; -}; +#include "target.h" attribute_hidden int gomp_get_num_devices (void) @@ -223,7 +172,7 @@ gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum, /* FIXME: This would be accelerator memory allocation, not host, and should allocate tgt_align aligned tgt_size block of memory. */ - tgt->to_free = gomp_malloc (tgt_size + tgt_align - 1); + tgt->to_free = devicep->device_alloc_func (tgt_size + tgt_align - 1); tgt->tgt_start = (uintptr_t) tgt->to_free; tgt->tgt_start = (tgt->tgt_start + tgt_align - 1) & ~(tgt_align - 1); tgt->tgt_end = tgt->tgt_start + tgt_size; @@ -288,7 +237,8 @@ gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum, memory. Perhaps add some smarts, like if copying several adjacent fields from host to target, use some host buffer to avoid sending each var individually. */ - memcpy ((void *) (tgt->tgt_start + k->tgt_offset), + devicep->device_host2dev_func( + (void *) (tgt->tgt_start + k->tgt_offset), (void *) k->host_start, k->host_end - k->host_start); break; @@ -325,7 +275,8 @@ gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum, to initialize the pointer with. */ cur_node.tgt_offset -= sizes[i]; /* FIXME: host to device copy, see above FIXME comment. */ - memcpy ((void *) (tgt->tgt_start + k->tgt_offset), + devicep->device_host2dev_func ( + (void *) (tgt->tgt_start + k->tgt_offset), (void *) &cur_node.tgt_offset, sizeof (void *)); break; @@ -341,7 +292,8 @@ gomp_map_vars (struct gomp_device_descr *devicep, size_t mapnum, cur_node.tgt_offset = tgt->list[i]->tgt->tgt_start + tgt->list[i]->tgt_offset; /* FIXME: host to device copy, see above FIXME comment. */ - memcpy ((void *) (tgt->tgt_start + i * sizeof (void *)), + devicep->device_host2dev_func ( + (void *) (tgt->tgt_start + i * sizeof (void *)), (void *) &cur_node.tgt_offset, sizeof (void *)); } @@ -357,7 +309,7 @@ gomp_unmap_tgt (struct target_mem_desc *tgt) /* FIXME: Deallocate on target the tgt->tgt_start .. tgt->tgt_end region. */ if (tgt->tgt_end) - free (tgt->to_free); + tgt->device_descr->device_free_func(tgt->to_free); free (tgt->array); free (tgt); @@ -384,7 +336,7 @@ gomp_unmap_vars (struct target_mem_desc *tgt) splay_tree_key k = tgt->list[i]; if (k->copy_from) /* FIXME: device to host copy. */ - memcpy ((void *) k->host_start, + devicep->device_dev2host_func ((void *) k->host_start, (void *) (k->tgt->tgt_start + k->tgt_offset), k->host_end - k->host_start); splay_tree_remove (&devicep->dev_splay_tree, k); @@ -434,13 +386,14 @@ gomp_update (struct gomp_device_descr *devicep, size_t mapnum, (void *) n->host_end); if ((kinds[i] & 7) == 1) /* FIXME: host to device copy. */ - memcpy ((void *) (n->tgt->tgt_start + n->tgt_offset + devicep->device_host2dev_func ( + (void *) (n->tgt->tgt_start + n->tgt_offset + cur_node.host_start - n->host_start), (void *) cur_node.host_start, cur_node.host_end - cur_node.host_start); else if ((kinds[i] & 7) == 2) /* FIXME: device to host copy. */ - memcpy ((void *) cur_node.host_start, + devicep->device_dev2host_func ((void *) cur_node.host_start, (void *) (n->tgt->tgt_start + n->tgt_offset + cur_node.host_start - n->host_start), cur_node.host_end - cur_node.host_start); @@ -656,7 +609,7 @@ gomp_find_available_plugins (void) strcat (plugin_name, ent->d_name); if (!gomp_load_plugin_for_device (¤t_device, plugin_name)) continue; - devices = realloc (devices, (num_devices + 1) + devices = gomp_realloc (devices, (num_devices + 1) * sizeof (struct gomp_device_descr)); if (devices == NULL) { @@ -687,6 +640,10 @@ gomp_find_available_plugins (void) } devices[0].plugin_handle = NULL; devices[0].device_available_func = NULL; + devices[0].device_alloc_func = malloc; + devices[0].device_free_func = free; + devices[0].device_dev2host_func = memcpy; + devices[0].device_host2dev_func = memcpy; devices[0].dev_splay_tree.root = NULL; gomp_mutex_init (&devices[0].dev_env_lock); } diff --git a/libgomp/target.h b/libgomp/target.h index cac951f..1fa7ec5 100644 --- a/libgomp/target.h +++ b/libgomp/target.h @@ -26,21 +26,57 @@ creation and termination. */ #ifndef _TARGET_H -#define _TARGET_H - -struct splay_tree_key_s { - /* Address of the host object. */ - uintptr_t host_start; - /* Address immediately after the host object. */ - uintptr_t host_end; - /* Descriptor of the target memory. */ - struct target_mem_desc *tgt; - /* Offset from tgt->tgt_start to the start of the target object. */ - uintptr_t tgt_offset; +#define _TARGET_H 1 + +struct target_mem_desc { /* Reference count. */ uintptr_t refcount; - /* True if data should be copied from device to host at the end. */ - bool copy_from; + /* All the splay nodes allocated together. */ + splay_tree_node array; + /* Start of the target region. */ + uintptr_t tgt_start; + /* End of the targer region. */ + uintptr_t tgt_end; + /* Handle to free. */ + void *to_free; + /* Previous target_mem_desc. */ + struct target_mem_desc *prev; + /* Number of items in following list. */ + size_t list_count; + + /* Corresponding target device descriptor. */ + struct gomp_device_descr *device_descr; + + /* List of splay keys to remove (or decrease refcount) + at the end of region. */ + splay_tree_key list[]; +}; + +/* This structure describes accelerator device. + It contains name of the corresponding libgomp plugin, function handlers for + interaction with the device, ID-number of the device, and information about + mapped memory. */ +struct gomp_device_descr +{ + /* This is the ID number of device. It could be specified in DEVICE-clause of + TARGET construct. */ + int id; + + /* Plugin file handler. */ + void *plugin_handle; + + /* Function handlers. */ + bool (*device_available_func) (void); + void *(*device_alloc_func) (size_t s); + void (*device_free_func) (void *); + void *(*device_dev2host_func)(void *, const void *, size_t); + void *(*device_host2dev_func)(void *, const void *, size_t); + + /* Splay tree containing information about mapped memory regions. */ + struct splay_tree_s dev_splay_tree; + + /* Mutex for operating with the splay tree and other shared structures. */ + gomp_mutex_t dev_env_lock; }; #endif /* _TARGET_H */