nvMolKit

repository·main·Indexed 42 days ago

https://github.com/nvidia-bionemo/nvmolkit

A CUDA-backed Python library for accelerating common RDKit molecular operations. It leverages NVIDIA GPUs and PyTorch for high-performance molecular modeling and manipulation, integrating closely with RDKit for chemical informatics. Version 0.6.0 requires an NVIDIA GPU with compute capability 7.0 or higher and CUDA 12.6 or later.

Tokens
29.8K
Snippets
75
Records
104
Agent score
49%

What's inside nvMolKit

  1. nvMolKit Features Overview

    main

    nvMolKit provides GPU-accelerated versions of common RDKit operations:

    • Morgan Fingerprints: Parallel generation for batches (sizes 128, 256, 512, 1024, 2048).
    • Molecular Similarity: Tanimoto and cosine similarity; supports all-to-all comparisons and chunked computation to limit memory usage.
    • ETKDG Conformer Generation: Batch 3D conformer generation; supports multiple GPUs.
    • Geometry Relaxation: Force field optimization (MMFF94 and UFF); supports multiple GPUs.
    • Butina clustering: GPU-accelerated Taylor-Butina clustering.
    • Substructure Search: GPU-accelerated matching for SMILES/SMARTS queries.
    • Maximum Common Substructure (MCS): GPU-accelerated MCS search across molecule pairs.
    • Conformer RMSD: Pairwise RMSD matrix computation for ensembles.
    • Torsion Fingerprint Deviation (TFD): GPU-accelerated TFD computation for geometry comparison.
  2. Use nvMolKit for GPU-accelerated cheminformatics

    main

    nvMolKit provides a Python API for performing batched, GPU-accelerated cheminformatics operations. It is designed to provide high-performance alternatives to RDKit-style operations by leveraging GPU acceleration.

    Key capabilities include:

    • Fingerprinting: Morgan fingerprints.
    • Similarity Search: Tanimoto and cosine similarity.
    • Conformer Generation & Optimization: ETKDG conformer embedding and MMFF/UFF force-field optimization.
    • Structural Analysis: TFD (Topological Fingerprint Descriptor), conformer RMSD, and substructure search.
    • Advanced Search: Maximum Common Substructure (MCS) search.
    • Clustering: Butina clustering.
  3. What is nvMolKit and when to use it

    main

    nvMolKit provides GPU-accelerated, batched implementations of common RDKit operations. It is designed for high-throughput cheminformatics workflows where you process large batches (typically thousands or more) of molecules in parallel on one or more GPUs.

    Use nvMolKit when:

    • You have a large batch of molecules.
    • You care about total throughput/wall time rather than per-molecule latency.
    • You are repeating the same operation identically across a batch (e.g., fingerprinting a library or bulk similarity).

    Use plain RDKit when:

    • You are processing single molecules (one-offs).
    • Your workflow cannot be expressed as a batch.

    Note: nvMolKit links against RDKit; inputs and outputs are real RDKit Mol objects.

  4. Handle Asynchronous GPU Results with AsyncGpuResult

    main

    Operations that return GPU-resident data (like fingerprinting or similarity) return an AsyncGpuResult object. This allows you to queue multiple GPU operations without waiting for each to complete, enabling efficient pipeline construction.

    Accessing Results: To retrieve the data, you must synchronize the GPU and then convert the result to your desired format:

    • .torch(): Returns a zero-copy torch Tensor (stays on GPU).
    • .numpy(): Returns a numpy array (moves data to CPU; involves synchronization).

    Streams: Most operations accept an optional stream parameter (a torch.cuda.Stream) to control execution.

    Synchronization: Use torch.cuda.synchronize() to ensure all queued operations are complete before accessing results.

    from nvmolkit.fingerprints import MorganFingerprintGenerator
    import torch
    
    fpgen = MorganFingerprintGenerator(radius=2, fpSize=1024)
    # Returns AsyncGpuResult
    result = fpgen.GetFingerprints(mols)
    
    # Accessing results
    torch.cuda.synchronize()
    fps_torch = result.torch()  # Zero-copy on GPU
    fps_numpy = result.numpy()  # Moves to CPU
  5. How AsyncGpuResult works

    main

    The AsyncGpuResult type is used by operations that return a single flat tensor (e.g., fingerprints, similarity matrices, RMSD/TFD vectors, Butina inputs).

    Key Behaviors:

    • Asynchronous: The kernel may not have completed when the call returns. You must synchronize before reading values on the host.
    • Zero-copy Torch: result.torch() returns a zero-copy torch.Tensor on the GPU.
    • Numpy Conversion: result.numpy() synchronizes and returns a CPU numpy array.
    • Interoperability: It exposes __cuda_array_interface__, allowing it to be passed directly into other nvMolKit functions (e.g., fingerprints $\rightarrow$ similarity) without a host round-trip.

    CUDA Stream Control: A subset of APIs (fingerprints, similarity, Butina, RMSD) accept an optional stream: torch.cuda.Stream | None = None argument. This allows you to overlap nvMolKit work with your own kernels using non-default streams.

    import torch
    from rdkit import Chem
    from nvmolkit.fingerprints import MorganFingerprintGenerator
    from nvmolkit.similarity import crossTanimotoSimilarity
    
    stream = torch.cuda.Stream()
    fpgen = MorganFingerprintGenerator(radius=2, fpSize=1024)
    mols = [Chem.MolFromSmiles(smi) for smi in ["CCO", "c1ccccc1", "CC(=O)O"]]
    
    with torch.cuda.stream(stream):
        fps = fpgen.GetFingerprints(mols, stream=stream)
        sim = crossTanimotoSimilarity(fps, stream=stream)
    stream.synchronize()
    print(sim.torch())
  6. Configure MMFFBatchedForcefield for fine-grained control

    main

    Use MMFFBatchedForcefield when you need per-molecule settings or atom-specific constraints. Unlike the top-level functions, this class allows you to pass sequences (lists) for scalar arguments to apply different settings to each molecule in the batch.

    Supported per-molecule arguments:

    • properties: RDKit MMFFMolProperties objects (or None for defaults).
    • nonBondedThreshold: Non-bonded cutoff distance.
    • ignoreInterfragInteractions: Boolean to omit non-bonded terms between fragments.

    Constraints: Constraints are added via a per-molecule view ff[i]. Constraints applied to molecule i affect all its conformers. Use the relative=True flag on distance, angle, or torsion constraints to use offsets from the current geometry instead of absolute values.

    from rdkit.Chem import AllChem
    from nvmolkit.batchedForcefield import MMFFBatchedForcefield
    
    # Setup per-molecule properties
    props_b = AllChem.MMFFGetMoleculeProperties(mols[1])
    props_c = AllChem.MMFFGetMoleculeProperties(mols[2])
    props_c.SetMMFFVariant("MMFF94s")
    props_c.SetMMFFDielectricConstant(4.0)
    props_c.SetMMFFDielectricModel(2)  # 1 = constant, 2 = distance-dependent
    
    # Initialize batched forcefield with per-molecule lists
    ff = MMFFBatchedForcefield(
        mols,
        properties=[None, props_b, props_c],
        nonBondedThreshold=[100.0, 25.0, 25.0],
        ignoreInterfragInteractions=[True, False, True],
    )
    
    # Add constraints to specific molecules
    ff[0].add_distance_constraint(idx1=0, idx2=2, relative=True, min_len=-0.2, max_len=0.5, force_constant=20.0)
    ff[0].add_position_constraint(idx=0, max_displ=0.1, force_constant=50.0)
    ff[1].add_angle_constraint(idx1=0, idx2=1, idx3=2, relative=False, min_angle_deg=100.0, max_angle_deg=120.0, force_constant=25.0)
    ff[2].add_torsion_constraint(idx1=0, idx2=1, idx3=2, idx4=3, relative=False, min_dihedral_deg=-10.0, max_dihedral_deg=10.0, force_constant=8.0)
    
    # Run minimization
    energies, converged = ff.minimize(maxIters=200, forceTol=1e-4)
  7. Configure GPU Target Architectures via NVMOLKIT_CUDA_TARGET_MODE

    main

    The NVMOLKIT_CUDA_TARGET_MODE CMake variable determines which GPU architectures are supported in the build:

    • default: Uses CMAKE_CUDA_ARCHITECTURES if provided; otherwise, defaults to compute capability 7.0.
    • native: Builds specifically for the GPU present on the current system. This is recommended for local development as it is the fastest, but the resulting binary is not portable.
    • full: Builds for all architectures $\ge$ 7.0, including Blackwell (requires NVCC $\ge$ 12.8). This is recommended for distribution as it works on all major GPUs, though it results in larger binaries and longer compile times.

    Recommendation: Use native for development and full for distribution.

  8. Hardware and Driver Requirements for nvMolKit

    main

    To run nvMolKit, your environment must meet the following requirements:

    • GPU: NVIDIA GPU with compute capability 7.0 (V100) or higher.
    • Driver: CUDA Driver sufficient for CUDA 12.6 or later (driver version >= 560.28).
    • PyTorch: The installed PyTorch CUDA backend must be compatible with your host driver. If using pip, ensure you select the correct CUDA backend from the PyTorch local install selector.
  9. How molecular similarity works in nvMolKit

    main

    nvMolKit provides GPU-accelerated Tanimoto and cosine similarity computations.

    Core Behavior:

    • Each similarity call returns an n × m matrix representing the similarity between two batches of fingerprints.
    • If only one batch is provided, the function performs an all-to-all similarity computation, returning an n × n matrix.
    • The results can be accessed as a PyTorch tensor by calling the .torch() method on the returned AsyncGpuResult object.

    Input Requirements:

    • Data Type: Inputs must be int32 or uint32.
    • Shape: Fingerprints must be packed into 32-bit integers with shape (num_fingerprints, fp_size/32). Each row represents a fingerprint, and each column represents a 32-bit block.
    • Consistency: If two batches are provided, they must both have the same fp_size.
    # Example of accessing the result as a torch tensor
    sims = crossTanimotoSimilarity(fps).torch()
  10. How Device3DResult works

    main

    The Device3DResult type is used by ETKDG embedding and MMFF/UFF optimization (both one-shot and BatchedForcefield) when called with output=CoordinateOutput.DEVICE. This is the GPU-resident equivalent of writing conformers back to Mol objects, ideal for chaining downstream GPU work without host round-trips.

    Fields:

    • values: AsyncGpuResult of shape (total_atoms, 3) float64. Concatenated conformer coordinates in CSR-style layout.
    • atom_starts, mol_indices, conf_indices: AsyncGpuResult int32 buffers describing the layout (values[atom_starts[i]:atom_starts[i+1]] is conformer i's atoms).
    • energies, converged: AsyncGpuResult buffers (populated only for MMFF/UFF minimization).
    • gpu_id: The device the buffers live on.

    Methods:

    • .per_molecule(): Returns nested list[list[torch.Tensor]] of per-conformer views.
    • .dense(pad_value=nan): Materializes a padded (n_mols, max_confs, max_atoms, 3) tensor.
  11. How MCSBatchResult works

    main

    The findMCS function is synchronous and returns an MCSBatchResult backed by CPU NumPy arrays.

    Key Behaviors:

    • Flat Results: Results are returned as a flat list. result[k] (or result.get_result(k)) materializes the result at pair position k.
    • Pair Identification: Use result.pairs[k] to identify which pair the result corresponds to.
    • Mapping: Each MCSResult contains pair, num_atoms, num_bonds, canceled, atom_mapping, and bond_mapping. The two columns of each mapping index the first and second molecule of that result pair, respectively.
  12. Install nvMolKit via Conda (Recommended)

    main

    Conda is the recommended installation method for nvMolKit. Ensure you have a conda-based environment manager (like Miniconda or Miniforge) activated.

    Standard Installation:

    conda install -c conda-forge nvmolkit

    Installation with specific CUDA version: If your system's CUDA driver does not support CUDA 13, you should pin a CUDA 12 backend and include the pytorch-gpu metapackage:

    conda install -c conda-forge nvmolkit pytorch-gpu cuda_version=12.6

    Note: Choose a cuda_version less than or equal to the version reported by nvidia-smi.

    conda install -c conda-forge nvmolkit