https://github.com/halide/Halide
Raw File
Tip revision: a317ebe4aa0bbf3412163b528923158b977f4a73 authored by Steven Johnson on 28 March 2018, 00:45:23 UTC
Various test fixes
Tip revision: a317ebe
Module.h
#ifndef HALIDE_MODULE_H
#define HALIDE_MODULE_H

/** \file
 *
 * Defines Module, an IR container that fully describes a Halide program.
 */

#include <functional>

#include "Argument.h"
#include "ExternalCode.h"
#include "IR.h"
#include "ModulusRemainder.h"
#include "Outputs.h"
#include "Target.h"

namespace Halide {

/** Type of linkage a function in a lowered Halide module can have. 
    Also controls whether auxiliary functions and metadata are generated. */
enum class LinkageType {
    External, ///< Visible externally.
    ExternalPlusMetadata, ///< Visible externally. Argument metadata and an argv wrapper are also generated.
    Internal, ///< Not visible externally, similar to 'static' linkage in C.
};

namespace Internal {

/** Definition of an argument to a LoweredFunc. This is similar to
 * Argument, except it enables passing extra information useful to
 * some targets to LoweredFunc. */
struct LoweredArgument : public Argument {
    /** For scalar arguments, the modulus and remainder of this
     * argument. */
    ModulusRemainder alignment;

    LoweredArgument() {}
    LoweredArgument(const Argument &arg) : Argument(arg) {}
    LoweredArgument(const std::string &_name, Kind _kind, const Type &_type, uint8_t _dimensions,
                    Expr _def = Expr(),
                    Expr _min = Expr(),
                    Expr _max = Expr()) : Argument(_name, _kind, _type, _dimensions, _def, _min, _max) {}
};

/** Definition of a lowered function. This object provides a concrete
 * mapping between parameters used in the function body and their
 * declarations in the argument list. */
struct LoweredFunc {
    std::string name;

    /** Arguments referred to in the body of this function. */
    std::vector<LoweredArgument> args;

    /** Body of this function. */
    Stmt body;

    /** The linkage of this function. */
    LinkageType linkage;

    /** The name-mangling choice for the function. Defaults to using
     * the Target. */
    NameMangling name_mangling;

    LoweredFunc(const std::string &name,
                const std::vector<LoweredArgument> &args,
                Stmt body,
                LinkageType linkage,
                NameMangling mangling = NameMangling::Default);
    LoweredFunc(const std::string &name,
                const std::vector<Argument> &args,
                Stmt body,
                LinkageType linkage,
                NameMangling mangling = NameMangling::Default);
};

}

namespace Internal {
struct ModuleContents;
}

/** A halide module. This represents IR containing lowered function
 * definitions and buffers. */
class Module {
    Internal::IntrusivePtr<Internal::ModuleContents> contents;

public:
    Module(const std::string &name, const Target &target);

    /** Get the target this module has been lowered for. */
    const Target &target() const;

    /** The name of this module. This is used as the default filename
     * for output operations. */
    const std::string &name() const;

    /** If this Module had an auto-generated schedule, this is the C++ source
     * for that schedule. */
    const std::string &auto_schedule() const;

    /** The declarations contained in this module. */
    // @{
    const std::vector<Buffer<>> &buffers() const;
    const std::vector<Internal::LoweredFunc> &functions() const;
    std::vector<Internal::LoweredFunc> &functions();
    const std::vector<Module> &submodules() const;
    const std::vector<ExternalCode> &external_code() const;
    // @}

    /** Return the function with the given name. If no such function
    * exists in this module, assert. */
    Internal::LoweredFunc get_function_by_name(const std::string &name) const;

    /** Add a declaration to this module. */
    // @{
    void append(const Buffer<> &buffer);
    void append(const Internal::LoweredFunc &function);
    void append(const Module &module);
    void append(const ExternalCode &external_code);
    // @}

    /** Compile a halide Module to variety of outputs, depending on
     * the fields set in output_files. */
    void compile(const Outputs &output_files_arg) const;

    /** Compile a halide Module to in-memory object code. Currently
     * only supports LLVM based compilation, but should be extended to
     * handle source code backends. */
    Buffer<uint8_t> compile_to_buffer() const;

    /** Return a new module with all submodules compiled to buffers on
     * on the result Module. */
    Module resolve_submodules() const;

    /** When generating metadata from this module, remap any occurrences
     * of 'from' into 'to'. */
    void remap_metadata_name(const std::string &from, const std::string &to) const;

    /** Retrieve the metadata name map. */
    std::map<std::string, std::string> get_metadata_name_map() const;

    /** Set the auto_schedule text for the Module. It is an error to call this
     * multiple times for a given Module. */
    void set_auto_schedule(const std::string &auto_schedule);
};

/** Link a set of modules together into one module. */
Module link_modules(const std::string &name, const std::vector<Module> &modules);

/** Create an object file containing the Halide runtime for a given
 * target. For use with Target::NoRuntime. */
void compile_standalone_runtime(const std::string &object_filename, Target t);

/** Create an object and/or static library file containing the Halide runtime for a given
 * target. For use with Target::NoRuntime. Return an Outputs with just the actual
 * outputs filled in (typically, object_name and/or static_library_name).
 */
Outputs compile_standalone_runtime(const Outputs &output_files, Target t);

typedef std::function<Module(const std::string &, const Target &)> ModuleProducer;

void compile_multitarget(const std::string &fn_name,
                         const Outputs &output_files,
                         const std::vector<Target> &targets,
                         ModuleProducer module_producer,
                         const std::map<std::string, std::string> &suffixes = {});

}

#endif
back to top