calculate_multiplication_blocks

C++ Function Reference

1 Signature

BlockSizes BigDataStatMeth::calculate_multiplication_blocks(hsize_t N, hsize_t M, hsize_t K)

2 Description

Calculate optimal block sizes specifically for multiplication.

3 Parameters

  • N (hsize_t): Number of result rows (dsA->ncols)
  • M (hsize_t): Number of result cols (dsB->nrows)
  • K (hsize_t): Inner dimension (dsA->nrows = dsB->ncols)

4 Returns

Type: BlockSizes

5 Details

NNumber of result rows (dsA->ncols) MNumber of result cols (dsB->nrows) KInner dimension (dsA->nrows = dsB->ncols)

6 Call Graph

Function dependencies

7 Source Code

File: inst/include/hdf5Algebra/multiplication.hppLines 105-161

inline BlockSizes calculate_multiplication_blocks(hsize_t N, hsize_t M, hsize_t K) {
        const hsize_t MEMORY_BUDGET = (hsize_t)(1.5 * 1024 * 1024 * 1024);  // 1.5GB
        const hsize_t bytes_per_element = sizeof(double);
        const hsize_t min_block = 256;
        
        BlockSizes result;
        result.type = classify_matrix_type(N, M, K);
        
        switch (result.type) {
        case RECTANGULAR_EXTREME: {
            // Para big-omics: K >> N,M - priorizar bloques grandes en K
            hsize_t small_dim = std::min(N, M);
            result.output_block = std::min(small_dim, (hsize_t)1024);
            
            // Maximizar bloque K con memoria restante
            // Memory = A_block + B_block = K×(N+M) aprox
            hsize_t remaining_budget = (hsize_t)(0.8 * MEMORY_BUDGET);
            result.inner_block = remaining_budget / ((N + M) * bytes_per_element);
            result.inner_block = std::min({result.inner_block, K, (hsize_t)32768});
            break;
        }
            
        case SQUARE_SMALL: {
            hsize_t block = sqrt(MEMORY_BUDGET / (3 * bytes_per_element));
            block = std::min({block, N/2, M/2, K/2});
            result.inner_block = result.output_block = block;
            break;
        }
            
        case SQUARE_LARGE: {
            hsize_t target_blocks = 2;  // 2×2 output blocks
            result.output_block = std::max({N / target_blocks, M / target_blocks, min_block});
            
            hsize_t output_memory = result.output_block * result.output_block * bytes_per_element;
            hsize_t remaining_budget = MEMORY_BUDGET - output_memory;
            result.inner_block = remaining_budget / (2 * result.output_block * bytes_per_element);
            result.inner_block = std::min({result.inner_block, K, (hsize_t)16384});
            break;
        }
            
        case SQUARE_EXTREME: {
            hsize_t block = sqrt(MEMORY_BUDGET / (3 * bytes_per_element));
            block = std::min({block, (hsize_t)8192});
            result.inner_block = result.output_block = block;
            break;
        }
        }
        
        // Aplicar límites y redondear
        result.inner_block = std::max(result.inner_block, min_block);
        result.output_block = std::max(result.output_block, min_block);
        
        result.inner_block = ((result.inner_block + 63) / 64) * 64;
        result.output_block = ((result.output_block + 63) / 64) * 64;
        
        return result;
    }

8 Usage Example

#include "BigDataStatMeth.hpp"

// Example usage
auto result = calculate_multiplication_blocks(...);