Skip to content

MoreMaps.jl

A flexible mapping framework for Julia that provides different parallel backends, progress tracking, and iteration patterns.

Features

  • Multiple backends: Sequential, Threaded, Distributed (Pmap), and Daggermap execution

  • Progress tracking: LogLogger, ProgressLogger, TermLogger, and QualityLogger

  • Nested array support: Map over specific leaf types in nested array structures

  • Cartesian (and arbitrary) expansions: Easy combinatorial iteration over inputs

  • Tuple / NamedTuple inputs: Map over Tuples and NamedTuples, returning the same shape

  • DimensionalData support: Map directly over Dimension arguments

Quick Start

julia
using MoreMaps

# Basic usage with default sequential backend
x = rand(100)
C = Chart()
y = map(sqrt, C, x)

# Use threading for parallel execution
C_threaded = Chart(Threaded())
y_threaded = map(sqrt, C_threaded, x)

# Add progress tracking
C_progress = Chart(Threaded(), LogLogger(10))
y_progress = map(sqrt, C_progress, x)
100-element Vector{Float64}:
 0.37411501514180423
 0.4739641570766191
 0.9544805485859318
 0.9589927903587687
 0.6941675579451689
 0.7060223528636117
 0.556742470941165
 0.9895682179059248
 0.4633321065718647
 0.9111090649316985

 0.4136934556655939
 0.5452735437683048
 0.8370080680680487
 0.7855607521754191
 0.6713509153109212
 0.7095369056105864
 0.14966629076100588
 0.29581729528664535
 0.8774251115550487

You can also pass a Backend or Progress value (or even the bare type) directly to map, and a default Chart wrapping it will be constructed for you:

julia
using MoreMaps
x = rand(10)
map(sqrt, Threaded(), x)        # equivalent to map(sqrt, Chart(Threaded()), x)
map(sqrt, LogLogger(5), x)      # equivalent to map(sqrt, Chart(LogLogger(5)), x)
10-element Vector{Float64}:
 0.17743328555359794
 0.9913638156386827
 0.2417152801519074
 0.7043278486643413
 0.9668754760347431
 0.9979062605533893
 0.6050113466953589
 0.7653565956309032
 0.8908547708976027
 0.9974458856161245

Basics

The basis of a MoreMaps map is the Chart type, which configures how mapping operations are executed.

A Chart is parameterised by four things:

  • backend: Specifies the execution backend

  • progress: Configures the progress logging behavior

  • leaf: The element type where recursion terminates, used for mapping nested arrays. Stored as a type parameter rather than a field.

  • expansion: Determines how the input iterables are combined (e.g. Cartesian product). Either NoExpansion() or a Function.

A chart can be constructed using keywords or arbitrary-order positional arguments. The default Chart() reproduces Base.map(), and is constructed as:

julia
C = Chart(backend   = Sequential(),    # No parallel execution; similar to Base.map
          progress  = NoProgress(),    # No progress logging
          leaf      = MoreMaps.All,    # Map over each element of the root array, like Base.map
          expansion = NoExpansion())   # Map over the original input arrays, as for Base.map

# Or, using positional arguments in any order. Each argument is dispatched on its
# type: `Backend` -> backend, `Progress` -> progress, `Type` -> leaf, `Function`
# -> expansion.
C = Chart(Sequential(), NoProgress(), MoreMaps.All, NoExpansion())

# Default behavior
C == Chart()

Mapping

Once you have a Chart, pass it to the standard Base.map function:

julia
using MoreMaps

x = rand(10)
C = Chart()
y = map(sqrt, C, x)
y == map(sqrt, x)
true

Tuple and NamedTuple inputs are supported and the result is returned with the same shape:

julia
map(x -> x^2, Chart(), (1, 2, 3))             # -> Tuple
map(x -> x^2, Chart(), (a = 1, b = 2, c = 3)) # -> NamedTuple
(a = 1, b = 4, c = 9)

See the following pages for details on configuring a Chart:

  • Backends - Execution strategies (Sequential, Threaded, Pmap, Daggermap)

  • Progress - Progress tracking options (LogLogger, ProgressLogger, TermLogger, QualityLogger, NoProgress)

  • Leaves - Nested array handling

  • Expansions - Cartesian product and custom iterations