@@ -817,6 +817,62 @@ int CeedReference(Ceed ceed) {
817817 return CEED_ERROR_SUCCESS ;
818818}
819819
820+ /**
821+ @brief Computes the current memory usage of the work vectors in a `Ceed` context and prints to debug.abort
822+
823+ @param[in] ceed `Ceed` context
824+
825+ @return An error code: 0 - success, otherwise - failure
826+
827+ @ref Developer
828+ **/
829+ int CeedGetWorkVectorMemoryUsage (Ceed ceed , CeedScalar * usage_mb ) {
830+ * usage_mb = 0.0 ;
831+ if (ceed -> work_vectors ) {
832+ for (CeedInt i = 0 ; i < ceed -> work_vectors -> num_vecs ; i ++ ) {
833+ CeedSize vec_len ;
834+ CeedCall (CeedVectorGetLength (ceed -> work_vectors -> vecs [i ], & vec_len ));
835+ * usage_mb += vec_len ;
836+ }
837+ * usage_mb *= sizeof (CeedScalar ) * 1e-6 ;
838+ CeedDebug (ceed , "Resource {%s}: Work vectors memory usage: %" CeedInt_FMT " vectors, %g MB\n" , ceed -> resource , ceed -> work_vectors -> num_vecs ,
839+ * usage_mb );
840+ }
841+ return CEED_ERROR_SUCCESS ;
842+ }
843+
844+ /**
845+ @brief Clear inactive work vectors in a `Ceed` context below a minimum length.
846+
847+ @param[in,out] ceed `Ceed` context
848+ @param[in] min_len Minimum length of work vector to keep
849+
850+ @return An error code: 0 - success, otherwise - failure
851+
852+ @ref Backend
853+ **/
854+ int CeedClearWorkVectors (Ceed ceed , CeedSize min_len ) {
855+ if (!ceed -> work_vectors ) return CEED_ERROR_SUCCESS ;
856+ for (CeedInt i = 0 ; i < ceed -> work_vectors -> num_vecs ; i ++ ) {
857+ if (ceed -> work_vectors -> is_in_use [i ]) continue ;
858+ CeedSize vec_len ;
859+ CeedCall (CeedVectorGetLength (ceed -> work_vectors -> vecs [i ], & vec_len ));
860+ if (vec_len < min_len ) {
861+ ceed -> ref_count += 2 ; // Note: increase ref_count to prevent Ceed destructor from triggering
862+ CeedCall (CeedVectorDestroy (& ceed -> work_vectors -> vecs [i ]));
863+ ceed -> ref_count -= 1 ; // Note: restore ref_count
864+ ceed -> work_vectors -> num_vecs -- ;
865+ if (ceed -> work_vectors -> num_vecs > 0 ) {
866+ ceed -> work_vectors -> vecs [i ] = ceed -> work_vectors -> vecs [ceed -> work_vectors -> num_vecs ];
867+ ceed -> work_vectors -> is_in_use [i ] = ceed -> work_vectors -> is_in_use [ceed -> work_vectors -> num_vecs ];
868+ ceed -> work_vectors -> is_in_use [ceed -> work_vectors -> num_vecs ] = false;
869+ i -- ;
870+ }
871+ }
872+ }
873+ return CEED_ERROR_SUCCESS ;
874+ }
875+
820876/**
821877 @brief Get a `CeedVector` for scratch work from a `Ceed` context.
822878
@@ -831,7 +887,8 @@ int CeedReference(Ceed ceed) {
831887 @ref Backend
832888**/
833889int CeedGetWorkVector (Ceed ceed , CeedSize len , CeedVector * vec ) {
834- CeedInt i = 0 ;
890+ CeedInt i = 0 ;
891+ CeedScalar usage_mb ;
835892
836893 if (!ceed -> work_vectors ) CeedCall (CeedWorkVectorsCreate (ceed ));
837894
@@ -858,6 +915,7 @@ int CeedGetWorkVector(Ceed ceed, CeedSize len, CeedVector *vec) {
858915 ceed -> work_vectors -> num_vecs ++ ;
859916 CeedCallBackend (CeedVectorCreate (ceed , len , & ceed -> work_vectors -> vecs [i ]));
860917 ceed -> ref_count -- ; // Note: ref_count manipulation to prevent a ref-loop
918+ if (ceed -> is_debug ) CeedGetWorkVectorMemoryUsage (ceed , & usage_mb );
861919 }
862920 // Return pointer to work vector
863921 ceed -> work_vectors -> is_in_use [i ] = true;
0 commit comments