Composite `CeedOperator` collective context operations

Abierto
#2,003 14 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

@Infinity-002 ya está trabajando en esto.

Desde el 15/9/2026.

Evaluación

Dificultad
5/5
Tiempo estimado
Más de una semana
Aptitud para principiantes
35/100
Tipo de issue
Nueva funcionalidad
Claridad
Bastante claro
Estado de actividad
Tranquilo
Stack tecnológico
c

Línea de trabajo

Comience con las funciones existentes CeedOperatorGetContext[Double|Int32|Boolean]Read/Restore y los puntos de entrada CeedOperatorCompositeGetNumSub y GetSubList mencionados en el issue. Primero aclare con los maintainers si Phase 1, Phase 2 o ambas están dentro del alcance; se considera terminado cuando una interfaz pública acordada admite las operaciones de contexto composite y las reglas de validez especificadas.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

enhancement good student contribution help wanted interface

Summary

Add an interface for collective operations over composite CeedOperator context values.

Motivation

Currently, using the CeedOperatorGetContext[Double|Int32|Boolean]Read functions on a composite CeedOperator simply returns the value from the first sub-operator that has the context field defined. While useful for fields that should be the same for all sub-operators, e.g. time or timestep, there are many circumstances where each context would have a separate value which we want to perform a collective operation over. This is especially true for contexts which may have values written within a CeedQFunction (i.e. CeedQFunctionSetContextWritable(ctx, true)).

One place where this would be useful is in checking for element inversion, domain violation, or error checking, where a single boolean value context would be set to true within a CeedQFunction if an error is detected. Right now, in order to determine if any of the sub-operators of the composite operator op set the flag with name name in the context, a user must loop over the sub-operators and do something like the following:

CeedInt       num_sub;
CeedOperator *sub_operators;
bool          value  = false, is_set = false;

CeedOperatorCompositeGetNumSub(op, &num_sub);
CeedOperatorCompositeGetSubList(op, &sub_operators);
for (CeedInt i = 0; i < num_sub; i++) {
  CeedContextFieldLabel label = NULL;
  PetscSizeT            num_values;
  const bool           *values_ceed;

  CeedOperatorGetContextFieldLabel(sub_operators[i], name, &label);
  if (label) {
    CeedOperatorGetContextBooleanRead(sub_operators[i], label, &num_values, &values_ceed);
    value  = value || values_ceed[0];
    is_set = true;
    CeedOperatorRestoreContextBooleanRead(sub_operators[i], label, &values_ceed);
  }
}

Possible Interface

All of this is open to discussion and suggestion, but I think this would be a logical approach.

Phase 1: Composite Operator Context Getter

Much of the user-side difficulty of the above approach can be alleviated by providing functions to get the values associated with a given field of each sub-operator of a composite CeedOperator. This interface would look like (using boolean fields as an example):

CeedOperatorCompositeGetContextBooleanRead(CeedOperator composite_op, CeedContextFieldLabel label, CeedInt* num_suboperator_fields, size_t **num_values, const bool ***values_ceed);
CeedOperatorCompositeRestoreContextBooleanRead(CeedOperator composite_op, CeedContextFieldLabel label, CeedInt* num_suboperator_fields, size_t *num_values, const bool ***values_ceed);

where *num_suboperator_fields would be set to the number of suboperators with the requested field, *num_values would be set to the number of values in the field (already enforced to be constant across suboperators), and *values would be an array of pointers to each of the suboperator field value data (essentially the same as the current interface, just with an extra array over suboperators). That array could easily be cached if desired, though their size likely doesn't justify it.

Using this interface, the above code would be simplified to:

CeedInt num_sub;
size_t  num_values;
bool  **values_ceed;
bool    value  = false, is_set = false;

CeedOperatorCompositeGetContextBooleanRead(op, label, &num_sub, &num_values, &values_ceed);
is_set = num_sub > 0;
for (CeedInt i = 0; i < num_sub; i++) value  = value || values_ceed[i][0];
CeedOperatorCompositeRestoreContextBooleanRead(op, label, &num_sub, &num_values, &values_ceed);
Phase 2: Collective Operation Utilities

I think that as a starting point, a generic backend function like:

CeedOperatorContextCompositeReduceGeneric(CeedOperator op, CeedContextFieldLabel field_label, CeedContextFieldType field_type, CeedCollectiveOperation operation, size_t *num_values, void *values);

where CeedCollectiveOperation is an enum mirroring the default MPI_Op values (excluding MINLOC and MAXLOC):

typedef enum {
  CEED_OPERATION_MIN,
  CEED_OPERATION_MAX,
  CEED_OPERATION_BOR,
  CEED_OPERATION_BXOR,
  CEED_OPERATION_LOR,
  CEED_OPERATION_LXOR,
  CEED_OPERATION_BAND,
  CEED_OPERATION_LAND,
  CEED_OPERATION_SUM,
  CEED_OPERATION_PROD,
} CeedCollectiveOperation;

Note, only some of the operations are valid for a given CeedContextFieldType. Specifically, following MPI convention:

[ MAX, MIN] CEED_CONTEXT_FIELD_DOUBLE, CEED_CONTEXT_FIELD_INT32
[ SUM, PROD] CEED_CONTEXT_FIELD_DOUBLE, CEED_CONTEXT_FIELD_INT32
[ LAND, LOR, LXOR] CEED_CONTEXT_FIELD_INT32, CEED_CONTEXT_FIELD_BOOL
[ BAND, BOR, BXOR] CEED_CONTEXT_FIELD_INT32

Then, the user-facing functions (note that the values array would be allocated by libCEED and freed by the user, or we could use a Get/Restore interface):

CeedOperatorContextCompositeReduceBoolean(CeedOperator op, CeedContextFieldLabel field_label, CeedCollectiveOperation operation, size_t *num_values, bool **values);
CeedOperatorContextCompositeReduceDouble(CeedOperator op, CeedContextFieldLabel field_label, CeedCollectiveOperation operation, size_t *num_values, double **values);
CeedOperatorContextCompositeReduceInt32(CeedOperator op, CeedContextFieldLabel field_label, CeedCollectiveOperation operation, size_t *num_values, int32_t **values);

These functions should check that the requested operation is valid, then apply it over each of the field_label->num_values values and store the results in a new array, which is returned to the user as *values.

Lenguaje dominante
C
Estrellas
273
Forks
84
Merge medio
1 d 15 h
PR fusionados (30 d)
21

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de CEED/libCEED

Todos los issues de CEED/libCEED

Issues similares

Más issues de C

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.