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

5) rust: use borrow in compute interface #1087

Open
wants to merge 12 commits into
base: master-dev
Choose a base branch
from
31 changes: 24 additions & 7 deletions compiler/generator/instructions_compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -578,7 +578,15 @@ void InstructionsCompiler::compileMultiSignal(Tree L)
string name;
if (gGlobal->gOutputLang == "rust") {
name = subst("*output$0", T(index));
pushComputeDSPMethod(IB::genStoreStackVar(name, res));
if (gGlobal->gComputeMix) {
// take the cpp code and remove the the loop
ValueInst* res1 = IB::genAdd(res, IB::genLoadStackVar(name));
pushComputeDSPMethod(IB::genStoreStackVar(name, res1));
} else {
pushComputeDSPMethod(IB::genStoreStackVar(name, res));
}


} else if (gGlobal->gOutputLang == "jax") {
res = CS(sig);
string result_var = "_result" + to_string(index);
Expand Down Expand Up @@ -1130,9 +1138,14 @@ ValueInst* InstructionsCompiler::generateVariableStore(Tree sig, ValueInst* exp)
return IB::genLoadStructVar(vname);
}
} else {
// "Slow" variables are declared as locals in 'frame' or 'compute' functions
pushComputeBlockMethod(IB::genDecStackVar(vname, ctype, exp));
return IB::genLoadStackVar(vname);
if (gGlobal->gOneSample) {
pushControlDeclare(IB::genDecStackVar(vname, ctype, exp));
return IB::genLoadStackVar(vname);
} else {
// "Slow" variables are declared as locals in 'frame' or 'compute' functions
pushComputeBlockMethod(IB::genDecStackVar(vname, ctype, exp));
return IB::genLoadStackVar(vname);
}
}
}

Expand Down Expand Up @@ -1170,9 +1183,13 @@ ValueInst* InstructionsCompiler::generateVariableStore(Tree sig, ValueInst* exp)
getConditionCode(sig), IB::genStoreStructVar(vname_perm, exp)));
return IB::genLoadStructVar(vname_perm);
} else {
// copy the object variable to the local one
pushComputeBlockMethod(
IB::genDecStackVar(vname, ctype, IB::genLoadStructVar(vname_perm)));
if (gGlobal->gOneSample) {
pushControlDeclare(IB::genDecStackVar(vname, ctype, IB::genLoadStructVar(vname_perm)));
} else {
// copy the object variable to the local one
pushComputeBlockMethod(
IB::genDecStackVar(vname, ctype, IB::genLoadStructVar(vname_perm)));
}
// execute the code
pushComputeDSPMethod(IB::genControlInst(getConditionCode(sig),
IB::genStoreStackVar(vname, exp)));
Expand Down
106 changes: 77 additions & 29 deletions compiler/generator/rust/rust_code_container.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,8 @@ void RustCodeContainer::produceClass()

tab(n, *fOut);
*fOut << "use std::convert::TryInto;";
tab(n, *fOut);
*fOut << "use std::borrow;";

// Generate gub containers
generateSubContainers();
Expand Down Expand Up @@ -511,14 +513,30 @@ void RustCodeContainer::produceClass()
// Parameter getter/setter
produceParameterGetterSetter(n + 1, parameterLookup);

// Control
if (gGlobal->gExtControl) {
tab(n + 1, *fOut);
tab(n + 1, *fOut);
*fOut << "pub fn control(&mut self) {";
tab(n + 2, *fOut);
generateControlDeclarations(&fCodeProducer);
back(1, *fOut);
*fOut << "}";
}

// Compute
generateCompute(n + 1);
generateComputeInterface(n + 1);
if (gGlobal->gOneSample) {
generateComputeFrame(n + 1);
} else {
generateCompute(n + 1);
}

tab(n, *fOut);
*fOut << "}" << endl;
tab(n, *fOut);
produceFaustDspBlob();
if (!gGlobal->gRustNoTraitSwitch) {
produceFaustDspBlob();
}
}

void RustCodeContainer::produceMetadata(int n)
Expand Down Expand Up @@ -611,39 +629,68 @@ void RustCodeContainer::generateComputeHeader(int n, std::ostream* fOut, int fNu
// Compute "compute" declaration
tab(n, *fOut);
tab(n, *fOut);
*fOut << "pub fn compute_arrays("
<< "&mut self, " << fFullCount << ": usize, inputs: &[&[FaustFloat] ; " << fNumInputs
<< "]"
<< ", outputs: &mut [&mut [FaustFloat] ; " << fNumOutputs << "]) {";
*fOut << "pub fn compute<InType, OutType>(";
tab(n + 1, *fOut);
}

