@@ -2375,6 +2375,154 @@ int CeedOperatorLinearAssembleQFunctionBuildOrUpdate(CeedOperator op, CeedVector
23752375 return CeedOperatorLinearAssembleQFunctionBuildOrUpdate_Core (op , * assembled == NULL , true, assembled , rstr , request );
23762376}
23772377
2378+ // Estimate the work to rebuild the assembled QFunction data, without changing its state.
2379+ static int CeedOperatorLinearAssembleQFunctionGetFlopsEstimate (CeedOperator op , CeedSize * flops ) {
2380+ CeedInt num_elem , num_qpts , num_input_fields , num_active_inputs = 0 ;
2381+ CeedQFunction qf ;
2382+ CeedQFunctionField * qf_input_fields ;
2383+ CeedOperatorField * op_input_fields ;
2384+ CeedQFunctionAssemblyData data ;
2385+ bool is_setup , update_needed ;
2386+
2387+ * flops = 0 ;
2388+ CeedCall (CeedOperatorGetQFunctionAssemblyData (op , & data ));
2389+ CeedCall (CeedQFunctionAssemblyDataIsSetup (data , & is_setup ));
2390+ if (is_setup ) {
2391+ CeedCall (CeedQFunctionAssemblyDataIsUpdateNeeded (data , & update_needed ));
2392+ } else {
2393+ update_needed = true;
2394+ }
2395+ if (!update_needed ) return CEED_ERROR_SUCCESS ;
2396+
2397+ CeedCall (CeedOperatorGetNumElements (op , & num_elem ));
2398+ CeedCall (CeedOperatorGetNumQuadraturePoints (op , & num_qpts ));
2399+ CeedCall (CeedOperatorGetQFunction (op , & qf ));
2400+ CeedCall (CeedQFunctionGetFields (qf , & num_input_fields , & qf_input_fields , NULL , NULL ));
2401+ CeedCall (CeedOperatorGetFields (op , NULL , & op_input_fields , NULL , NULL ));
2402+ for (CeedInt i = 0 ; i < num_input_fields ; i ++ ) {
2403+ CeedEvalMode eval_mode ;
2404+ CeedVector vec ;
2405+
2406+ CeedCall (CeedOperatorFieldGetVector (op_input_fields [i ], & vec ));
2407+ if (vec == CEED_VECTOR_ACTIVE ) {
2408+ CeedInt size ;
2409+
2410+ CeedCall (CeedQFunctionFieldGetSize (qf_input_fields [i ], & size ));
2411+ num_active_inputs += size ;
2412+ } else {
2413+ CeedBasis basis ;
2414+ CeedElemRestriction rstr ;
2415+ CeedSize basis_flops , rstr_flops ;
2416+
2417+ CeedCall (CeedQFunctionFieldGetEvalMode (qf_input_fields [i ], & eval_mode ));
2418+ if (eval_mode != CEED_EVAL_WEIGHT ) {
2419+ CeedCall (CeedOperatorFieldGetElemRestriction (op_input_fields [i ], & rstr ));
2420+ CeedCall (CeedElemRestrictionGetFlopsEstimate (rstr , CEED_NOTRANSPOSE , & rstr_flops ));
2421+ CeedCall (CeedElemRestrictionDestroy (& rstr ));
2422+ CeedCall (CeedOperatorFieldGetBasis (op_input_fields [i ], & basis ));
2423+ basis_flops = 0 ;
2424+ if (basis != CEED_BASIS_NONE ) CeedCall (CeedBasisGetFlopsEstimate (basis , CEED_NOTRANSPOSE , eval_mode , false, 0 , & basis_flops ));
2425+ CeedCall (CeedBasisDestroy (& basis ));
2426+ * flops += rstr_flops + basis_flops * num_elem ;
2427+ }
2428+ }
2429+ CeedCall (CeedVectorDestroy (& vec ));
2430+ }
2431+ {
2432+ CeedSize qf_flops ;
2433+
2434+ CeedCall (CeedQFunctionGetFlopsEstimate (qf , & qf_flops ));
2435+ CeedCheck (qf_flops > -1 , CeedOperatorReturnCeed (op ), CEED_ERROR_INCOMPLETE ,
2436+ "Must set CeedQFunction FLOPs estimate with CeedQFunctionSetUserFlopsEstimate" );
2437+ * flops += (CeedSize )num_elem * num_qpts * num_active_inputs * qf_flops ;
2438+ }
2439+ CeedCall (CeedQFunctionDestroy (& qf ));
2440+ return CEED_ERROR_SUCCESS ;
2441+ }
2442+
2443+ static int CeedOperatorLinearAssembleGetFlopsEstimate_Core (CeedOperator op , bool is_point_block , bool is_diagonal , CeedSize * flops ) {
2444+ bool is_at_points , is_composite ;
2445+
2446+ CeedCall (CeedOperatorCheckReady (op ));
2447+ * flops = 0 ;
2448+ CeedCall (CeedOperatorIsComposite (op , & is_composite ));
2449+ if (is_composite ) {
2450+ CeedInt num_sub ;
2451+ CeedOperator * suboperators ;
2452+
2453+ CeedCall (CeedOperatorCompositeGetNumSub (op , & num_sub ));
2454+ CeedCall (CeedOperatorCompositeGetSubList (op , & suboperators ));
2455+ for (CeedInt i = 0 ; i < num_sub ; i ++ ) {
2456+ CeedSize sub_flops ;
2457+
2458+ CeedCall (CeedOperatorLinearAssembleGetFlopsEstimate_Core (suboperators [i ], is_point_block , is_diagonal , & sub_flops ));
2459+ * flops += sub_flops ;
2460+ }
2461+ return CEED_ERROR_SUCCESS ;
2462+ }
2463+ CeedCall (CeedOperatorIsAtPoints (op , & is_at_points ));
2464+ CeedCheck (!is_at_points , CeedOperatorReturnCeed (op ), CEED_ERROR_UNSUPPORTED , "AtPoints operator not supported" );
2465+
2466+ CeedCall (CeedOperatorLinearAssembleQFunctionGetFlopsEstimate (op , flops ));
2467+ {
2468+ CeedOperatorAssemblyData data ;
2469+ CeedBasis * bases_in , * bases_out ;
2470+ CeedElemRestriction * rstrs_in , * rstrs_out ;
2471+ CeedInt num_bases_in , num_bases_out , * num_eval_modes_in , * num_eval_modes_out ;
2472+
2473+ CeedCall (CeedOperatorGetOperatorAssemblyData (op , & data ));
2474+ CeedCall (CeedOperatorAssemblyDataGetEvalModes (data , & num_bases_in , & num_eval_modes_in , NULL , NULL , & num_bases_out , & num_eval_modes_out ,
2475+ NULL , NULL , NULL ));
2476+ CeedCall (CeedOperatorAssemblyDataGetBases (data , NULL , & bases_in , NULL , NULL , & bases_out , NULL ));
2477+ CeedCall (CeedOperatorAssemblyDataGetElemRestrictions (data , NULL , & rstrs_in , NULL , & rstrs_out ));
2478+ for (CeedInt b_in = 0 ; b_in < num_bases_in ; b_in ++ ) {
2479+ for (CeedInt b_out = 0 ; b_out < num_bases_out ; b_out ++ ) {
2480+ CeedInt num_elem , num_nodes_in , num_nodes_out , num_comp_in , num_comp_out , num_qpts ;
2481+
2482+ if (is_diagonal && bases_in [b_in ] != bases_out [b_out ]) continue ;
2483+ CeedCall (CeedElemRestrictionGetNumElements (rstrs_in [b_in ], & num_elem ));
2484+ CeedCall (CeedElemRestrictionGetNumComponents (rstrs_in [b_in ], & num_comp_in ));
2485+ CeedCall (CeedElemRestrictionGetNumComponents (rstrs_out [b_out ], & num_comp_out ));
2486+ if (bases_in [b_in ] == CEED_BASIS_NONE ) {
2487+ CeedCall (CeedElemRestrictionGetElementSize (rstrs_in [b_in ], & num_nodes_in ));
2488+ num_qpts = num_nodes_in ;
2489+ } else {
2490+ CeedCall (CeedBasisGetNumNodes (bases_in [b_in ], & num_nodes_in ));
2491+ CeedCall (CeedBasisGetNumQuadraturePoints (bases_in [b_in ], & num_qpts ));
2492+ }
2493+ if (bases_out [b_out ] == CEED_BASIS_NONE ) {
2494+ CeedCall (CeedElemRestrictionGetElementSize (rstrs_out [b_out ], & num_nodes_out ));
2495+ } else {
2496+ CeedCall (CeedBasisGetNumNodes (bases_out [b_out ], & num_nodes_out ));
2497+ }
2498+ if (is_diagonal ) {
2499+ const CeedSize num_comp = is_point_block ? num_comp_in * num_comp_out : num_comp_in ;
2500+
2501+ * flops += 3 * (CeedSize )num_elem * num_nodes_in * num_qpts * num_eval_modes_in [b_in ] * num_eval_modes_out [b_out ] * num_comp ;
2502+ * flops += (CeedSize )num_elem * num_nodes_in * num_comp ;
2503+ if (is_point_block ) * flops += (CeedSize )num_elem * num_nodes_in * num_comp * (num_comp_out - 1 );
2504+ } else {
2505+ * flops += 2 * (CeedSize )num_elem * num_comp_in * num_comp_out * num_nodes_out * num_qpts * num_eval_modes_in [b_in ] *
2506+ (num_eval_modes_out [b_out ] + num_nodes_in );
2507+ }
2508+ }
2509+ }
2510+ }
2511+ return CEED_ERROR_SUCCESS ;
2512+ }
2513+
2514+ int CeedOperatorLinearAssembleDiagonalGetFlopsEstimate (CeedOperator op , CeedSize * flops ) {
2515+ return CeedOperatorLinearAssembleGetFlopsEstimate_Core (op , false, true, flops );
2516+ }
2517+
2518+ int CeedOperatorLinearAssemblePointBlockDiagonalGetFlopsEstimate (CeedOperator op , CeedSize * flops ) {
2519+ return CeedOperatorLinearAssembleGetFlopsEstimate_Core (op , true, true, flops );
2520+ }
2521+
2522+ int CeedOperatorLinearAssembleGetFlopsEstimate (CeedOperator op , CeedSize * flops ) {
2523+ return CeedOperatorLinearAssembleGetFlopsEstimate_Core (op , false, false, flops );
2524+ }
2525+
23782526/**
23792527 @brief Assemble the diagonal of a square linear `CeedOperator`
23802528
0 commit comments