Skip to content
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

Add parameter tracking and FFun/FVar in SDF3 backend #1123

Merged
merged 1 commit into from
Feb 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions compiler/generator/sdf3/SDF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@ void Actor::addInputSignalName(const string& name)
this->inputSignals.push_back(name);
}

void Actor::addParameter(const std::string& paramName, const std::string& paramVal)
{
this->params[paramName] = paramVal;
}

void Actor::addPort(Port newPort)
{
this->ports.push_back(newPort);
Expand Down Expand Up @@ -145,6 +150,11 @@ vector<string> Actor::getInputSignalNames()
return this->inputSignals;
}

std::map<std::string, std::string> Actor::getParams()
{
return this->params;
}

// replace old signal name with new signal name (order must be retained)
void Actor::replaceInputSignalName(const string& oldName, const string& newName)
{
Expand Down
30 changes: 17 additions & 13 deletions compiler/generator/sdf3/SDF.hh
Original file line number Diff line number Diff line change
Expand Up @@ -48,19 +48,21 @@ class Port {
class Actor {
public:
Actor(const std::string&, const std::string&);
void setName(const std::string&);
void setType(const std::string&);
void addPort(Port);
void removePort(const std::string&);
void setDelayInputSigName(const std::string&);
void setArg(const std::string&, int);
void addInputSignalName(const std::string&);
std::string getName();
std::string getType();
std::vector<Port> getPorts();
std::string getDelayInputSigName();
std::pair<std::string, int> getArg();
std::vector<std::string> getInputSignalNames();
void setName(const std::string&);
void setType(const std::string&);
void addPort(Port);
void removePort(const std::string&);
void setDelayInputSigName(const std::string&);
void setArg(const std::string&, int);
void addInputSignalName(const std::string&);
void addParameter(const std::string& paramName, const std::string& paramVal);
std::string getName();
std::string getType();
std::vector<Port> getPorts();
std::string getDelayInputSigName();
std::pair<std::string, int> getArg();
std::vector<std::string> getInputSignalNames();
std::map<std::string, std::string> getParams();
void replaceInputSignalName(const std::string& oldName, const std::string& newName);
void writeToXML(std::ostream& fout);
void writePropertiesToXML(std::ostream& fout);
Expand All @@ -75,6 +77,8 @@ class Actor {
std::pair<std::string, int> args;
std::vector<std::string> inputSignals; // track list of input signals for rec operator in order
// to bypass it in SDF representation
std::map<std::string, std::string>
params; // track parameters for given actor (i.e. init, min, max)
};

class Channel {
Expand Down
149 changes: 123 additions & 26 deletions compiler/generator/sdf3/signal2SDF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "Text.hh"
#include "global.hh"
#include "ppsig.hh"
#include "prim2.hh"
#include "property.hh"
#include "signalVisitor.hh"
#include "signals.hh"
Expand Down Expand Up @@ -102,6 +103,36 @@ void Signal2SDF::sigToSDF(Tree L, ostream& fout)
}
}
}
// update names of UI actors to reflect their parameters
for (auto& b : uiActors) {
string newName = actorList.at(b).getName();
for (auto& [paramName, value] : actorList.at(b).getParams()) {
newName += "PARAM" + paramName + value;
}
actorList.at(b).setName(newName);
for (auto& c : chList) { // update actor name in channel list
if (c.second.getSrcActor() == b) {
chList.at(c.first).setSrcActor(newName);
} else if (c.second.getDstActor() == b) {
chList.at(c.first).setDstActor(newName);
}
}
}
// update names of delay actors to reflect their parameters
for (auto& b : delayActors) {
string newName = actorList.at(b).getName();
for (auto& [paramName, value] : actorList.at(b).getParams()) {
newName += "PARAM" + paramName + value;
}
actorList.at(b).setName(newName);
for (auto& c : chList) { // update actor name in channel list
if (c.second.getSrcActor() == b) {
chList.at(c.first).setSrcActor(newName);
} else if (c.second.getDstActor() == b) {
chList.at(c.first).setDstActor(newName);
}
}
}
// Write graph information (actor/channel names, ports)
for (auto& a : actorList) {
// add self loops
Expand Down Expand Up @@ -203,7 +234,7 @@ void Signal2SDF::visit(Tree sig)
self(x);
return;
} else if (isSigDelay(sig, x, y)) {
logActor(sig, "delay");
logDelayActor(sig, x, y, "delay");
self(x);
self(y);
return;
Expand All @@ -221,12 +252,14 @@ void Signal2SDF::visit(Tree sig)

// Foreign functions
else if (isSigFFun(sig, ff, largs)) {
logActor(sig, ffname(ff));
mapself(largs);
return;
} else if (isSigFConst(sig, type, name, file)) {
logActor(sig, tree2str(name));
return;
} else if (isSigFVar(sig, type, name, file)) {
logActor(sig, "fvar");
return;
}

Expand Down Expand Up @@ -323,24 +356,24 @@ void Signal2SDF::visit(Tree sig)
logActor(sig, "checkbox");
return;
} else if (isSigVSlider(sig, label, c, x, y, z)) {
logActor(sig, "vslider");
logUISliderActor(sig, "vslider", c, x, y, z);
// self(c), self(x), self(y), self(z);
return;
} else if (isSigHSlider(sig, label, c, x, y, z)) {
logActor(sig, "hslider");
logUISliderActor(sig, "hslider", c, x, y, z);
// self(c), self(x), self(y), self(z);
return;
} else if (isSigNumEntry(sig, label, c, x, y, z)) {
logActor(sig, "nentry");
self(c), self(x), self(y), self(z);
logUISliderActor(sig, "nentry", c, x, y, z);
// self(c), self(x), self(y), self(z);
return;
} else if (isSigVBargraph(sig, label, x, y, z)) {
logActor(sig, "vbargraph");
self(x), self(y), self(z);
logUIGraphActor(sig, "vbargraph", x, y, z);
// self(x), self(y), self(z);
return;
} else if (isSigHBargraph(sig, label, x, y, z)) {
logActor(sig, "hbargraph");
self(x), self(y), self(z);
logUIGraphActor(sig, "hbargraph", x, y, z);
// self(x), self(y), self(z);
return;
}

Expand All @@ -364,9 +397,11 @@ void Signal2SDF::visit(Tree sig)
self(x), self(y);
return;
} else if (isSigEnable(sig, x, y)) {
logActor(sig, "enable");
self(x), self(y);
return;
} else if (isSigControl(sig, x, y)) {
logActor(sig, "control");
self(x), self(y);
return;
}
Expand Down Expand Up @@ -449,7 +484,6 @@ void Signal2SDF::bypassRec(const string& recActorName, vector<string>& inputSign
chList.at(channelToMod)
.setSrcActor(
inputSignalNames[i]); // connect output channel of REC to one of its input actors
chList.at(channelToMod).setInitialTokens(1);
}
}