void RustCodeContainer::generateComputeInterfaceHeader(int n, std::ostream* fOut, int fNumInputs,
int fNumOutputs)
{
// Compute "compute" declaration
*fOut << "pub fn compute("
<< "&mut self, " << fFullCount << ": usize, inputs: & [& [FaustFloat] ]"
<< ", outputs: & mut[& mut[FaustFloat] ]) {";
*fOut << "&mut self,";
tab(n + 1, *fOut);
*fOut << "count: usize,";
tab(n + 1, *fOut);
*fOut << "inputs: impl borrow::Borrow<[InType]>,";
tab(n + 1, *fOut);
*fOut << "mut outputs: impl borrow::BorrowMut<[OutType]>,";
tab(n, *fOut);
*fOut << ") where";
tab(n + 1, *fOut);
*fOut << "InType: borrow::Borrow<[FaustFloat]>,";
tab(n + 1, *fOut);
*fOut << "OutType: borrow::BorrowMut<[FaustFloat]>,";
tab(n, *fOut);
*fOut << "{";
tab(n + 1, *fOut);
}

void RustCodeContainer::generateComputeInterface(int n)
void RustCodeContainer::generateComputeFrame(int n)
{
// Generates declaration
tab(n, *fOut);
tab(n, *fOut);
generateComputeInterfaceHeader(n, fOut, fNumInputs, fNumOutputs);
*fOut << "pub fn compute_frame(&mut self, inputs: &[&FaustFloat], ";
*fOut << "outputs: &mut [&mut FaustFloat]) {";

*fOut << "let input_array = inputs.split_at(" << fNumInputs
<< ").0.try_into().expect(\"too few input buffers\");";
tab(n + 1, *fOut);
*fOut << "let output_array = outputs.split_at_mut(" << fNumOutputs
<< ").0.try_into().expect(\"too few output buffers\");";
tab(n + 1, *fOut);
*fOut << "self.compute_arrays(count, input_array, output_array);";
for(int i = 0; i < fNumInputs; i++){
tab(n+1, *fOut);
*fOut << "let input"<< i <<" = inputs["<< i <<"];";
};

for(int i = 0; i < fNumOutputs; i++){
tab(n+1, *fOut);
*fOut << "let (nextoutput, outputs): (&mut [&mut f64], &mut [&mut f64]) = outputs.split_at_mut(1);";
tab(n+1, *fOut);
*fOut << "let output"<< i <<": &mut FaustFloat = nextoutput[0];";
};

fCodeProducer.Tab(n + 1);

if (!gGlobal->gExtControl) {
generateControlDeclarations(&fCodeProducer);
} else {
}

tab(n+1, *fOut);
*fOut << "//generateOneSample";
tab(n+1, *fOut);
// Generates one sample computation
BlockInst* block = fCurLoop->generateOneSample();
block->accept(&fCodeProducer);

/*
// TODO : atomic switch
// Currently for soundfile management
// also for temp vars
*/
generatePostComputeBlock(&fCodeProducer);
tab(n, *fOut);
*fOut << "}";
tab(n, *fOut);
*fOut << "}" << endl;
}

// Scalar
Expand All @@ -663,7 +710,7 @@ void RustScalarCodeContainer::generateCompute(int n)
tab(n + 1, *fOut);
fCodeProducer.Tab(n + 1);

// Generates local variables declaration and setup

generateComputeBlock(&fCodeProducer);

// Generates one single scalar loop
Expand All @@ -678,9 +725,10 @@ void RustScalarCodeContainer::generateCompute(int n)
loop->accept(&fCodeProducer);

// Currently for soundfile management
// and for temp vars
generatePostComputeBlock(&fCodeProducer);

back(1, *fOut);
tab(n, *fOut);
*fOut << "}" << endl;
}

