diff mbox series

libgomp: Add OMPD Address Space Information functions.

Message ID 20200708193035.1797676-1-y2s1982@gmail.com
State New
Headers show
Series libgomp: Add OMPD Address Space Information functions. | expand

Commit Message

y2s1982 July 8, 2020, 7:30 p.m. UTC
This patch adds Address Space Information function implementations as
defined in section 5.5.4 of OpenMP API Specification 5.0.

2020-07-08  Tony Sim  <y2s1982@gmail.com>

libgomp/ChangeLog:

	* Makefile.am (libgompd_la_OBJECTS): Add ompd-addr.c.
	* Makefile.in: Regenerate.
	* ompd-addr.c: New file.

---
 libgomp/Makefile.am |  2 +-
 libgomp/Makefile.in |  5 +--
 libgomp/ompd-addr.c | 88 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 92 insertions(+), 3 deletions(-)
 create mode 100644 libgomp/ompd-addr.c

Comments

Jakub Jelinek July 8, 2020, 8:42 p.m. UTC | #1
On Wed, Jul 08, 2020 at 03:30:35PM -0400, y2s1982 wrote:
> +ompd_rc_t
> +ompd_get_omp_version (ompd_address_space_handle_t *address_space,
> +		      ompd_word_t *omp_version)
> +{
> +  if (omp_version == NULL)
> +    return ompd_rc_bad_input;
> +  if (address_space == NULL)
> +    return ompd_rc_stale_handle;
> +
> +  /* _OPENMP macro is defined to have yyyymm integer.  */
> +  ompd_size_t macro_length = sizeof (int);
> +
> +  ompd_rc_t ret = ompd_rc_ok;
> +
> +  struct ompd_address_t addr;
> +  ret = gompd_callbacks.symbol_addr_lookup (address_space->context, NULL,
> +					    "openmp_version", &addr, NULL);

This can't be right.  There is no openmp_version variable in libgomp.so.1
(and I don't think we should add it).
As I said multiple times before, you should add one (read-only) data
variable to libgomp.so.1 that will encode a lot of information that OMPD
needs and the version should be in there.

> +ompd_rc_t
> +ompd_get_omp_version_string (ompd_address_space_handle_t *address_space,
> +			     const char **string)
> +{
> +  if (string == NULL)
> +    return ompd_rc_bad_input;
> +
> +  if (address_space == NULL)
> +    return ompd_rc_stale_handle;
> +
> +  ompd_word_t omp_version;
> +  ompd_rc_t ret = ompd_get_omp_version (address_space, &omp_version);
> +  if (ret != ompd_rc_ok)
> +    return ret;
> +
> +  char *tmp = "GNU OpenMP Runtime implementing OpenMP 5.0 "
> +	    ompd_stringify (omp_version);

This will append "omp_version" to the string literal, won't it?
That is not what you want in there, you instead want the value.

	Jakub
y2s1982 July 8, 2020, 11:53 p.m. UTC | #2
Hello Jakub,

Thank you again for detailed feedback. I had few questions.

On Wed, Jul 8, 2020 at 4:42 PM Jakub Jelinek <jakub@redhat.com> wrote:

> On Wed, Jul 08, 2020 at 03:30:35PM -0400, y2s1982 wrote:
> > +ompd_rc_t
> > +ompd_get_omp_version (ompd_address_space_handle_t *address_space,
> > +                   ompd_word_t *omp_version)
> > +{
> > +  if (omp_version == NULL)
> > +    return ompd_rc_bad_input;
> > +  if (address_space == NULL)
> > +    return ompd_rc_stale_handle;
> > +
> > +  /* _OPENMP macro is defined to have yyyymm integer.  */
> > +  ompd_size_t macro_length = sizeof (int);
> > +
> > +  ompd_rc_t ret = ompd_rc_ok;
> > +
> > +  struct ompd_address_t addr;
> > +  ret = gompd_callbacks.symbol_addr_lookup (address_space->context,
> NULL,
> > +                                         "openmp_version", &addr, NULL);
>
> This can't be right.  There is no openmp_version variable in libgomp.so.1
> (and I don't think we should add it).
> As I said multiple times before, you should add one (read-only) data
> variable to libgomp.so.1 that will encode a lot of information that OMPD
> needs and the version should be in there.
>

I do remember, though I obviously understood wrongly. Sorry about that.
I had assumed it might have something to do with ICV but didn't realize it
would also
apply to other variables. In all honesty, I was looking for _OPENMP macro;
I assumed
such information would be stored somewhere already and thought
symbol_addr_lookup() would find it somehow. I saw mentions of it on
ChangeLog,
testsuits, and in one string, but I couldn't find the actual macro. As for
openmp_version,
I (wrongly) made the assumption looking at the omp_lib.h.in. I should learn
more
about .in file's syntax and what they do.

To place a variable in libgomp.so.1, should I define a related struct and
declare a global
extern variable of the struct in omp.h and define it in some related .c
file?
Can I then simply use the name of the declared variable as the name (where
"openmp_version" currently  is) to find the struct? As for the value for
_OPENMP version,
where can I find it, or should OMPD maintain its own values for it?


> > +ompd_rc_t
> > +ompd_get_omp_version_string (ompd_address_space_handle_t *address_space,
> > +                          const char **string)
> > +{
> > +  if (string == NULL)
> > +    return ompd_rc_bad_input;
> > +
> > +  if (address_space == NULL)
> > +    return ompd_rc_stale_handle;
> > +
> > +  ompd_word_t omp_version;
> > +  ompd_rc_t ret = ompd_get_omp_version (address_space, &omp_version);
> > +  if (ret != ompd_rc_ok)
> > +    return ret;
> > +
> > +  char *tmp = "GNU OpenMP Runtime implementing OpenMP 5.0 "
> > +         ompd_stringify (omp_version);
>
> This will append "omp_version" to the string literal, won't it?
> That is not what you want in there, you instead want the value.
>

Oh I see. Thanks for pointing that out. I am still learning how macro
expansion works.

Cheers,

Tony

>
>         Jakub
>
>
Jakub Jelinek July 9, 2020, 7:17 a.m. UTC | #3
On Wed, Jul 08, 2020 at 07:53:23PM -0400, y2s1982 . wrote:
> I do remember, though I obviously understood wrongly. Sorry about that.
> I had assumed it might have something to do with ICV but didn't realize it
> would also
> apply to other variables. In all honesty, I was looking for _OPENMP macro;
> I assumed
> such information would be stored somewhere already and thought
> symbol_addr_lookup() would find it somehow. I saw mentions of it on
> ChangeLog,
> testsuits, and in one string, but I couldn't find the actual macro. As for
> openmp_version,

openmp_version is a Fortran PARAMETER, which is (for integral variables) something
like
enum { openmp_version = ... };
or C++ const int openmp_version = ...
if only non-ODR used, i.e. replaced by the value whenever used.

You can always readelf -Wa .libs/libgomp.so.1 or nm -D .libs/libgomp.so.1 to
see what is actually present and exported.

> I (wrongly) made the assumption looking at the omp_lib.h.in. I should learn
> more
> about .in file's syntax and what they do.
> 
> To place a variable in libgomp.so.1, should I define a related struct and
> declare a global
> extern variable of the struct in omp.h and define it in some related .c
> file?

Definitely not in omp.h, that header is for OpenMP users.  Private
implementation stuff should not be there.  But it can be in libgomp.h.

> Can I then simply use the name of the declared variable as the name (where
> "openmp_version" currently  is) to find the struct? As for the value for
> _OPENMP version,
> where can I find it, or should OMPD maintain its own values for it?

_OPENMP is a predefined macro by C/C++ (and Fortran uses that omp_lib.f90
file).  And it is only predefined if preprocessing with -fopenmp.
I guess you can define some private structure, especially for the header of
that variable (where you add perhaps some magic 32-bit number, some version
number of the layout of the variable, this _OPENMP version, size of the
whole variable and others as needed).  What I'd suggest is that it then
contains some array of self-describing further values once you'll need it.
And it should be compact if possible (ideal would be e.g. sleb128/uleb128
encoding of numbers like in DWARF; e.g. one way to do it compact would be
have a generator program that would include omp.h and libgomp.h and stdio.h,
would use offsetof/sizeof and whatever and write it on stdout as initializer
of a const char GOMP_library_description[] = { 0x12, 0x7a, 0x2b, ... };
which then would be compiled and linked into libgomp.so.1.
And that you don't try to read data from that variable all the time, but
instead do it once from ompd_process_init, where you'd look up that
variable, read and parse that variable, store what you found into the
process handle and punt if anything is unexpected in there.
Once you need more information in there, it would be nice to macroize
that info, e.g. have a macro when you need size of some internal structure,
or offsetof of its member, or size of the member, or when some pointer needs
to be dereferenced to achieve something.

But perhaps for start just use a struct and parse the information from
there, and only when we have clearer picture on what kind of information we
need we can extend it.

	Jakub
diff mbox series

Patch

diff --git a/libgomp/Makefile.am b/libgomp/Makefile.am
index fe0a92122ea..0a4a9c10eb9 100644
--- a/libgomp/Makefile.am
+++ b/libgomp/Makefile.am
@@ -90,7 +90,7 @@  libgomp_la_SOURCES = alloc.c atomic.c barrier.c critical.c env.c error.c \
 	oacc-mem.c oacc-async.c oacc-plugin.c oacc-cuda.c priority_queue.c \
 	affinity-fmt.c teams.c allocator.c oacc-profiling.c oacc-target.c
 
-libgompd_la_SOURCES = ompd-lib.c ompd-proc.c
+libgompd_la_SOURCES = ompd-lib.c ompd-proc.c ompd-addr.c
 
 include $(top_srcdir)/plugin/Makefrag.am
 
diff --git a/libgomp/Makefile.in b/libgomp/Makefile.in
index 2b487e00499..9ceb2c6e460 100644
--- a/libgomp/Makefile.in
+++ b/libgomp/Makefile.in
@@ -235,7 +235,7 @@  am_libgomp_la_OBJECTS = alloc.lo atomic.lo barrier.lo critical.lo \
 	$(am__objects_1)
 libgomp_la_OBJECTS = $(am_libgomp_la_OBJECTS)
 libgompd_la_LIBADD =
-am_libgompd_la_OBJECTS = ompd-lib.lo ompd-proc.lo
+am_libgompd_la_OBJECTS = ompd-lib.lo ompd-proc.lo ompd-addr.lo
 libgompd_la_OBJECTS = $(am_libgompd_la_OBJECTS)
 AM_V_P = $(am__v_P_@AM_V@)
 am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
@@ -592,7 +592,7 @@  libgomp_la_SOURCES = alloc.c atomic.c barrier.c critical.c env.c \
 	oacc-async.c oacc-plugin.c oacc-cuda.c priority_queue.c \
 	affinity-fmt.c teams.c allocator.c oacc-profiling.c \
 	oacc-target.c $(am__append_4)
-libgompd_la_SOURCES = ompd-lib.c ompd-proc.c
+libgompd_la_SOURCES = ompd-lib.c ompd-proc.c ompd-addr.c
 
 # Nvidia PTX OpenACC plugin.
 @PLUGIN_NVPTX_TRUE@libgomp_plugin_nvptx_version_info = -version-info $(libtool_VERSION)
@@ -816,6 +816,7 @@  distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oacc-plugin.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oacc-profiling.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oacc-target.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ompd-addr.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ompd-lib.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ompd-proc.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ordered.Plo@am__quote@
diff --git a/libgomp/ompd-addr.c b/libgomp/ompd-addr.c
new file mode 100644
index 00000000000..f1f3b8071c1
--- /dev/null
+++ b/libgomp/ompd-addr.c
@@ -0,0 +1,88 @@ 
+/* Copyright (C) 2020 Free Software Foundation, Inc.
+   Contributed by Yoosuk Sim <y2s1982@gmail.com>.
+
+   This file is part of the GNU Offloading and Multi Processing 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
+   <http://www.gnu.org/licenses/>.  */
+
+/* This file contains function definitions for OMPD's Address Space Information
+   functions defined in the OpenMP 5.0 API Documentation, 5.5.4.  */
+
+#include <stdlib.h>
+#include <string.h>
+#include "omp-tools.h"
+#include "libgompd.h"
+
+ompd_rc_t
+ompd_get_omp_version (ompd_address_space_handle_t *address_space,
+		      ompd_word_t *omp_version)
+{
+  if (omp_version == NULL)
+    return ompd_rc_bad_input;
+  if (address_space == NULL)
+    return ompd_rc_stale_handle;
+
+  /* _OPENMP macro is defined to have yyyymm integer.  */
+  ompd_size_t macro_length = sizeof (int);
+
+  ompd_rc_t ret = ompd_rc_ok;
+
+  struct ompd_address_t addr;
+  ret = gompd_callbacks.symbol_addr_lookup (address_space->context, NULL,
+					    "openmp_version", &addr, NULL);
+  if (ret != ompd_rc_ok)
+    return ret;
+
+  ret = gompd_callbacks.read_memory (address_space->context, NULL, &addr,
+				     macro_length, (void *) omp_version);
+  return ompd_rc_ok;
+}
+
+ompd_rc_t
+ompd_get_omp_version_string (ompd_address_space_handle_t *address_space,
+			     const char **string)
+{
+  if (string == NULL)
+    return ompd_rc_bad_input;
+
+  if (address_space == NULL)
+    return ompd_rc_stale_handle;
+
+  ompd_word_t omp_version;
+  ompd_rc_t ret = ompd_get_omp_version (address_space, &omp_version);
+  if (ret != ompd_rc_ok)
+    return ret;
+
+  char *tmp = "GNU OpenMP Runtime implementing OpenMP 5.0 "
+	    ompd_stringify (omp_version);
+  size_t s = strlen (tmp) + 1;
+
+  char *t = NULL;
+  ret = gompd_callbacks.alloc_memory (s, (void *) t);
+  if (ret != ompd_rc_ok)
+    return ret;
+
+  strcpy (t, tmp);
+
+  *string = t;
+
+  return ret;
+}