Parallel Processing#

Both CadQuery and GMSH use parallel processing for operations like imprinting and meshing. By default, they use all available CPU cores.

When to Limit Threads#

  • Shared servers: Avoid monopolizing all cores

  • Memory constraints: Each thread requires memory; fewer threads = lower peak memory

  • Debugging: Single-threaded execution can make errors easier to diagnose

Limiting Imprinting Threads#

Imprinting is usually the most memory hungry parallel step. The export methods take the thread count directly on the imprint argument, so there is no need to change any global setting:

model.export_dagmc_h5m_file(
    filename="dagmc.h5m",
    imprint=1,  # imprint on a single thread, the lowest peak RAM
)

Only the imprint is limited, the meshing keeps all its threads on every backend, and the previous thread count is restored once the imprint is done. See Imprinting for details.

Limiting CadQuery Threads#

To limit every CadQuery operation rather than just the imprint, CadQuery provides a setThreads function:

from cadquery.occ_impl.shapes import setThreads

setThreads(4)  # Limit to 4 threads

# Now run your geometry operations
import cadquery as cq
from cad_to_dagmc import CadToDagmc

# ...

Alternative: Configure Before Import#

import OCP
OCP.OSD.OSD_ThreadPool.DefaultPool_s(4)  # Limit to 4 threads

import cadquery as cq
from cad_to_dagmc import CadToDagmc

# ...

Alternative: Environment Variable#

export OMP_NUM_THREADS=4
python my_script.py

Or in Python:

import os
os.environ["OMP_NUM_THREADS"] = "4"

import cadquery as cq
from cad_to_dagmc import CadToDagmc

# ...

Limiting GMSH Threads#

GMSH parallelism is controlled through its own options:

import gmsh
import cad_to_dagmc

gmsh_obj = cad_to_dagmc.init_gmsh()

# Limit parallel meshing to 4 threads
gmsh.option.setNumber("General.NumThreads", 4)
gmsh.option.setNumber("Mesh.MaxNumThreads1D", 4)
gmsh.option.setNumber("Mesh.MaxNumThreads2D", 4)
gmsh.option.setNumber("Mesh.MaxNumThreads3D", 4)

# ... continue with meshing ...

Thread Options Summary#

Component

Method

When Applied

Imprinting

imprint=<int> export argument

For the duration of the imprint only

CadQuery

setThreads()

Any time before operations

CadQuery

OSD_ThreadPool.DefaultPool_s()

Before importing CadQuery

CadQuery

OMP_NUM_THREADS env var

Before Python starts

GMSH

General.NumThreads

After GMSH initialization

GMSH

Mesh.MaxNumThreads*D

After GMSH initialization

Complete Example#

import os
os.environ["OMP_NUM_THREADS"] = "4"  # For CadQuery

import cadquery as cq
from cadquery.occ_impl.shapes import setThreads
import gmsh
import cad_to_dagmc

# Limit CadQuery threads
setThreads(4)

# Create geometry
assembly = cq.Assembly()
assembly.add(cq.Workplane("XY").sphere(10))

# Initialize model
model = cad_to_dagmc.CadToDagmc()
model.add_cadquery_object(assembly, material_tags=["mat1"])

# For advanced GMSH control
gmsh_obj = cad_to_dagmc.init_gmsh()
gmsh.option.setNumber("General.NumThreads", 4)
gmsh.option.setNumber("Mesh.MaxNumThreads2D", 4)

# ... continue with export ...

Performance Considerations#

  • More threads generally = faster for large models

  • Memory usage scales with thread count

  • On small models, threading overhead may negate benefits

  • I/O bound operations don’t benefit much from parallelism

See Also#