Expand Down Expand Up @@ -564,28 +598,22 @@ void Signal2SDF::logActor(Tree sig, const string& type)
}

/**
* Add the actor associated with sig to the actor list
* Add the delay actor associated with sig to the actor list and track range of delay values
*/
void Signal2SDF::logDelayActor(Tree sig, Tree x, Tree y, const string& type)
{
stringstream actorName;
stringstream arg1Name;
stringstream arg2Name;
int i;
actorName << sig;
arg1Name << x;
arg2Name << y;
actorList.insert(pair<string, Actor>(actorName.str(), Actor(actorName.str(), type)));
// NOTE assume here that fixed delays will only have Int argument, might need to expand to
// include Real values
if (isSigInt(y, &i)) { // fixed delay: track delay length to model later
delayActors.push_back(actorName.str());
actorList.at(actorName.str()).setDelayInputSigName(arg1Name.str());
actorList.at(actorName.str()).setArg(arg2Name.str(), i);
} else { // variable delay: leave alone; will resolve later
actorList.at(actorName.str()).addInputSignalName(arg1Name.str());
actorList.at(actorName.str()).addInputSignalName(arg2Name.str());
}
delayActors.push_back(actorName.str());

// delay sizes need to be integer values rather than floats/doubles
interval delayRange = getCertifiedSigType(y)->getInterval();
std::string min = std::to_string((int)delayRange.lo());
std::string max = std::to_string((int)delayRange.hi());
actorList.at(actorName.str()).addParameter("min", min);
actorList.at(actorName.str()).addParameter("max", max);

addChannel(sig);
}

