def METHOD_NAME(paths, jobs, split, part):
    print("Using {}x parallelism".format(jobs))
    # Create build folder to prevent process race
    cache_dir.mkdir(exist_ok=True, parents=True)
    (cache_dir / "config").write_text('{"prefix_len": 2}')
    # Validate that paths exist!
    invalid_paths = [p for p in paths if not Path(p).exists()]
    if invalid_paths: print("Invalid paths:\n- " + "\n- ".join(invalid_paths));
    results = len(invalid_paths)
    # Find all project files
    projects = [p for path in paths for p in Path(path).glob("**/project.xml")]
    projects.sort()
    # Split projects up into parts
    if split > 1:
        chunk_size = math.ceil(len(projects) / args.split)
        projects = projects[chunk_size*args.part:min(chunk_size*(args.part+1), len(projects))]
    # first generate all projects
    with ThreadPool(jobs) as pool:
        projects = pool.map(generate, projects)
    results += projects.count(None)
    # Filter projects for successful generation
    projects = [p for p in projects if p is not None]
    # Then build the successfully generated ones
    with ThreadPool(jobs) as pool:
        projects = pool.map(build, projects)
    results += projects.count(None)
    # Filter projects for successful compilation and runablity
    projects = [p for p in projects if p is not None and "CI: run" in p.read_text()]
    # Then run the successfully compiled ones
    with ThreadPool(jobs) as pool:
        projects = pool.map(run, projects)
    results += projects.count(None)
    return results