zeam-vm / pelemay_backend

PelemayBackend: A memory-saving, fault-tolerant and distributed collection of Nx compilers and backends for embedded systems.
Apache License 2.0
25 stars 0 forks source link

Logging backend with aspect-oriented programming #25

Open zacky1972 opened 1 year ago

zacky1972 commented 1 year ago

Implement LoggingBackend to investigate behavior of Nx backends.

In general, it is maintainable to implement logging for some component, using aspect-oriented programming (AOP), which solves issues about cross-cutting concern, including logging, sophisticatedly.

Moreover, AOP is useful not only for logging, but also for other use case. So, we'll implement the join point model of AOP for Nx backends, which is named DecoratingBackend.

Implement DecoratingBackend to be able to specify a set of the functions in Nx.Backend with the AspectJ manner and with grouping written in hexdocs of Nx, for example, Aggregates, Backend, Conversion, ...

The working branch is feature/25.

zacky1972 commented 1 year ago

Rename DecoratingBackend into BackendDecorator because it will be implemented as an AOP-based generator of a Behaviour as a backend.

BackendDecorator should be categorized in utilities instead of in backends.

zacky1972 commented 1 year ago

The conceptual code of LoggingBackend is:

defmodule LoggingBackend do
  require Logger
  use BackendDecorator
  @behaviour Nx.Backend

  def_hook(:all, base_backend) do
    Logger.debug("Enter #{base_backend}.#{function} with args #{inspect args}")
    invoke(base_backend, function, args)
    Logger.debug("Exit #{base_backend}.#{function}")
  end
endmodule
zacky1972 commented 1 year ago

@fhunleth commented:

I am wondering if this might be interesting at run time and integrate well with Erlang's tracing. I have only used Erlang's tracing to match on functions. I think that's all they can do. I use recon_trace for this. I wonder if it would be useful to specify a match to log the function calls from one place to another like you can with AOP. For example, specify the function that gets a message and specify a function that's really deep in the code. Then tell it to log the functions in between so you can see how an input is transformed into an action really deep in the code. This doesn't sound like what you are trying to achieve, but I am curious if Erlang's runtime tracing feature can help out on this.

polvalente commented 1 year ago

The concept seems really useful! Especially for finding bugs during development of some functionality in a given backend