Giter Club home page Giter Club logo

Comments (5)

wsmoses avatar wsmoses commented on May 28, 2024

The problem is that for an arbitrary global we will likely have to be conservative and assume it is active (unless we prove it’s used otherwise in that function). If it is active, we need shadow memory for that global — which is presently done by looking up the annotation. So the two ways to resolve are to either prove that the global doesn’t impact derivatives or some other way to get the shadow

from enzyme.

wsmoses avatar wsmoses commented on May 28, 2024

We could have a mode where you specify the mapping from active global to shadow and snything else is considered inactive

from enzyme.

timkaler avatar timkaler commented on May 28, 2024

I updated my original comment with a few cases/thoughts. I feel like we need to handle at least (a) and (b) in order to work with reasonably complex programs, and ideally we'd have a catch-all scheme that is able to, perhaps inefficiently and with specially defined behavior, handle the general case.

This is just brainstorming at the moment. Why can't we find all the globals in the program and then pass them through to different functions as arguments. We probably wouldn't actually do it that way, but what goes wrong?

from enzyme.

wsmoses avatar wsmoses commented on May 28, 2024

I agree a and b could be handled by inter procedural active analysis, though you do need more information — namely knowledge whether the global is something you care about as being active.

I.e I might want the output of a function with respect to a global. We might be able to make assumptions that you only care about a set of global specified to resolve.

Also analysis I don’t think is sufficient for indirect calls wherein you don’t know how they touch global a priori.

This doesn’t mean we shouldn’t special case allow that, but something to be cognizant of.

As a truly general case passing in all global won’t work with indirect functions or functions in other translation units since you won’t be able to determine the globals used in advanced

from enzyme.

timkaler avatar timkaler commented on May 28, 2024

As a truly general case passing in all global won’t work with indirect functions or functions in other translation units since you won’t be able to determine the globals used in advanced

Indirect calls are a difficult case that I think we will want to consider out of scope, for now at least. Already, I think we have made compromises that have made indirect function calls incorrect. Disallowing indirect function calls seems to be a reasonable and clearly-defined way of restricting enzyme's scope. Similarly for functions in other translation units, although I think that case is easier to handle/work-around.

Continuing the brainstorming...

For (c) (statically allocated array of floats) I think the challenge here is initialization of the shadow data. We could disallow using global variables to provide "input gradients" to a top level enzyme_autodiff call. Then, I think it would be correct to zero-initialize the shadow data at the start of the top-level call.

For (d) things are more challenging. Let's consider a simpler case that's similar to (c). Instead of a statically allocated array of floats, we have a statically allocated pointer that points to a dynamically allocated array of floats. In this case, the actual dynamic allocation may be performed outside of the enzyme_autodiff call. It's unclear how one figures out how to allocate the data pointed-to by the shadow pointer.

As a side question, consider this case:

stdlike::map<int, float>* v = new stdlike::map();
stdlike::map<int, float>* d_v = new stdlike::map();

__enzyme_autodiff(foo, v, d_v, ...);

If the implementation stdlike::map is deterministic --- i.e. the internal structure is deterministic modulo memory addresses --- then I think things are fine. Suppose the maps use randomization, e.g. to maintain balance of a tree. If the maps are empty initially and in an identical starting state, then I think we are still fine (but require a careful argument) because we are going to record the random bits used for modifying v and use the same random bits to modify d_v. If the maps use randomization, and are not empty, then I think we need to require that they are in the same internal state.

A category of realistic codes that some of these examples are motivated by are those that use global data structures for handling memory allocation. These codes may need to be considered out-of-scope for now, but I'd prefer to hammer-down the precise, ideally minimal, set of excluded uses we require.

from enzyme.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.