YAC 3.21.0
Yet Another Coupler
Loading...
Searching...
No Matches
utils_core.c
Go to the documentation of this file.
1// Copyright (c) 2024 The YAC Authors
2//
3// SPDX-License-Identifier: BSD-3-Clause
4
5#include <stdlib.h>
6#include <stdio.h>
7#include <errno.h>
8#include <limits.h>
9#include <string.h>
10
11#include "utils_core.h"
12#include "yac_mpi_internal.h"
13
15 struct yac_name_type_pair const * pairs, size_t count, int type) {
16
17 char const * name = NULL;
18 for (size_t i = 0; (i < count) && (name == NULL); ++i)
19 if (pairs[i].type == type) name = pairs[i].name;
20 return name;
21}
22
24 struct yac_name_type_pair const * pairs, size_t count, char const * name) {
25
26 int type = INT_MAX;
27 if (name != NULL)
28 for (size_t i = 0; (i < count) && (type == INT_MAX); ++i)
29 if (!strcmp(pairs[i].name, name)) type = pairs[i].type;
30 return type;
31}
32
33char * yac_string_dup(char const * string) {
34 return (string != NULL) ? xstrdup(string) : NULL;
35}
36
39 DEF_NAME_TYPE_PAIR(false, 0),
40 DEF_NAME_TYPE_PAIR(true, 1),
41 DEF_NAME_TYPE_PAIR(FALSE, 0),
42 DEF_NAME_TYPE_PAIR(TRUE, 1),
43 DEF_NAME_TYPE_PAIR(no, 0),
44 DEF_NAME_TYPE_PAIR(yes, 1),
45 DEF_NAME_TYPE_PAIR(NO, 0),
46 DEF_NAME_TYPE_PAIR(YES, 1),
47 DEF_NAME_TYPE_PAIR(off, 0),
48 DEF_NAME_TYPE_PAIR(on, 1),
49 DEF_NAME_TYPE_PAIR(OFF, 0),
50 DEF_NAME_TYPE_PAIR(ON, 1),
53
54int yac_getenv_bool(const char * name, int default_value, MPI_Comm comm) {
55
56 YAC_ASSERT(name != NULL, "Environment variable name must not be NULL");
57 YAC_ASSERT((default_value == 0) || (default_value == 1),
58 "Default value must be 0(false) or 1(true)");
59 YAC_ASSERT(comm != MPI_COMM_NULL, "Communicator must not be MPI_COMM_NULL");
60
61 int value = default_value;
62 int rank;
63 yac_mpi_call(MPI_Comm_rank(comm, &rank), comm);
64
65 // determine value only on rank 0 to avoid potential issues with
66 // inconsistent environment variables across ranks
67 if (rank == 0) {
68
69 char * str_value = getenv(name);
70
71 if ((str_value != NULL) && (str_value[0] != '\0')) {
72
73 value =
75 bool_table, bool_table_size, str_value);
77 value != INT_MAX,
78 "\"%s\" is not a valid boolean value for environment variable %s",
79 str_value, name);
80 }
81 }
82
83 // broadcast value to all ranks
84 yac_mpi_call(MPI_Bcast(&value, 1, MPI_INT, 0, comm), comm);
85
86 return value;
87}
88
90 const char * name, int default_value, int threshold, MPI_Comm comm) {
91
92 YAC_ASSERT(name != NULL, "Environment variable name must not be NULL");
93 YAC_ASSERT(comm != MPI_COMM_NULL, "Communicator must not be MPI_COMM_NULL");
94
95 int value = default_value;
96 int rank;
97 yac_mpi_call(MPI_Comm_rank(comm, &rank), comm);
98
99 // determine value only on rank 0 to avoid potential issues with
100 // inconsistent environment variables across ranks
101 if (rank == 0) {
102
103 char * str_value = getenv(name);
104
105 if ((str_value != NULL) && (str_value[0] != '\0')) {
106
107 errno = 0;
108 char * end_ptr = NULL;
109 long value_long = strtol(str_value, &end_ptr, 10);
110
112 (value_long >= INT_MIN) && (value_long <= INT_MAX),
113 "\"%s\" is not a valid integer value for environment variable %s",
114 str_value, name);
115
116 value = ((int)value_long < threshold) ? default_value : (int)value_long;
117 }
118 }
119
120 yac_mpi_call(MPI_Bcast(&value, 1, MPI_INT, 0, comm), comm);
121
122 return value;
123}
124
126 const char * name, const char * default_value, MPI_Comm comm) {
127
128 YAC_ASSERT(name != NULL, "Environment variable name must not be NULL");
129 YAC_ASSERT(comm != MPI_COMM_NULL, "Communicator must not be MPI_COMM_NULL");
130
131 int rank;
132 yac_mpi_call(MPI_Comm_rank(comm, &rank), comm);
133
134 size_t str_value_len = SIZE_MAX; // SIZE_MAX means use default
135 char * str_value = NULL;
136
137 // determine value only on rank 0 to avoid potential issues with
138 // inconsistent environment variables across ranks
139 if (rank == 0) {
140
141 str_value = yac_string_dup(getenv(name));
142 if ((str_value != NULL) && (str_value[0] != '\0')) {
143 str_value_len = strlen(str_value);
144 }
145 }
146
147 // broadcast length of string to all ranks
148 yac_mpi_call(MPI_Bcast(&str_value_len, 1, YAC_MPI_SIZE_T, 0, comm), comm);
149
150 // if the environment variable is not set or is an empty string
151 if (str_value_len == SIZE_MAX) {
152
153 // use default value
154 str_value = yac_string_dup(default_value);
155 } else {
156
157 if (rank != 0) str_value = xmalloc(str_value_len + 1);
158
159 // broadcast string value to all ranks
161 MPI_Bcast(str_value, str_value_len + 1, MPI_CHAR, 0, comm), comm);
162 }
163
164 return str_value;
165}
#define YAC_ASSERT(exp, msg)
int yac_name_type_pair_get_type(struct yac_name_type_pair const *pairs, size_t count, char const *name)
Definition utils_core.c:23
#define DEF_NAME_TYPE_PAIR(NAME, TYPE)
char const * yac_name_type_pair_get_name(struct yac_name_type_pair const *pairs, size_t count, int type)
Definition utils_core.c:14
#define DEF_NAME_TYPE_PAIRS(NAME,...)
enum callback_type type
struct @23::@24 value
static const struct yac_name_type_pair bool_table[]
Definition param_bool.c:13
#define xstrdup(s)
Definition ppm_xfuncs.h:84
#define xmalloc(size)
Definition ppm_xfuncs.h:66
const char * name
String name (e.g., "true")
char const * name
Definition toy_scrip.c:114
int yac_getenv_bool(const char *name, int default_value, MPI_Comm comm)
int yac_getenv_int(const char *name, int default_value, int threshold, MPI_Comm comm)
Definition utils_core.c:89
char * yac_string_dup(char const *string)
Definition utils_core.c:33
char * yac_getenv_str(const char *name, const char *default_value, MPI_Comm comm)
Definition utils_core.c:125
#define YAC_ASSERT_F(exp, format,...)
Definition yac_assert.h:39
#define yac_mpi_call(call, comm)
#define YAC_MPI_SIZE_T