Skip to content

defModule macro to define neural nets without inline C++ #5

@mratsim

Description

@mratsim

Currently we need to inline C++ code due to Nim not being able to generate C++ code with default value or wrap types without default constructors nim-lang/Nim#4687

This leads to the following code

emitTypes:
"""
struct Net: public torch::nn::Module {
torch::nn::Linear fc1{nullptr};
torch::nn::Linear fc2{nullptr};
torch::nn::Linear fc3{nullptr};
};
"""
type Net
{.pure, importcpp.}
= object of Module
fc1: Linear
fc2: Linear
fc3: Linear

with emittypes a workaround nim-lang/Nim#16664

template emitTypes*(typesection: static string): untyped =
## Emit a C/C++ typesection
{.emit: "/*TYPESECTION*/\n" & typesection.}
template emitGlobals*(globals: static string): untyped =
## Emit a C/C++ global variable declaration
{.emit: "/*VARSECTION*/\n" & globals.}
template emitIncludes*(includes: static string): untyped =
## Emit a C/C++ global variable declaration
{.emit: "/*INCLUDESECTION*/\n" & includes.}

Instead it would be more convenient to have a macro defModule (name subject to bikeshedding) with the following syntax:

defModule:
  type Net = object of Module
    fc1: Linear = nil
    fc2: Linear = nil
    fc3: Linear = nil

and generates the proper C++ code (nil mapped to {nullptr}) and rewrite the typesection with the proper {.pure, importcpp.} pragma.

This is similar to nim-lang/RFCs#126, nim-lang/RFCs#252

Implementation details:

  • To interpolate with the proper symbol, use the syntax {.emit:["type something {", NimTypeInterpolated, " field{nullptr};"].}
  • With interpolation we should properly support both C++ types without extracting from their importcpp pragma and Nim types without fiddling with gensym.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions