Skip to content

Commit

Permalink
Add parameter tracking and FFun/FVar in SDF3 backend
Browse files Browse the repository at this point in the history
  • Loading branch information
jkmingwen committed Feb 20, 2025
1 parent 2044ce8 commit 2f9b23c
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 39 deletions.
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

0 comments on commit 2f9b23c

Please sign in to comment.