1*f996e368SLisandro Dalcin #include <petsc/private/petscimpl.h> /*I "petscsys.h" I*/ 2*f996e368SLisandro Dalcin #if defined(PETSC_HAVE_YAML) 3*f996e368SLisandro Dalcin #include <yaml.h> 4*f996e368SLisandro Dalcin #endif 5*f996e368SLisandro Dalcin 6*f996e368SLisandro Dalcin static MPI_Comm petsc_yaml_comm = MPI_COMM_NULL; /* only used for parallel error handling */ 7*f996e368SLisandro Dalcin 8*f996e368SLisandro Dalcin PETSC_STATIC_INLINE MPI_Comm PetscYAMLGetComm(void) 9*f996e368SLisandro Dalcin { 10*f996e368SLisandro Dalcin return PetscLikely(petsc_yaml_comm != MPI_COMM_NULL) ? petsc_yaml_comm : (petsc_yaml_comm = PETSC_COMM_SELF); 11*f996e368SLisandro Dalcin } 12*f996e368SLisandro Dalcin 13*f996e368SLisandro Dalcin PETSC_STATIC_INLINE MPI_Comm PetscYAMLSetComm(MPI_Comm comm) 14*f996e368SLisandro Dalcin { 15*f996e368SLisandro Dalcin MPI_Comm prev = PetscYAMLGetComm(); petsc_yaml_comm = comm; return prev; 16*f996e368SLisandro Dalcin } 17*f996e368SLisandro Dalcin 18*f996e368SLisandro Dalcin #if defined(PETSC_HAVE_YAML) 19*f996e368SLisandro Dalcin 20*f996e368SLisandro Dalcin #define TAG(node) ((const char *)((node)->tag)) 21*f996e368SLisandro Dalcin #define STR(node) ((const char *)((node)->data.scalar.value)) 22*f996e368SLisandro Dalcin #define SEQ(node) ((node)->data.sequence.items) 23*f996e368SLisandro Dalcin #define MAP(node) ((node)->data.mapping.pairs) 24*f996e368SLisandro Dalcin 25*f996e368SLisandro Dalcin static PetscErrorCode PetscParseLayerYAML(PetscOptions options, yaml_document_t *doc, yaml_node_t *node) 26*f996e368SLisandro Dalcin { 27*f996e368SLisandro Dalcin MPI_Comm comm = PetscYAMLGetComm(); 28*f996e368SLisandro Dalcin char name[PETSC_MAX_OPTION_NAME] = "", prefix[PETSC_MAX_OPTION_NAME] = ""; 29*f996e368SLisandro Dalcin PetscErrorCode ierr; 30*f996e368SLisandro Dalcin 31*f996e368SLisandro Dalcin PetscFunctionBegin; 32*f996e368SLisandro Dalcin if (node->type != YAML_MAPPING_NODE) SETERRQ(comm, PETSC_ERR_SUP, "Unsupported YAML node type: expected mapping"); 33*f996e368SLisandro Dalcin for (yaml_node_pair_t *pair = MAP(node).start; pair < MAP(node).top; pair++) { 34*f996e368SLisandro Dalcin yaml_node_t *keynode = yaml_document_get_node(doc, pair->key); 35*f996e368SLisandro Dalcin yaml_node_t *valnode = yaml_document_get_node(doc, pair->value); 36*f996e368SLisandro Dalcin PetscBool isMergeKey,isDummyKey,isIncludeTag; 37*f996e368SLisandro Dalcin 38*f996e368SLisandro Dalcin if (!keynode) SETERRQ(comm, PETSC_ERR_LIB, "Corrupt YAML document"); 39*f996e368SLisandro Dalcin if (!valnode) SETERRQ(comm, PETSC_ERR_LIB, "Corrupt YAML document"); 40*f996e368SLisandro Dalcin if (keynode->type != YAML_SCALAR_NODE) SETERRQ(comm, PETSC_ERR_SUP, "Unsupported YAML node type: expected scalar"); 41*f996e368SLisandro Dalcin 42*f996e368SLisandro Dalcin /* "<<" is the merge key: don't increment the prefix */ 43*f996e368SLisandro Dalcin ierr = PetscStrcmp(STR(keynode), "<<", &isMergeKey);CHKERRQ(ierr); 44*f996e368SLisandro Dalcin if (isMergeKey) { 45*f996e368SLisandro Dalcin if (valnode->type == YAML_SEQUENCE_NODE) { 46*f996e368SLisandro Dalcin for (yaml_node_item_t *item = SEQ(valnode).start; item < SEQ(valnode).top; item++) { 47*f996e368SLisandro Dalcin yaml_node_t *itemnode = yaml_document_get_node(doc, *item); 48*f996e368SLisandro Dalcin if (!itemnode) SETERRQ(comm, PETSC_ERR_LIB, "Corrupt YAML document"); 49*f996e368SLisandro Dalcin if (itemnode->type != YAML_MAPPING_NODE) SETERRQ(comm, PETSC_ERR_SUP, "Unsupported YAML node type: expected mapping"); 50*f996e368SLisandro Dalcin ierr = PetscParseLayerYAML(options, doc, itemnode);CHKERRQ(ierr); 51*f996e368SLisandro Dalcin } 52*f996e368SLisandro Dalcin } else if (valnode->type == YAML_MAPPING_NODE) { 53*f996e368SLisandro Dalcin ierr = PetscParseLayerYAML(options, doc, valnode);CHKERRQ(ierr); 54*f996e368SLisandro Dalcin } else SETERRQ(comm, PETSC_ERR_SUP, "Unsupported YAML node type: expected sequence or mapping"); 55*f996e368SLisandro Dalcin continue; /* to next pair */ 56*f996e368SLisandro Dalcin } 57*f996e368SLisandro Dalcin 58*f996e368SLisandro Dalcin /* "$$*" are treated as dummy keys, we use them for !include tags and to define anchors */ 59*f996e368SLisandro Dalcin ierr = PetscStrbeginswith(STR(keynode), "$$", &isDummyKey);CHKERRQ(ierr); 60*f996e368SLisandro Dalcin if (isDummyKey) { 61*f996e368SLisandro Dalcin ierr = PetscStrendswith(TAG(valnode), "!include", &isIncludeTag);CHKERRQ(ierr);CHKERRQ(ierr); 62*f996e368SLisandro Dalcin if (isIncludeTag) { /* TODO: add proper support relative paths */ 63*f996e368SLisandro Dalcin ierr = PetscOptionsInsertFileYAML(comm, options, STR(valnode), PETSC_TRUE);CHKERRQ(ierr); 64*f996e368SLisandro Dalcin } 65*f996e368SLisandro Dalcin continue; /* to next pair */ 66*f996e368SLisandro Dalcin } 67*f996e368SLisandro Dalcin 68*f996e368SLisandro Dalcin if (valnode->type == YAML_SCALAR_NODE) { 69*f996e368SLisandro Dalcin ierr = PetscSNPrintf(name, sizeof(name), "-%s", STR(keynode));CHKERRQ(ierr); 70*f996e368SLisandro Dalcin ierr = PetscOptionsSetValue(options, name, STR(valnode));CHKERRQ(ierr); 71*f996e368SLisandro Dalcin 72*f996e368SLisandro Dalcin } else if (valnode->type == YAML_SEQUENCE_NODE) { 73*f996e368SLisandro Dalcin PetscSegBuffer seg; 74*f996e368SLisandro Dalcin char *buf, *strlist; 75*f996e368SLisandro Dalcin PetscBool addSep = PETSC_FALSE; 76*f996e368SLisandro Dalcin 77*f996e368SLisandro Dalcin ierr = PetscSegBufferCreate(sizeof(char), PETSC_MAX_PATH_LEN, &seg);CHKERRQ(ierr); 78*f996e368SLisandro Dalcin for (yaml_node_item_t *item = SEQ(valnode).start; item < SEQ(valnode).top; item++) { 79*f996e368SLisandro Dalcin yaml_node_t *itemnode = yaml_document_get_node(doc, *item); 80*f996e368SLisandro Dalcin const char *itemstr = NULL; 81*f996e368SLisandro Dalcin size_t itemlen; 82*f996e368SLisandro Dalcin 83*f996e368SLisandro Dalcin if (!itemnode) SETERRQ(comm, PETSC_ERR_LIB, "Corrupt YAML document"); 84*f996e368SLisandro Dalcin 85*f996e368SLisandro Dalcin if (itemnode->type == YAML_SCALAR_NODE) { 86*f996e368SLisandro Dalcin itemstr = STR(itemnode); 87*f996e368SLisandro Dalcin 88*f996e368SLisandro Dalcin } else if (itemnode->type == YAML_MAPPING_NODE) { 89*f996e368SLisandro Dalcin yaml_node_pair_t *kvn = itemnode->data.mapping.pairs.start; 90*f996e368SLisandro Dalcin yaml_node_pair_t *top = itemnode->data.mapping.pairs.top; 91*f996e368SLisandro Dalcin 92*f996e368SLisandro Dalcin if (top - kvn > 1) SETERRQ(comm, PETSC_ERR_SUP, "Unsupported YAML node value: expected a single key:value pair"); 93*f996e368SLisandro Dalcin if (top - kvn > 0) { 94*f996e368SLisandro Dalcin yaml_node_t *kn = yaml_document_get_node(doc, kvn->key); 95*f996e368SLisandro Dalcin yaml_node_t *vn = yaml_document_get_node(doc, kvn->value); 96*f996e368SLisandro Dalcin 97*f996e368SLisandro Dalcin if (!kn) SETERRQ(comm, PETSC_ERR_LIB, "Corrupt YAML document"); 98*f996e368SLisandro Dalcin if (!vn) SETERRQ(comm, PETSC_ERR_LIB, "Corrupt YAML document"); 99*f996e368SLisandro Dalcin if (kn->type != YAML_SCALAR_NODE) SETERRQ(comm, PETSC_ERR_SUP, "Unsupported YAML node type: expected scalar"); 100*f996e368SLisandro Dalcin 101*f996e368SLisandro Dalcin ierr = PetscStrcmp(STR(kn), "<<", &isMergeKey);CHKERRQ(ierr); 102*f996e368SLisandro Dalcin if (isMergeKey) SETERRQ(comm, PETSC_ERR_SUP, "Unsupported YAML node value: merge key '<<' not supported here"); 103*f996e368SLisandro Dalcin 104*f996e368SLisandro Dalcin ierr = PetscStrbeginswith(STR(kn), "$$", &isDummyKey);CHKERRQ(ierr); 105*f996e368SLisandro Dalcin if (isDummyKey) continue; 106*f996e368SLisandro Dalcin itemstr = STR(kn); 107*f996e368SLisandro Dalcin } 108*f996e368SLisandro Dalcin 109*f996e368SLisandro Dalcin ierr = PetscSNPrintf(prefix,sizeof(prefix), "%s_", STR(keynode));CHKERRQ(ierr); 110*f996e368SLisandro Dalcin ierr = PetscOptionsPrefixPush(options, prefix);CHKERRQ(ierr); 111*f996e368SLisandro Dalcin ierr = PetscParseLayerYAML(options, doc, itemnode);CHKERRQ(ierr); 112*f996e368SLisandro Dalcin ierr = PetscOptionsPrefixPop(options);CHKERRQ(ierr); 113*f996e368SLisandro Dalcin 114*f996e368SLisandro Dalcin } else SETERRQ(comm, PETSC_ERR_SUP, "Unsupported YAML node type: expected scalar or mapping"); 115*f996e368SLisandro Dalcin 116*f996e368SLisandro Dalcin ierr = PetscStrlen(itemstr, &itemlen);CHKERRQ(ierr); 117*f996e368SLisandro Dalcin if (itemlen) { 118*f996e368SLisandro Dalcin if (addSep) { 119*f996e368SLisandro Dalcin ierr = PetscSegBufferGet(seg, 1, &buf);CHKERRQ(ierr); 120*f996e368SLisandro Dalcin ierr = PetscArraycpy(buf, ",", 1);CHKERRQ(ierr); 121*f996e368SLisandro Dalcin } 122*f996e368SLisandro Dalcin ierr = PetscSegBufferGet(seg, itemlen, &buf);CHKERRQ(ierr); 123*f996e368SLisandro Dalcin ierr = PetscArraycpy(buf, itemstr, itemlen);CHKERRQ(ierr); 124*f996e368SLisandro Dalcin addSep = PETSC_TRUE; 125*f996e368SLisandro Dalcin } 126*f996e368SLisandro Dalcin } 127*f996e368SLisandro Dalcin ierr = PetscSegBufferGet(seg, 1, &buf);CHKERRQ(ierr); 128*f996e368SLisandro Dalcin ierr = PetscArrayzero(buf, 1);CHKERRQ(ierr); 129*f996e368SLisandro Dalcin ierr = PetscSegBufferExtractAlloc(seg, &strlist);CHKERRQ(ierr); 130*f996e368SLisandro Dalcin ierr = PetscSegBufferDestroy(&seg);CHKERRQ(ierr); 131*f996e368SLisandro Dalcin 132*f996e368SLisandro Dalcin ierr = PetscSNPrintf(name, sizeof(name), "-%s", STR(keynode));CHKERRQ(ierr); 133*f996e368SLisandro Dalcin ierr = PetscOptionsSetValue(options, name, strlist);CHKERRQ(ierr); 134*f996e368SLisandro Dalcin ierr = PetscFree(strlist);CHKERRQ(ierr); 135*f996e368SLisandro Dalcin 136*f996e368SLisandro Dalcin } else if (valnode->type == YAML_MAPPING_NODE) { 137*f996e368SLisandro Dalcin ierr = PetscSNPrintf(prefix,sizeof(prefix), "%s_", STR(keynode));CHKERRQ(ierr); 138*f996e368SLisandro Dalcin ierr = PetscOptionsPrefixPush(options, prefix);CHKERRQ(ierr); 139*f996e368SLisandro Dalcin ierr = PetscParseLayerYAML(options, doc, valnode);CHKERRQ(ierr); 140*f996e368SLisandro Dalcin ierr = PetscOptionsPrefixPop(options);CHKERRQ(ierr); 141*f996e368SLisandro Dalcin 142*f996e368SLisandro Dalcin } else SETERRQ(comm, PETSC_ERR_SUP, "Unsupported YAML node type: expected scalar, sequence or mapping"); 143*f996e368SLisandro Dalcin } 144*f996e368SLisandro Dalcin PetscFunctionReturn(0); 145*f996e368SLisandro Dalcin } 146*f996e368SLisandro Dalcin 147*f996e368SLisandro Dalcin #endif 148*f996e368SLisandro Dalcin 149*f996e368SLisandro Dalcin /*@C 150*f996e368SLisandro Dalcin PetscOptionsInsertStringYAML - Inserts YAML-formatted options into the database from a string 151*f996e368SLisandro Dalcin 152*f996e368SLisandro Dalcin Logically Collective 153*f996e368SLisandro Dalcin 154*f996e368SLisandro Dalcin Input Parameter: 155*f996e368SLisandro Dalcin + options - options database, use NULL for default global database 156*f996e368SLisandro Dalcin - in_str - YAML-formatted string options 157*f996e368SLisandro Dalcin 158*f996e368SLisandro Dalcin Level: intermediate 159*f996e368SLisandro Dalcin 160*f996e368SLisandro Dalcin .seealso: PetscOptionsSetValue(), PetscOptionsView(), PetscOptionsHasName(), PetscOptionsGetInt(), 161*f996e368SLisandro Dalcin PetscOptionsGetReal(), PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(), 162*f996e368SLisandro Dalcin PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 163*f996e368SLisandro Dalcin PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 164*f996e368SLisandro Dalcin PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 165*f996e368SLisandro Dalcin PetscOptionsFList(), PetscOptionsEList(), PetscOptionsInsertFile(), PetscOptionsInsertFileYAML() 166*f996e368SLisandro Dalcin @*/ 167*f996e368SLisandro Dalcin PetscErrorCode PetscOptionsInsertStringYAML(PetscOptions options,const char in_str[]) 168*f996e368SLisandro Dalcin { 169*f996e368SLisandro Dalcin #if defined(PETSC_HAVE_YAML) 170*f996e368SLisandro Dalcin MPI_Comm comm = PetscYAMLGetComm(); 171*f996e368SLisandro Dalcin yaml_parser_t parser; 172*f996e368SLisandro Dalcin yaml_document_t doc; 173*f996e368SLisandro Dalcin yaml_node_t *root; 174*f996e368SLisandro Dalcin PetscErrorCode ierr; 175*f996e368SLisandro Dalcin 176*f996e368SLisandro Dalcin PetscFunctionBegin; 177*f996e368SLisandro Dalcin if (!in_str) in_str = ""; 178*f996e368SLisandro Dalcin ierr = !yaml_parser_initialize(&parser); if (ierr) SETERRQ(comm, PETSC_ERR_LIB, "YAML parser initialization error"); 179*f996e368SLisandro Dalcin yaml_parser_set_input_string(&parser, (const unsigned char *)in_str, strlen(in_str)); 180*f996e368SLisandro Dalcin do { 181*f996e368SLisandro Dalcin ierr = !yaml_parser_load(&parser, &doc); if (ierr) SETERRQ(comm, PETSC_ERR_LIB, "YAML parser loading error"); 182*f996e368SLisandro Dalcin root = yaml_document_get_root_node(&doc); 183*f996e368SLisandro Dalcin if (root) { 184*f996e368SLisandro Dalcin ierr = PetscParseLayerYAML(options, &doc, root);CHKERRQ(ierr); 185*f996e368SLisandro Dalcin } 186*f996e368SLisandro Dalcin yaml_document_delete(&doc); 187*f996e368SLisandro Dalcin } while (root); 188*f996e368SLisandro Dalcin yaml_parser_delete(&parser); 189*f996e368SLisandro Dalcin PetscFunctionReturn(0); 190*f996e368SLisandro Dalcin #else 191*f996e368SLisandro Dalcin MPI_Comm comm = PetscYAMLGetComm(); 192*f996e368SLisandro Dalcin (void)options; (void)in_str; /* unused */ 193*f996e368SLisandro Dalcin SETERRQ(comm, PETSC_ERR_SUP, "YAML not supported in this build.\nPlease reconfigure using --download-yaml"); 194*f996e368SLisandro Dalcin #endif 195*f996e368SLisandro Dalcin } 196*f996e368SLisandro Dalcin 197*f996e368SLisandro Dalcin /*@C 198*f996e368SLisandro Dalcin PetscOptionsInsertFileYAML - Insert a YAML-formatted file in the option database 199*f996e368SLisandro Dalcin 200*f996e368SLisandro Dalcin Collective 201*f996e368SLisandro Dalcin 202*f996e368SLisandro Dalcin Input Parameter: 203*f996e368SLisandro Dalcin + comm - the processes that will share the options (usually PETSC_COMM_WORLD) 204*f996e368SLisandro Dalcin . options - options database, use NULL for default global database 205*f996e368SLisandro Dalcin . file - name of file 206*f996e368SLisandro Dalcin - require - if PETSC_TRUE will generate an error if the file does not exist 207*f996e368SLisandro Dalcin 208*f996e368SLisandro Dalcin Only a small subset of the YAML standard is implemented. Non-scalar keys are NOT supported; 209*f996e368SLisandro Dalcin aliases and the merge key "<<" are. 210*f996e368SLisandro Dalcin The algorithm recursively parses the yaml file, pushing and popping prefixes 211*f996e368SLisandro Dalcin and inserting key + values pairs using PetscOptionsSetValue(). 212*f996e368SLisandro Dalcin 213*f996e368SLisandro Dalcin PETSc will generate an error condition that stops the program if a YAML error 214*f996e368SLisandro Dalcin is detected, hence the user should check that the YAML file is valid before 215*f996e368SLisandro Dalcin supplying it, for instance at http://www.yamllint.com/ . 216*f996e368SLisandro Dalcin 217*f996e368SLisandro Dalcin Inspired by https://stackoverflow.com/a/621451 218*f996e368SLisandro Dalcin 219*f996e368SLisandro Dalcin Level: intermediate 220*f996e368SLisandro Dalcin 221*f996e368SLisandro Dalcin .seealso: PetscOptionsSetValue(), PetscOptionsView(), PetscOptionsHasName(), PetscOptionsGetInt(), 222*f996e368SLisandro Dalcin PetscOptionsGetReal(), PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(), 223*f996e368SLisandro Dalcin PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 224*f996e368SLisandro Dalcin PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 225*f996e368SLisandro Dalcin PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 226*f996e368SLisandro Dalcin PetscOptionsFList(), PetscOptionsEList(), PetscOptionsInsertFile(), PetscOptionsInsertStringYAML() 227*f996e368SLisandro Dalcin @*/ 228*f996e368SLisandro Dalcin PetscErrorCode PetscOptionsInsertFileYAML(MPI_Comm comm,PetscOptions options,const char file[],PetscBool require) 229*f996e368SLisandro Dalcin { 230*f996e368SLisandro Dalcin int yamlLength = -1; 231*f996e368SLisandro Dalcin char *yamlString = NULL; 232*f996e368SLisandro Dalcin MPI_Comm prev; 233*f996e368SLisandro Dalcin PetscMPIInt rank; 234*f996e368SLisandro Dalcin PetscErrorCode ierr; 235*f996e368SLisandro Dalcin 236*f996e368SLisandro Dalcin PetscFunctionBegin; 237*f996e368SLisandro Dalcin ierr = MPI_Comm_rank(comm, &rank);CHKERRMPI(ierr); 238*f996e368SLisandro Dalcin if (!rank) { 239*f996e368SLisandro Dalcin char fpath[PETSC_MAX_PATH_LEN]; 240*f996e368SLisandro Dalcin char fname[PETSC_MAX_PATH_LEN]; 241*f996e368SLisandro Dalcin FILE *fd; 242*f996e368SLisandro Dalcin size_t rd; 243*f996e368SLisandro Dalcin 244*f996e368SLisandro Dalcin ierr = PetscStrreplace(PETSC_COMM_SELF, file, fpath, sizeof(fpath));CHKERRQ(ierr); 245*f996e368SLisandro Dalcin ierr = PetscFixFilename(fpath, fname);CHKERRQ(ierr); 246*f996e368SLisandro Dalcin 247*f996e368SLisandro Dalcin fd = fopen(fname, "r"); 248*f996e368SLisandro Dalcin if (fd) { 249*f996e368SLisandro Dalcin fseek(fd, 0, SEEK_END); 250*f996e368SLisandro Dalcin yamlLength = (int)ftell(fd); 251*f996e368SLisandro Dalcin fseek(fd, 0, SEEK_SET); 252*f996e368SLisandro Dalcin if (yamlLength < 0) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to query size of YAML file: %s", fname); 253*f996e368SLisandro Dalcin ierr = PetscMalloc1(yamlLength+1, &yamlString);CHKERRQ(ierr); 254*f996e368SLisandro Dalcin rd = fread(yamlString, 1, (size_t)yamlLength, fd); 255*f996e368SLisandro Dalcin if (rd != (size_t)yamlLength) SETERRQ1(PETSC_COMM_SELF, PETSC_ERR_FILE_READ, "Unable to read entire YAML file: %s", fname); 256*f996e368SLisandro Dalcin yamlString[yamlLength] = 0; 257*f996e368SLisandro Dalcin fclose(fd); 258*f996e368SLisandro Dalcin } 259*f996e368SLisandro Dalcin } 260*f996e368SLisandro Dalcin 261*f996e368SLisandro Dalcin ierr = MPI_Bcast(&yamlLength, 1, MPI_INT, 0, comm);CHKERRMPI(ierr); 262*f996e368SLisandro Dalcin if (require && yamlLength < 0) SETERRQ1(comm, PETSC_ERR_FILE_OPEN, "Unable to open YAML option file: %s\n", file); 263*f996e368SLisandro Dalcin if (yamlLength < 0) PetscFunctionReturn(0); 264*f996e368SLisandro Dalcin 265*f996e368SLisandro Dalcin if (rank) {ierr = PetscMalloc1(yamlLength+1, &yamlString);CHKERRQ(ierr);} 266*f996e368SLisandro Dalcin ierr = MPI_Bcast(yamlString, yamlLength+1, MPI_CHAR, 0, comm);CHKERRMPI(ierr); 267*f996e368SLisandro Dalcin 268*f996e368SLisandro Dalcin prev = PetscYAMLSetComm(comm); 269*f996e368SLisandro Dalcin ierr = PetscOptionsInsertStringYAML(options, yamlString);CHKERRQ(ierr); 270*f996e368SLisandro Dalcin (void) PetscYAMLSetComm(prev); 271*f996e368SLisandro Dalcin 272*f996e368SLisandro Dalcin ierr = PetscFree(yamlString);CHKERRQ(ierr); 273*f996e368SLisandro Dalcin PetscFunctionReturn(0); 274*f996e368SLisandro Dalcin } 275