Expand Down
3 changes: 1 addition & 2 deletions compiler/generator/rust/rust_code_container.hh
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,7 @@ class RustCodeContainer : public virtual CodeContainer {

virtual void produceClass();
void generateComputeHeader(int n, std::ostream* fOut, int fNumInputs, int fNumOutputs);
void generateComputeInterfaceHeader(int n, std::ostream* fOut, int fNumInputs, int fNumOutputs);
void generateComputeInterface(int tab);
void generateComputeFrame(int tab);
virtual void generateCompute(int tab) = 0;
void produceInternal();
void produceFaustDspBlob();
Expand Down
28 changes: 15 additions & 13 deletions compiler/generator/rust/rust_instructions.hh
Original file line number Diff line number Diff line change
Expand Up @@ -225,13 +225,9 @@ class RustInstVisitor : public TextInstVisitor {
virtual void visit(DeclareBufferIterators* inst)
{
/* Generates an expression like:
let (outputs0, outputs1) = if let [outputs0, outputs1, ..] = outputs {
let outputs0 = outputs0[..count as usize].iter_mut();
let outputs1 = outputs1[..count as usize].iter_mut();
(outputs0, outputs1)
} else {
panic!("wrong number of outputs");
};
let [outputs0, outputs1] = outputs.borrow_mut();
let outputs0 = outputs0.borrow_mut[..count].iter_mut();
let outputs1 = outputs1.borrow_mut[..count].iter_mut();
*/

// Don't generate if no channels
Expand All @@ -245,24 +241,30 @@ class RustInstVisitor : public TextInstVisitor {
for (int i = 0; i < inst->fChannels; ++i) {
*fOut << name << i << ", ";
}
*fOut << "] = " << name << ";";
*fOut << "] = " << name;
if (inst->fMutable) {
*fOut << ".borrow_mut() else { panic!(\"wrong number of outputs\"); };";
} else {
*fOut << ".borrow() else { panic!(\"wrong number of inputs\"); };";
}

// Build fixed size iterator variables

for (int i = 0; i < inst->fChannels; ++i) {
tab(fTab, *fOut);
*fOut << "let " << name << i << " = " << name << i << "[..count as usize]";
*fOut << "let " << name << i << " = " << name << i;
;
if (inst->fMutable) {
if (inst->fChunk) {
*fOut << ".chunks_mut(vsize as usize);";
*fOut << ".borrow_mut()[..count].chunks_mut(vsize as usize);";
} else {
*fOut << ".iter_mut();";
*fOut << ".borrow_mut()[..count].iter_mut();";
}
} else {
if (inst->fChunk) {
*fOut << ".chunks(vsize as usize);";
*fOut << ".borrow()[..count].chunks(vsize as usize);";
} else {
*fOut << ".iter();";
*fOut << ".borrow()[..count].iter();";
}
}
}
Expand Down
20 changes: 15 additions & 5 deletions compiler/global.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,9 @@ void global::reset()
gGroupTaskSwitch = false;
gFunTaskSwitch = false;

gUIMacroSwitch = false;
gUIMacroSwitch = false;
gRustNoTraitSwitch = false;

gDumpNorm = -1;
gFTZMode = 0;
gRangeUI = false;
Expand Down Expand Up @@ -1371,6 +1373,10 @@ bool global::processCmdline(int argc, const char* argv[])
gUIMacroSwitch = true;
i += 1;

} else if (isCmd(argv[i], "-rnt", "--rust-no-faustdsp-trait")) {
gRustNoTraitSwitch = true;
i += 1;

} else if (isCmd(argv[i], "-t", "--timeout") && (i + 1 < argc)) {
gTimeout = std::atoi(argv[i + 1]);
i += 2;
Expand Down Expand Up @@ -1672,15 +1678,15 @@ bool global::processCmdline(int argc, const char* argv[])
}
#endif
if (gOneSample && gOutputLang != "cpp" && gOutputLang != "c" && gOutputLang != "dlang" &&
!startWith(gOutputLang, "cmajor") && gOutputLang != "fir") {
!startWith(gOutputLang, "cmajor") && gOutputLang != "fir" && gOutputLang != "rust") {
throw faustexception(
"ERROR : '-os' option can only be used with 'cpp', 'c', 'fir' or 'cmajor' "
"ERROR : '-os' option can only be used with 'cpp', 'c', 'dlang', 'cmajor', 'fir' or 'rust'"
"backends\n");
}

if (gExtControl && gOutputLang != "cpp" && gOutputLang != "c" && gOutputLang != "cmajor") {
if (gExtControl && gOutputLang != "cpp" && gOutputLang != "c" && gOutputLang != "cmajor" && gOutputLang != "rust") {
throw faustexception(
"ERROR : '-ec' option can only be used with 'cpp', 'c' or 'cmajor' "
"ERROR : '-ec' option can only be used with 'cpp', 'c', 'cmajor' or 'rust' "
"backends\n");
}

Expand Down Expand Up @@ -2114,6 +2120,10 @@ string global::printHelp()
<< "-uim --user-interface-macros add user interface macro definitions to the "
"output code."
<< endl;
sstr << tab
<< "-rnt --rust-no-faustdsp-trait (Rust only) Don't generate FaustDsp trait"
"implmentation."
<< endl;
sstr << tab << "-xml generate an XML description file."
<< endl;
sstr << tab << "-json generate a JSON description file."
Expand Down
1 change: 1 addition & 0 deletions compiler/global.hh
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ struct global {
bool gPrintFileListSwitch; // -flist option
bool gInlineArchSwitch; // -i option
bool gUIMacroSwitch; // -uim option
bool gRustNoTraitSwitch; // -rnt option
int gDumpNorm; // -norm option
bool gMathExceptions; // -me option, whether to check math functions domains
bool gLocalCausalityCheck; // -lcc option, when true trigs local causality errors (negative
Expand Down
Loading
Loading