import multiprocessing
from functools import reduce
import numpy as np

def {{ func_name }}_worker({{ ", ".join(func_args) }}):
    {{ func_body }}
    {% if is_class_method %}
    return self.results if hasattr(self, 'results') else None
    {% else %}
    return result
    {% endif %}

def {{ func_name }}_reduce(results):
    return reduce(lambda x, y: x + y, results)

def {{ func_name }}_parallel({{ ", ".join(func_args) }}):
    # Determine number of processors
    num_procs = multiprocessing.cpu_count()
    
    {% if is_class_method %}
    # For class methods, create multiple instances
    import copy
    instances = [copy.deepcopy(self) for _ in range(num_procs)]
    
    # Create process pool
    with multiprocessing.Pool() as pool:
        # Map phase: Process data in parallel
        mapped_results = pool.map({{ func_name }}_worker, instances)
        
        # Reduce phase: Combine results
        final_result = {{ func_name }}_reduce(mapped_results)
    
    return final_result
    {% else %}
    # For regular functions, use the first argument as data
    data = {{ func_args[0] if func_args else "data" }}
    
    # Create chunks for spatial domain partitioning
    chunks = np.array_split(data, num_procs) if hasattr(data, '__len__') else [data]
    
    # Create process pool
    with multiprocessing.Pool() as pool:
        # Map phase: Process chunks in parallel
        mapped_chunks = pool.map({{ func_name }}_worker, chunks)
        
        # Reduce phase: Combine results from all chunks
        final_result = {{ func_name }}_reduce(mapped_chunks)
    
    return final_result
    {% endif %}

if __name__ == '__main__':
    # Example usage
    {% if is_class_method %}
    # For class methods, create an instance first
    instance = SomeClass()
    {% if func_args|length > 1 %}
    result = instance.{{ func_name }}_parallel({{ func_args[1] }})
    {% else %}
    result = instance.{{ func_name }}_parallel()
    {% endif %}
    {% else %}
    # For regular functions
    result = {{ func_name }}_parallel({{ func_args[0] if func_args else "data" }})
    {% endif %}

