@@ -146,6 +146,29 @@ def run_processes(self, additional_mpi_args):
146146 + self .__get_gtest_settings (10 , '_' + task_type )
147147 )
148148
149+ def __create_coverage_wrapper (self , template_name , replacements ):
150+ """Create a coverage wrapper script from the template."""
151+ template_path = (
152+ Path (self .__get_project_path ()) / "scripts" / "templates" / template_name
153+ )
154+ wrapper_path = (
155+ Path (self .__get_project_path ()) / "build" / template_name .replace ('.template' , '' )
156+ )
157+
158+ # Read template
159+ with open (template_path , 'r' , encoding = 'utf-8' ) as template_file :
160+ content = template_file .read ()
161+
162+ # Replace placeholders
163+ for key , value in replacements .items ():
164+ content = content .replace (f"{{{ key } }}" , value )
165+
166+ # Write a wrapper script
167+ wrapper_path .write_text (content )
168+ wrapper_path .chmod (0o755 )
169+
170+ return wrapper_path
171+
149172 def run_processes_coverage (self , additional_mpi_args ):
150173 """Run tests in multiprocessing mode with a coverage collection."""
151174 ppc_num_proc = self .__ppc_env .get ("PPC_NUM_PROC" )
@@ -156,50 +179,54 @@ def run_processes_coverage(self, additional_mpi_args):
156179
157180 # Set up coverage environment for MPI processes
158181 if not self .__ppc_env .get ("PPC_ASAN_RUN" ):
159- # Enable coverage data collection for each MPI process
160- self .__ppc_env ["GCOV_PREFIX_STRIP" ] = "0"
161- # Use MPI rank to create unique coverage directories for each process
162- gcov_base_dir = Path (self .__get_project_path ()) / "build" / "gcov_data"
163- gcov_base_dir .mkdir (parents = True , exist_ok = True )
164-
165- # Set GCOV_PREFIX to include MPI rank - this creates separate directories
166- # for each MPI process at runtime
167- self .__ppc_env ["GCOV_PREFIX" ] = str (
168- gcov_base_dir / "rank_${PMI_RANK:-${OMPI_COMM_WORLD_RANK:-${SLURM_PROCID:-0}}}"
169- )
182+ # Check if we're using LLVM coverage or gcov
183+ llvm_profile_file = self .__ppc_env .get ("LLVM_PROFILE_FILE" )
184+
185+ if llvm_profile_file :
186+ # LLVM coverage setup
187+ wrapper_script = self .__create_coverage_wrapper (
188+ "mpi_llvm_coverage_wrapper.sh.template" ,
189+ {"llvm_profile_base" : llvm_profile_file .replace ('%p' , '%p' ).replace ('%m' , '%m' )}
190+ )
170191
171- # Create a wrapper script to set a unique prefix per process
172- wrapper_script = Path ( self . __get_project_path ()) / "build" / "mpi_coverage_wrapper.sh"
173- wrapper_content = f"""#!/bin/bash
174- # Get MPI rank from environment variables
175- if [ -n "$PMIX_RANK" ]; then
176- RANK=$PMIX_RANK
177- elif [ -n "$PMI_RANK" ]; then
178- RANK=$PMI_RANK
179- elif [ -n "$OMPI_COMM_WORLD_RANK" ]; then
180- RANK=$OMPI_COMM_WORLD_RANK
181- elif [ -n "$SLURM_PROCID" ]; then
182- RANK=$SLURM_PROCID
183- else
184- RANK=0
185- fi
186-
187- export GCOV_PREFIX=" { gcov_base_dir } /rank_$RANK"
188- mkdir -p "$ GCOV_PREFIX"
189- exec "$@"
190- """
191- wrapper_script . write_text ( wrapper_content )
192- wrapper_script . chmod ( 0o755 )
192+ # Run tests with the LLVM coverage wrapper
193+ for task_type in [ "all" , "mpi" ]:
194+ test_command = (
195+ mpi_running
196+ + [ str ( wrapper_script )]
197+ + [ str ( self . work_dir / 'ppc_func_tests' )]
198+ + self . __get_gtest_settings ( 10 , '_' + task_type )
199+ )
200+ self . __run_exec ( test_command )
201+ else :
202+ # Original gcov coverage setup
203+ # Enable coverage data collection for each MPI process
204+ self . __ppc_env [ "GCOV_PREFIX_STRIP" ] = "0"
205+ # Use MPI rank to create unique coverage directories for each process
206+ gcov_base_dir = Path ( self . __get_project_path ()) / "build" / "gcov_data"
207+ gcov_base_dir . mkdir ( parents = True , exist_ok = True )
208+
209+ # Set GCOV_PREFIX to include MPI rank - this creates separate directories
210+ # for each MPI process at runtime
211+ self . __ppc_env [ "GCOV_PREFIX" ] = str (
212+ gcov_base_dir / "rank_${PMI_RANK:-${OMPI_COMM_WORLD_RANK:-${SLURM_PROCID:-0}}}"
213+ )
193214
194- # Run tests with a coverage wrapper
195- for task_type in ["all" , "mpi" ]:
196- test_command = (
197- mpi_running
198- + [str (wrapper_script )]
199- + [str (self .work_dir / 'ppc_func_tests' )]
200- + self .__get_gtest_settings (10 , '_' + task_type )
215+ # Create a wrapper script to set a unique prefix per process
216+ wrapper_script = self .__create_coverage_wrapper (
217+ "mpi_gcov_coverage_wrapper.sh.template" ,
218+ {"gcov_base_dir" : str (gcov_base_dir )}
201219 )
202- self .__run_exec (test_command )
220+
221+ # Run tests with a coverage wrapper
222+ for task_type in ["all" , "mpi" ]:
223+ test_command = (
224+ mpi_running
225+ + [str (wrapper_script )]
226+ + [str (self .work_dir / 'ppc_func_tests' )]
227+ + self .__get_gtest_settings (10 , '_' + task_type )
228+ )
229+ self .__run_exec (test_command )
203230
204231 def run_performance (self ):
205232 """Run performance tests."""
0 commit comments