Expand Down Expand Up @@ -644,6 +672,75 @@ void Signal2SDF::logUIActor(Tree sig, Tree init)
}
}

/**
* Log UI component with information of its init, min, max, and step values
*/
void Signal2SDF::logUISliderActor(Tree sig, const std::string& type, Tree init, Tree min, Tree max,
Tree step)
{
std::map<std::string, Tree> parameters = {
{"init", init}, {"min", min}, {"max", max}, {"step", step}};
stringstream actorName; // get unique actor names from signal
actorName << sig;
actorList.insert(pair<string, Actor>(actorName.str(), Actor(actorName.str(), type)));
uiActors.push_back(actorName.str());

for (auto const& [name, val] : parameters) {
int i;
double r;
stringstream paramVal;

if (isSigInt(val, &i)) {
paramVal << i;
} else if (isSigReal(val, &r)) {
paramVal << r;
} else {
stringstream error;
error << __FILE__ << ":" << __LINE__ << " ERROR : " << name
<< " value for UI component not found : " << *sig << endl;
throw faustexception(error.str());
}
actorList.at(actorName.str()).addParameter(name, paramVal.str());
}

addChannel(sig);
}

/**
* Log UI graph (vbar/hbargraph) component with information of its min, max, and t0 values
*/
void Signal2SDF::logUIGraphActor(Tree sig, const std::string& type, Tree min, Tree max, Tree t0)
{
std::map<std::string, Tree> parameters = {
{"min", min}, {"max", max}
// {"tzero", t0} // NOTE excluded bargraph as it doesn't seem to relate to parameters
};
stringstream actorName; // get unique actor names from signal
actorName << sig;
actorList.insert(pair<string, Actor>(actorName.str(), Actor(actorName.str(), type)));
uiActors.push_back(actorName.str());

for (auto const& [name, val] : parameters) {
int i;
double r;
stringstream paramVal;

if (isSigInt(val, &i)) {
paramVal << i;
} else if (isSigReal(val, &r)) {
paramVal << r;
} else {
stringstream error;
error << __FILE__ << ":" << __LINE__ << " ERROR : " << name
<< " value for UI component not found : " << *sig << endl;
throw faustexception(error.str());
}
actorList.at(actorName.str()).addParameter(name, paramVal.str());
}

addChannel(sig);
}

/**
* Add the power actor associated with sig to the actor list
* and track the orger of execution - note that it denotes y^x
Expand Down
4 changes: 4 additions & 0 deletions compiler/generator/sdf3/signal2SDF.hh
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class Signal2SDF : public TreeTraversal {
std::vector<std::string> delayActors;
std::vector<std::string> recActors;
std::vector<std::string> inputArgTrackedActors;
std::vector<std::string> uiActors;

void visit(Tree t) override;

Expand All @@ -67,6 +68,9 @@ class Signal2SDF : public TreeTraversal {
void logRecActor(Tree sig, Tree le, const std::string& type);
void logBinopActor(Tree sig, Tree x, Tree y, const std::string& type);
void logUIActor(Tree sig, Tree init);
void logUISliderActor(Tree sig, const std::string& type, Tree init, Tree min, Tree max,
Tree step);
void logUIGraphActor(Tree sig, const std::string& type, Tree min, Tree max, Tree t0);
void logPowActor(Tree sig, Tree x, Tree y, const std::string& type);
void logCastActor(Tree sig, Tree x, const std::string& type);
bool isSigPow(Tree sig, int* i, Tree& x, Tree& y);
Expand Down