MPU Libraries
The Midas Processing Unit (MPU) is an infrastructure for developing Midas processing libraries with multiple software/hardware implementations. A common public interface is defined to simplify testing, validation, and performance comparisons. Wrappers are auto-generated for code sharing between various Midas and non-Midas frameworks.
The MPU Library class can be found in nxm.sys.lib.MPULib.java
There is an example option tree available for download here File:Demo.zip. For instruction on setting up the option tree, please refer here, Setting up an option tree.
Contents |
Category Contents
Naming Conventions
Library names should adhere to the following naming conventions:
Foo.java - the java reference implementation of the function Foo FooNative.c - the native C implementation of Foo FooGPU.c - the GPU native C implementation of Foo FooVerilog.c - the verilator C simulator implementation of Foo FooICE.c - the ICE FPGA implementation of Foo
The Java reference implementation should put readability above performance. The native and hardware implementations should stress performance. The NeXtMidas wrappers to the Native functions are of the form FooNative.java, FooGPU.java, FooVerilog.java, etc.
Format
The MPULib in nxm.sys.lib provides the standard framework for developing a suite of functions in different programming languages. The wrapper for each different implementation of the your function must extend the MPULib class. This allows the /MPU=x switch to select the desired implementation of the library function without altering the primitive.
There is an example for each library language on their respective pages: MPU Java, MPU Native, MPU GPU, MPU Verilator, MPU ICE
Primitive
It is recommended that you write a primitive that uses this class. The syntax to initialize an MPULib object looks as follows:
MPULib foo = MPULib.forName("Foo",MA);
The /MPU=x switch is parsed in the forName() method to select the implementation. The switch argument must match the first letters of one of the implementations or an exception will be thrown.
Here is how you would write a sample primitive:
fooprim.java
package nxm.demo.prim;
/* import some important classes */
import nxm.sys.lib.Data;
import nxm.sys.lib.DataFile;
import nxm.sys.lib.MPULib;
import nxm.sys.lib.Primitive;
/** Example primitive
This primitive shows how you would call an MPULib object.
It takes an input file and creates an output file that
is scaled my the argument 'MULT'. Here are the 4 arguments
-IN - Input file of type integer
-OUT - Output file name
-MULT - constant to scale input by
-STR - a meaningless string for demonstration
*/
public class fooprim extends Primitive {
DataFile fileIn, fileOut; // our files
Data dbi, dbo; // our data objects
MPULib fooObj; // our MPULib object
/** The open function - in here we open files and initialize our variables */
public int open () {
/* init our object */
fooObj = MPULib.forName("Foo", MA);
/* get the multiplier */
int mult = MA.getL("MULT", 2);
String str = MA.getS("STR", "blank");
/* get the input file */
fileIn = MA.getDataFile("IN");
fileIn.open();
/* get the output file */
fileOut = MA.getDataFile("OUT", fileIn, 0);
fileOut.open();
/* set the keys */
fooObj.set("FORMAT", fileIn.getFormat());
fooObj.set("MULTKEY", mult);
fooObj.set("STRKEY", str);
/* open the object */
fooObj.open();
/* setup the data buffers */
dbi = fileIn.getDataBuffer(xfer);
dbo = fileOut.getDataBuffer(xfer);
return NORMAL;
}
/** The process function - here is where we do the leg work */
public int process () {
int stat = NORMAL;
int n1 = fileIn.read(dbi);
if (n1<0) // EOF
stat = FINISH;
else if (n1 == xfer) {
fooObj.process(dbi.getBuf(), dbi.getSize(), dbo.getBuf(), dbo.getSize());
fileOut.write(dbo, n1);
}
else // incomplete packet, disregard
stat = FINISH;
return stat;
}
/** The close function - here is where we free our resources */
public int close () {
fooObj.close ();
fileIn.close ();
fileOut.close ();
return FINISH;
}
}
Example Calls
Some sample calls for the foo primitive would look as follows:
Java
nM> fooprim/mpu=java <arg> <arg> <arg>
Native
nM> fooprim/mpu=native <arg> <arg> <arg>
nM> fooprim/mpu=n <arg> <arg> <arg>
Ice
nM> fooprim/mpu=ice <arg> <arg> <arg>