# `Kernel.ParallelCompiler`
[🔗](https://github.com/elixir-lang/elixir/blob/v1.20.0-rc.3/lib/elixir/lib/kernel/parallel_compiler.ex#L5)

A module responsible for compiling and requiring files in parallel.

# `compile_opts`

```elixir
@type compile_opts() :: [
  after_compile: (-&gt; term()),
  each_file: (Path.t() -&gt; term()),
  each_long_compilation: (Path.t() -&gt; term()) | (Path.t(), pid() -&gt; term()),
  each_long_verification: (module() -&gt; term()) | (module(), pid() -&gt; term()),
  each_module: (Path.t(), module(), binary() -&gt; term()),
  each_cycle: ([module()], [Code.diagnostic(:warning)] -&gt;
                 {:compile, [module()], [Code.diagnostic(:warning)]}
                 | {:runtime, [module()], [Code.diagnostic(:warning)]}),
  long_compilation_threshold: pos_integer(),
  long_verification_threshold: pos_integer(),
  verification: boolean(),
  profile: :time,
  dest: Path.t(),
  beam_timestamp: term(),
  return_diagnostics: boolean(),
  max_concurrency: pos_integer(),
  purge_compiler_modules: boolean()
]
```

Options for parallel compilation functions.

# `error`

```elixir
@type error() :: {file :: Path.t(), Code.position(), message :: String.t()}
```

# `info`

```elixir
@type info() :: %{
  runtime_warnings: [Code.diagnostic(:warning)],
  compile_warnings: [Code.diagnostic(:warning)]
}
```

# `require_opts`

```elixir
@type require_opts() :: [
  each_file: (Path.t() -&gt; term()),
  each_module: (Path.t(), module(), binary() -&gt; term()),
  max_concurrency: pos_integer(),
  return_diagnostics: boolean()
]
```

Options for requiring files in parallel.

# `warning`

```elixir
@type warning() :: {file :: Path.t(), Code.position(), message :: String.t()}
```

# `async`

> This function is deprecated. Use `pmap/2` instead.

Starts a task for parallel compilation.

# `compile`
*since 1.6.0* 

```elixir
@spec compile([Path.t()], compile_opts()) ::
  {:ok, [atom()], [warning()] | info()}
  | {:error, [error()] | [Code.diagnostic(:error)], [warning()] | info()}
```

Compiles the given files.

Those files are compiled in parallel and can automatically
detect dependencies between them. Once a dependency is found,
the current file stops being compiled until the dependency is
resolved.

It must be invoked with `return_diagnostics: true` as option, so it returns
`{:ok, modules, warnings_info}` or `{:error, errors, warnings_info}`,
where `warnings_info` has the shape:

    %{
      runtime_warnings: [warning],
      compile_warnings: [warning]
    }

## Options

  * `:after_compile` - invoked after all modules are compiled, but before
    they are verified. If the files are being written to disk, such as in
    `compile_to_path/3`, this will be invoked after the files are written

  * `:each_file` - for each file compiled, invokes the callback passing the
    file

  * `:each_long_compilation` - for each file that takes more than a given
    timeout (see the `:long_compilation_threshold` option) to compile, invoke
    this callback passing the file as its argument (and optionally the PID
    of the process compiling the file)

  * `:each_long_verification` (since v1.19.0) - for each file that takes more
    than a given timeout (see the `:long_verification_threshold` option) to
    compile, invoke this callback passing the module as its argument (and
    optionally the PID of the process verifying the module)

  * `:each_module` - for each module compiled, invokes the callback passing
    the file, module and the module bytecode

  * `:each_cycle` - after the given files are compiled, invokes this function
    that should return the following values:
    * `{:compile, modules, warnings}` - to continue compilation with a list of
      further modules to compile
    * `{:runtime, modules, warnings}` - to stop compilation and verify the list
      of modules because dependent modules have changed

  * `:long_compilation_threshold` - the timeout (in seconds) to check for files
    taking too long to compile. For each file that exceeds the threshold, the
    `:each_long_compilation` callback is invoked. Defaults to `10` seconds.

  * `:long_verification_threshold` (since v1.19.0) - the timeout (in seconds) to
    check for modules taking too long to compile. For each module that exceeds the
    threshold, the `:each_long_verification` callback is invoked. Defaults to
    `10` seconds.

  * `:verification` (since v1.19.0) - if code verification, such as unused functions,
    deprecation warnings, and type checking should run. Defaults to `true`.
    We recommend disabling it only for debugging purposes.

  * `:profile` - if set to `:time` measure the compilation time of each compilation cycle
     and group pass checker

  * `:purge_compiler_modules` - if set to `true`, automatically purge compilation modules
    after compilation (see `Code.purge_compiler_modules/0`)

  * `:dest` - the destination directory for the BEAM files. When using `compile/2`,
    this information is only used to properly annotate the BEAM files before
    they are loaded into memory. If you want a file to actually be written to
    `dest`, use `compile_to_path/3` instead.

  * `:beam_timestamp` - the modification timestamp to give all BEAM files

  * `:return_diagnostics` (since v1.15.0) - returns maps with information instead of
    a list of warnings and returns diagnostics as maps instead of tuples.
    This option must be set to true, except for backwards compatibibility reasons.

  * `:max_concurrency` - the maximum number of files to compile in parallel.
    Setting this option to 1 will compile files sequentially.
    Defaults to the number of schedulers online, or at least `2`.

# `compile_to_path`
*since 1.6.0* 

```elixir
@spec compile_to_path([Path.t()], Path.t(), compile_opts()) ::
  {:ok, [atom()], [warning()] | info()}
  | {:error, [error()] | [Code.diagnostic(:error)], [warning()] | info()}
```

Compiles the given files and writes resulting BEAM files into path.

See `compile/2` for more information.

# `pmap`
*since 1.16.0* 

Perform parallel compilation of `collection` with `fun`.

If you have a file that needs to compile other modules in parallel,
the spawned processes need to be aware of the compiler environment.
This function allows a developer to perform such tasks.

# `require`
*since 1.6.0* 

```elixir
@spec require([Path.t()], require_opts()) ::
  {:ok, [atom()], [warning()] | info()}
  | {:error, [error()] | [Code.diagnostic(:error)], [warning()] | info()}
```

Requires the given files in parallel.

Opposite to compile, dependencies are not attempted to be
automatically solved between files.

It must be invoked with `return_diagnostics: true` as option, so it returns
`{:ok, modules, warnings_info}` or `{:error, errors, warnings_info}`,
where `warnings_info` has the shape:

    %{
      runtime_warnings: [warning],
      compile_warnings: [warning]
    }

## Options

  * `:each_file` - for each file compiled, invokes the callback passing the
    file

  * `:each_module` - for each module compiled, invokes the callback passing
    the file, module and the module bytecode

  * `:max_concurrency` - the maximum number of files to compile in parallel.
    Setting this option to 1 will compile files sequentially.
    Defaults to the number of schedulers online, or at least `2`.

  * `:return_diagnostics` (since v1.15.0) - returns maps with information instead of
    a list of warnings and returns diagnostics as maps instead of tuples.
    This option must be set to true, except for backwards compatibibility reasons.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
