Parallel Processing#

Both CadQuery and GMSH use parallel processing for operations like imprinting and meshing. By default, imprinting explicitly requests the OpenCASCADE logical processor count; meshing has separate thread controls.

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. Set the keyword-only imprint_threads argument without changing a global setting:

model.export_dagmc_h5m_file(
    filename="dagmc.h5m",
    imprint_threads=1,  # Lower peak RAM
)

Only imprinting is limited; meshing uses its own settings on both backends. The previous pool size is restored afterwards, including on errors. By default, imprint_threads="all" requests all logical processors, overriding an existing limit. See Imprinting for the available options.

Limiting cad-to-dagmc-mesher Meshing Threads#

The cad-to-dagmc-mesher backend meshes in parallel after the imprint (the surface triangulation, the edge discretisation, merging and repair, the mesh checks and any tet meshing). Set the keyword-only mesh_threads argument to run that on fewer threads, for a lower peak RAM at the cost of speed:

model.export_dagmc_h5m_file(
    filename="dagmc.h5m",
    imprint_threads=4,
    mesh_threads=4,
)

The mesh is the same on any number of threads. mesh_threads="all" (the default) leaves the mesher’s thread pool as it is. The limit applies for the export only and is undone afterwards, including on errors. It is also accepted by export_unstructured_mesh_file. The gmsh backend takes threads instead and warns that mesh_threads is unused. A cad-to-dagmc-mesher too old to take mesh_threads raises RuntimeError for anything other than "all".

Limiting CadQuery Threads#

For other CadQuery operations, use setThreads to configure the OpenCASCADE thread pool:

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_threads=4

For the duration of the imprint only

cad-to-dagmc-mesher meshing

mesh_threads=4

For the meshing after the imprint only

CadQuery

setThreads()

Before other CadQuery 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#