gomp-discuss
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: [Gomp-discuss] It's time to populate !


From: Steven Bosscher
Subject: RE: [Gomp-discuss] It's time to populate !
Date: 15 Feb 2003 13:20:59 +0100

Op za 15-02-2003, om 11:22 schreef Biagio Lucini:
> On Fri, 14 Feb 2003, Scott Robert Ladd wrote:
> 
> > Biagio Lucini wrote
> > > Well, is Scott happy with it?
> > 
> > I'll make a few changes based on what people have said, then finish the
> > boilerplate .c code.
> > 
> > I suppose I need to start a test program too, huh?
> > 
> 
> If you need a hand I'm here... I thought I could start implementing a few
> functions using the POSIX threading model, which should be fine for some
> things. We will need also a bit of knowledge of system programming, like
> e.g. how to get the number of CPUs to set the default and how to get the
> value of the OMP shell variables.
> 

Here's a start.  Haven't done much for OMP_SCHEDULE because I'm not sure
what to do with embedded spaces in the environment variable.  Those can
happen but the OpenMP specs don't tell what to do with them.

Greetz
Steven



/* OpenMP environment variables
   Copyright (C) 2003 Free Software Foundation, Inc.
   Contributed by Steven Bosscher

This file is part of the GNU OpenMP for GCC runtime library (libgomp).

libgomp 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.

lomgomp 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 for more details.

You should have received a copy of the GNU Lesser General Public
License along with libgomp; see the file COPYING.LIB.  If not,
write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */

/* Environment scanner.  Examine the environment for OpenMP API
   environment variables that control the execution of parallel code.

   The names of environment variables must be uppercase. The values
   assigned to them are case insensitive and may have leading and
   trailing white space. Modifications to the values after the program
   has started are ignored.

   The environment variables are defined in the OpenMP specs:
   OMP_SCHEDULE sets the run-time schedule type and chunk size.
   OMP_NUM_THREADS sets the number of threads to use during execution.
   OMP_DYNAMIC enables/disables dynamic adjustment of the number of threads.
   OMP_NESTED enables or disables nested parallelism.

   Our philosophy here is that a broken environment variable should
   never prevent the program from running, so an environment variable
   with a messed-up value will simply be ignored.  */

#include <string.h>

typedef struct omp_env_var
{
  char *name;
  char *description;
  void (*init) (const char *);
}
omp_env_var;

/* Functions to initialize the library based on the settings of an
   environment variable.  These functions are only called once we've
   found that the environment variable is set to some value.  These
   functions mush parse that value and initialize the library settings
   accordingly.  */

static void omp_env_schedule_init (const char *);
static void omp_env_num_threads_init (const char *);
static void omp_env_nested_init (const char *);
static void omp_env_dynamic_init (const char *);

/* The environment variable definitions:  */

static omp_env_var omp_env_var_table[] = {
  {"OMP_SCHEDULE",
   "Sets the run-time schedule type and chunk size.  This applies "
   "only to `for' and `parallel for' directives that have the "
   "run-time schedure type `runtime'.",
   &omp_env_schedule_init},

  {"OMP_NUM_THREADS",
   "Sets the default number of threads to use during excecution. "
   "An explicit `num_threads' clause on a `parallel' directive overrides "
   "this default.",
   &omp_env_num_threads_init},

  {"OMP_DYNAMIC",
   "Enables (TRUE) or disables (FALSE) dynamic adjustment of the number "
   "of threads.",
   &omp_env_dynamic_init},

  {"OMP_NESTED",
   "Enables (TRUE) or disables (FALSE) nested parallelism.",
   &omp_env_nested_init},

  {NULL, NULL, NULL}
};


/* Define isblank if we're not dealing with a GNU system.  */
#ifndef isblank
#define isblank(C) ((C) == ' 0' || (C) == '\t')
#endif

/* Skip leading spaces.  */
#ifndef isblank 
#define skip_whitespace(C) while (isblank(*(C))) (C)++;

/* Get a boolean environment variable.  We just trim the leading
   blanks, uppercase the remaining string, and then compare with TRUE
   and FALSE.  Returns 1 for TRUE, 0 for FALSE, or -1 for something
   that didn't make sense.  */

static int
get_boolean (const char * value)
{
  int j = 0, i = strlen (value);

  /* Trim trailing blanks.  */
  while (isblank (value[i])) i--;

  /* Any string longer than 5 chars doesn't make sense at this point.  */
  if (i > 5)
    return -1;

  /* Uppercase the trimmed string.  */
  for (j = 0; j <= i; j++)
    {
      if (islower (value[j]))
        value[j] = toupper (value[j]);  
    }

  /* See what we've got.  */
  if (!strncmp (value, "TRUE", i))
    return 1;
  else if (!strncmp (value, "FALSE", i))
    return 0;
  else
    return -1;
}


static void
omp_env_schedule_init (const char * value)
{
  static struct
  {
    char name[];
    int value;
  }
  schedule_types[] = {
    {"guided", 0}, /* FIXME: replace '0' with appropriate value.  */
    {"static", 0},
    {"dynamic", 0},
    {"runtime", 0}, /* Warn user if he's so stupid to try this.  */
    {NULL, 0}
  };

  /* Look at the string, find a comma, and handle whitespace.  Then
     strcmp through schedule_types.  If there's no match, the
     environment variable is bad.  Otherwise, get the chunk size.  */

  /* You can get the number of configured and online processors with:

     long N_CPUs_configured = sysconf (_SC_NPROCESSORS_CONF);
     long N_CPUs_online = sysconf (_SC_NPROCESSORS_ONLN);  */
}


/* Get a positive integer from the environment.  */

static void
omp_env_num_threads_init (const char * value)
{
  char c;
  int num_threads = 0, i = 0;

  /* Intrestingly, '+'[0-9]* is not a string in POSIX, but a positive
     integer value.  A leading minus is also allowed but we don't allow
     negative values for num_threads so to us it's illegal.  */
  if (value[0] == '+')
    i++;

  for (c = value[i]; c != '\0'; i++)
    {
      /* Blanks terminate the value.  */
      if (isblank (c))
        break;

      /* Bail out if not a digit.  */
      if (!isdigit (c))
        return;

      num_threads = 10 * num_threads + (c - '0');
    }

  /* Make sure we've found a positive integer.  Negative integers are
     not possible at this point anyway, but (num_threads == 0) is
     possible.  */
  if (num_threads < 1)
    return;

  /* TODO: Set the library value of num_threads.  */
}


/* Do we allow nested parallelism (TRUE|FALSE)?  */

static void
omp_env_nested_init (const char * value)
{
  int nested = get_boolean (value);
  /* TODO: Set the library value of nested.  */
}


/* Do we adjust the number of threads dynamically (TRUE|FALSE)?  */

static void
omp_env_dynamic_init (const char * value)
{
  int dynamic = get_boolean (value);
  /* TODO: Set the library value of dynamic.  */
}


/* See if we can find an OpenMP environment variable, and adjust the
   library default settings if we do.  */

void
omp_env_init (void)
{
  const char *value;
  int i = 0;

  /* Loop through the environment variable table.  */
  while (omp_env_var_table[i].name != NULL)
    {
      value = get_env (omp_env_var_table[i]);

      /* If value != NULL, skip leading blanks and get the value for
         this environment variable if the init function is defined.  */
      if (value && omp_env_var_table[i].init)
        omp_env_var_table[i].init (skip_whitespace (value));
    }

  return;
}





reply via email to

[Prev in Thread] Current Thread [Next in Thread]