-
Notifications
You must be signed in to change notification settings - Fork 64
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support paramterized multiports and banks through generics #349
Comments
I don't understand why you say "this is not possible." The Cpp target invokes constructors at runtime. It just has to be able to evaluate the parameter values while invoking the constructors. |
With "this is not possible" I was referring to the process of resolving and checking parameterized width at compile time. Of course this checking could be done at runtime, but we would lose the possibility to throw compile time errors. Also, I am not sure how well the visualizations would work if the precise width is unknown. The point I try to make is that type parameters are a viable alternative to constructor parameters, as they can be resolved at compile time (both by the LF compiler and by the C++ compiler). |
I guess you mean "it is not possible to check at compile time widths that are specified as command-line parameters at run time." This is correct, of course. I would argue that we should not allow widths to specified via command-line parameters (illustrations below about why this would not be a good idea, just in case we do not agree about that part). If so, the essential problem here is how to prohibit this. One possibility is simply to generate code that rejects command-line updates of any parameter that is used to specify widths. I don't think this would be hard to do. I guess you are proposing using type variables because programmers don't expect to be able to change type variables at runtime, correct? This makes sense, in which case, I guess the only issue is whether using type variables will lose anything in expressivity. There is also the practical question of who will implement this... Here are two arguments for why widths should not be specifiable on the command line: Consider a federated execution specified at the top level as a bank of reactors. The command line program that is generated will have to figure out how many programs to start and on which machines. I guess this would have to done in the generated launcher script? The RTI would also now have to repeat all the logic in the code generator that determines which federates are connected to which. I suspect this means the RTI will need access to the source code or some abstracted version of it. Also, if you can override widths on the command line, then you can make them inconsistent no matter what the code generator and validator have done. E.g., suppose you have a multiport with width w1 feeding two multiports with widths w2 and w3. Currently, the code generator checks that, with the default parameter values given in the source code, w1 = w2 + w3. If each of these parameters can be overridden on the command line, then doesn’t the runtime code have to repeat this check? |
Yes, I think this summarizes it well. While I agree that it would be possible to check whether a parameter is used somewhere in the context of a width specification and to enable/disable command line overrides accordingly, I don't think this would be very intuitive for the programmer. I think type variables are an intriguing alternative as they make the difference obvious. Actually parameterized width specifications directly modify the interface of a Reactor (which we can interpret as its type) and hence I think there is a semantic difference between standard parameters that change the behavior of a reactor and width parameters that change the interface. So far I cannot see any downside in using type parameters instead of reactor parameters for width specifications. But of course it would need to be implemented. There is already rudimentary support for type parameters in C++, so I think it wouldn't be too hard to make it work, but I guess this is more complicated for C. In any case, I don't think this is urgent. I opened the issue as a brain dump to keep track of the thought. |
This is a summary of yesterday's discussion in the LF weekly. The underlying assumption in the discussion above was that we want to validate the widths of connected multiports (and/or banks) at compile time. This is, to check whether the widths of the left-hand side operands match the width of the right-hand side operands of the connection operator (
Both options have the disadvantage that any change in width's requires recompilation, as @lhstrh pointed out. So maybe we should question the compile-time checks. Allowing applications to scale according to a given parameter would be an interesting and valuable property. Instead of verifying multiport connections at compile-time we could move these checks to the runtime. In conclusion of this discussion, I think we might want to deal with this issue differently for different targets. While it likely makes sense to have more static programs that are checked at compile time in the C target (which also targets small micro-controllers), we probably want to have more flexibility for other targets. Considering that the C++ runtime already does many checks at runtime (including dependency analysis of reactions), it would only be consequent to extend the runtime with native support for banks and multiports. |
There is actually another aspect to this problem that only occured to me while working on the C++ code generator today. The C++ generator translates each reactor to a class and each reactor instantiation is translated to an instantiation of this class. Parameters are simply passed to the constructor of this class. This means that the code generated for a reactor needs to be general and work with the whole range of parameters that can be supplied. In essence, all instances of a reactor share the same code and are implemented by the same class. I think the C target generates code for each instance (right?). This means it can generate the connection logic individually for each reactor instance and for the given width parameters. In C++, however, the generated reactor class would need to provide a more general logic, since we don't know in advance which parameters will be passed to the constructor. This means that Edward's suggestion of forbidding command line overrides of width parameters does not work for C++. In fact, parameterized width do not work at all for the C++ code generator without either having runtime logic for drawing connections or making width's class template parameters (which then essentially means that each instance would use a different class). Of course, there is the third option of generating individual classes for each instance, but I would really like to avoid that. |
We definitely want to avoid generating individual classes for each instance. That would be very unfortunate! In the C target, the constructor for a reactor does not construct its contained reactors. Instead, the code generator generates code that constructs all the reactors, sets their parameter values and initial state values, and then connects them together. Presumably, the same thing could be done in C++, at the cost that using the underlying classes independently from the LF code generator would become less convenient. |
The C target currently supports multiports and reactor banks with a variable sized width (provided by a parameter). This is possible, because the C code generator treats parameter as compile time constants. Thus, it can resolve the precise value of any width specification during compile-time. However, this is not possible in the C++ target as parameters are runtime constants. They are initialized when the application starts and may be overwritten by CLI parameters that the generated binary parses.
It occurred to me that generics present a potential solution for the problem as they are always resolved at compile time. We currently have syntax for this:
We could enhance it like this:
Where the types with
<>
would be restricted to eithertype
orwidth
. This would also provide a viable solution for the C target should it allow overwriting parameters via the CLI in the future.The text was updated successfully, but these errors were encountered: