jcuda cuModuleLoad() cannot load file using the path of getClass().getResource().getPath() - jcuda

I am trying to use cuModuleLoad() in JCuda to load a vectorAdd.ptx file from /src/main/resources. The code is as follows:
cuModuleLoad(module, getClass.getResource("vectorAdd.ptx").getPath())
But the cuModuleLoad() doesn't pick up this file. It only works when I pass in the absolute path of the ptx file. But I would like to have the ptx file shipped with compile jar files. Is there any way to accomplish this?

The cuModuleLoad function in JCuda is a direct mapping to the corresponding cuModuleLoad function in CUDA. It expects a file name as the second argument.
The problem is: cuModuleLoad can not load the PTX file, because the PTX file simply does not exist for CUDA! The PTX file is hidden inside the JAR file.
When you obtain a resource from a JAR file using someClass.getResource(), then it will point to the resource in the JAR file. When you do something like
System.out.println(getClass().getResource("vectorAdd.ptx").getPath());
and run this (as a JAR file), then you will see an output like this:
file:/U:/YourWorkspace/YourJarFile.jar!/vectorAdd.ptx
Note the .jar! part: This path is not a path to a real file, but only a path to a resource in the JAR.
In order to load the PTX file from a JAR, you have to read the PTX file from the JAR into a byte[] array on Java side, and then pass it to the cuModuleLoadData function of JCuda (which corresponds to the cuModuleLoadData function of CUDA).
Here is an example that loads the PTX data from a JAR file into a byte array, representing the zero-terminated string that can be passed to cuModuleLoadData:
import static jcuda.driver.JCudaDriver.cuCtxCreate;
import static jcuda.driver.JCudaDriver.cuDeviceGet;
import static jcuda.driver.JCudaDriver.cuInit;
import static jcuda.driver.JCudaDriver.cuModuleGetFunction;
import static jcuda.driver.JCudaDriver.cuModuleLoadData;
import static jcuda.runtime.JCuda.cudaDeviceReset;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import jcuda.driver.CUcontext;
import jcuda.driver.CUdevice;
import jcuda.driver.CUfunction;
import jcuda.driver.CUmodule;
import jcuda.driver.JCudaDriver;
public class JCudaPtxInJar
{
public static void main(String args[]) throws IOException
{
// Initialization
JCudaDriver.setExceptionsEnabled(true);
cuInit(0);
CUdevice device = new CUdevice();
cuDeviceGet(device, 0);
CUcontext context = new CUcontext();
cuCtxCreate(context, 0, device);
// Read the PTX data into a zero-terminated string byte array
byte ptxData[] = toZeroTerminatedStringByteArray(
JCudaPtxInJar.class.getResourceAsStream(
"JCudaVectorAddKernel.ptx"));
// Load the module data
CUmodule module = new CUmodule();
cuModuleLoadData(module, ptxData);
// Obtain a function pointer to the "add" function
// and print a simple test/debug message
CUfunction function = new CUfunction();
cuModuleGetFunction(function, module, "add");
System.out.println("Got function "+function);
cudaDeviceReset();
}
/**
* Read the contents of the given input stream, and return it
* as a byte array containing the ZERO-TERMINATED string data
* from the stream. The caller is responsible for closing the
* given stream.
*
* #param inputStream The input stream
* #return The ZERO-TERMINATED string byte array
* #throws IOException If an IO error occurs
*/
private static byte[] toZeroTerminatedStringByteArray(
InputStream inputStream) throws IOException
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte buffer[] = new byte[8192];
while (true)
{
int read = inputStream.read(buffer);
if (read == -1)
{
break;
}
baos.write(buffer, 0, read);
}
baos.write(0);
return baos.toByteArray();
}
}
Compiling this and packing it into a JAR (together with the /resources/JCudaVectorAddKernel.ptx PTX file, of course) will allow you to start the program and obtain the example function from the PTX in the JAR.

Related

How to use ASM Opcodes.ACC_SYNTHETIC

I am testing ACC_SYNTHETIC on a method by using ASM. The follows is my code
public static void generateMethodBean() throws IOException {
System.out.println("11111");
ClassWriter cw = new ClassWriter(0);
cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, "cn/curious/asm/Bean", null, "java/lang/Object", null);
MethodVisitor m0Visitor = cw.visitMethod(Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC | Opcodes.ACC_SYNTHETIC, "lambda$main$1", "()V", null, null);
m0Visitor.visitCode();
m0Visitor.visitInsn(Opcodes.RETURN);
m0Visitor.visitMaxs(0, 0);
m0Visitor.visitEnd();
cw.visitEnd();
byte[] buffer = cw.toByteArray();
// StringWriter stringWriter = new StringWriter();
// PrintWriter printWriter = new PrintWriter(stringWriter);
// CheckClassAdapter.verify(new ClassReader(buffer), true, printWriter);
// System.out.println(printWriter.toString());
File file = new File(FILE_PATH_PREFIX + File.separator + "Bean2.class");
FileUtils.writeByteArrayToFile(file, buffer);
}
But the result class file has nothing.
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package cn.curious.asm;
public class Bean {
}
I feel confusion about ACC_SYNTHETIC, how to use it correctly?
Update
Here is the javap output. The -p make it work.
javap -v -l -s -p Bean.class
Classfile /Users/Documents/work/idea_workspace/asmtest/src/main/java/cn/curious/asm/Bean.class
Last modified 2020-3-5; size 127 bytes
MD5 checksum 7367bcf65d9a32a72e4261101d3697cc
public class cn.curious.asm.Bean
minor version: 0
major version: 52
flags: ACC_PUBLIC
Constant pool:
#1 = Utf8 cn/curious/asm/Bean
#2 = Class #1 // cn/curious/asm/Bean
#3 = Utf8 java/lang/Object
#4 = Class #3 // java/lang/Object
#5 = Utf8 lambda$main$1
#6 = Utf8 ()V
#7 = Utf8 Code
{
private static void lambda$main$1();
descriptor: ()V
flags: ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
Code:
stack=0, locals=0, args_size=0
0: return
}
Thats the idea behind synthetic methods, these are methods generated by compiler, so decompilers often skip it by default, as by definition they should not be needed in source code.
Like java specification states that
A construct emitted by a Java compiler must be marked as synthetic if it does not correspond to a construct declared explicitly or
implicitly in source code, unless the emitted construct is a class
initialization method (JVMS §2.9).
And jvm one:
The ACC_SYNTHETIC flag indicates that this method was generated by a
compiler and does not appear in source code [with some exceptions]
Try to use javap -verbose -private -s -classpath yourJar.jar my.Class (or just directly to class filed) instead, it should list all your methods. Or just generate second normal method that will invoke this synthetic method and check if you can run it. Or just use reflections and getDeclaredMethods method to get all declared methods, including synthetic ones.

How does the POI Event API read data from Excel and why does it use less RAM?

I am currently writing my bachelor thesis and I am using the POI Event API from Apache. In short, my work is about a more efficient way to read data from Excel.
I get asked by developers again and again how exactly this is meant with Event API. Unfortunately I don't find anything on the Apache page about the basic principle.
Following code, how I use the POI Event API (This is from the Apache example for XSSF and SAX):
import java.io.InputStream;
import java.util.Iterator;
import org.apache.poi.ooxml.util.SAXHelper;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.ParserConfigurationException;
public class ExampleEventUserModel {
public void processOneSheet(String filename) throws Exception {
OPCPackage pkg = OPCPackage.open(filename);
XSSFReader r = new XSSFReader( pkg );
SharedStringsTable sst = r.getSharedStringsTable();
XMLReader parser = fetchSheetParser(sst);
// To look up the Sheet Name / Sheet Order / rID,
// you need to process the core Workbook stream.
// Normally it's of the form rId# or rSheet#
InputStream sheet2 = r.getSheet("rId2");
InputSource sheetSource = new InputSource(sheet2);
parser.parse(sheetSource);
sheet2.close();
}
public void processAllSheets(String filename) throws Exception {
OPCPackage pkg = OPCPackage.open(filename);
XSSFReader r = new XSSFReader( pkg );
SharedStringsTable sst = r.getSharedStringsTable();
XMLReader parser = fetchSheetParser(sst);
Iterator<InputStream> sheets = r.getSheetsData();
while(sheets.hasNext()) {
System.out.println("Processing new sheet:\n");
InputStream sheet = sheets.next();
InputSource sheetSource = new InputSource(sheet);
parser.parse(sheetSource);
sheet.close();
System.out.println("");
}
}
public XMLReader fetchSheetParser(SharedStringsTable sst) throws SAXException, ParserConfigurationException {
XMLReader parser = SAXHelper.newXMLReader();
ContentHandler handler = new SheetHandler(sst);
parser.setContentHandler(handler);
return parser;
}
/**
* See org.xml.sax.helpers.DefaultHandler javadocs
*/
private static class SheetHandler extends DefaultHandler {
private SharedStringsTable sst;
private String lastContents;
private boolean nextIsString;
private SheetHandler(SharedStringsTable sst) {
this.sst = sst;
}
public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException {
// c => cell
if(name.equals("c")) {
// Print the cell reference
System.out.print(attributes.getValue("r") + " - ");
// Figure out if the value is an index in the SST
String cellType = attributes.getValue("t");
if(cellType != null && cellType.equals("s")) {
nextIsString = true;
} else {
nextIsString = false;
}
}
// Clear contents cache
lastContents = "";
}
public void endElement(String uri, String localName, String name)
throws SAXException {
// Process the last contents as required.
// Do now, as characters() may be called more than once
if(nextIsString) {
int idx = Integer.parseInt(lastContents);
lastContents = sst.getItemAt(idx).getString();
nextIsString = false;
}
// v => contents of a cell
// Output after we've seen the string contents
if(name.equals("v")) {
System.out.println(lastContents);
}
}
public void characters(char[] ch, int start, int length) {
lastContents += new String(ch, start, length);
}
}
public static void main(String[] args) throws Exception {
ExampleEventUserModel example = new ExampleEventUserModel();
example.processOneSheet(args[0]);
example.processAllSheets(args[0]);
}
}
Can someone please explain to me how the Event API works? Is it the same as the event-based architecture or is it something else?
A *.xlsx file, which is Excel stored in Office Open XML and is what apache poi handles as XSSF, is a ZIP archive containing the data in XML files within a directory structure. So we can unzip the *.xlsx file and get the data directly from the XML files then.
There is /xl/sharedStrings.xml having all the string cell values in it. And there is /xl/workbook.xml describing the workbook structure. And there are /xl/worksheets/sheet1.xml, /xl/worksheets/sheet2.xml, ... which are storing the sheets' data. And there is /xl/styles.xml having the style settings for all cells in the sheets.
Per default while creating a XSSFWorkbook all those parts of the *.xlsx file will become object representations as XSSFWorkbook, XSSFSheet, XSSFRow, XSSFCell, ... and further objects of org.apache.poi.xssf.*.* in memory.
To get an impression of how memory consuming XSSFSheet, XSSFRow and XSSFCell are, a look into the sources will be good. Each of those objects contains multiple Lists and Maps as internally members and of course multiple methods too. Now imagine a sheet having hundreds of thousands of rows each containing up to hundreds of cells. Each of those rows and cells will be represented by a XSSFRow or a XSSFCell in memory. This cannot be an accusation to apache poi because those objects are necessary if working with those objects is needed. But if the need is really only getting the content out of the Excel sheet, then those objects are not all necessary. That's why the XSSF and SAX (Event API) approach.
So if the need is only reading data from sheets one could simply parsing the XML of all the /xl/worksheets/sheet[n].xml files without the need for creating memory consuming objects for each sheet and for each row and for each cell in those sheets.
Parsing XML in event based mode means that the code goes top down through the XML and has callback methods defined which get called if the code detects the start of an element, the end of an element or character content within an element. The appropriate callback methods then handle what to do on start, end or with character content of an element. So reading the XML file only means running top down through the file once, handle the events (start, end, character content of an element) and are able getting all needed content out of it. So memory consuming is reduced to storing the text data gotten from the XML.
XSSF and SAX (Event API) uses class SheetHandler which extends DefaultHandler for this.
But if we are already at this level where we get at the underlying XML data and process it, then we could go one more step back too. Native Java is able handling ZIP and parsing XML. So we would not even need additional libraries at all. See how read excel file having more than 100000 row in java? where I have shown this. My code uses Package javax.xml.stream which also provides using event based XMLEventReader but not using callbacks but linear code. Maybe this code is simpler to understand because it is all in one.
For detecting whether a number format is a date format, and so the formatted cell contains a date / time value, one single apache poi class org.apache.poi.ss.usermodel.DateUtil is used. This is done to simplify the code. Of course even this class we could have coded our self.

get method to display containing folder, size, and time of last modification Java

I have a program I am writing for a class. I have got the first part down, but need help with the code for this part:
containing folder, size, and time of last modification these steps are the ones I need help writing in.
Here is the challenge
1. Create a file using any word-processing program or text editor. Write an application that displays the file’s name, containing folder, size, and time of last modification.
below is my code so far
import java.nio.file.*;
import java.nio.file.attribute.*;
import java.io.IOException;
import static java.nio.file.AccessMode.*;
public class FileStatistics
{
public static void main(String[] args)
{
Path filePath =
Paths.get("C:\\Users\\John\\Desktop\\N Drive\\St Leo Master folder\\COM-209\\module 6\\sixtestfile.txt");
System.out.println("Path is" + filePath.toString ());
try
{
filePath.getFileSystem().provider().checkAccess
(filePath, READ, EXECUTE);
System.out.println("File can be read & executed");
}
catch(IOException e)
{
System.out.println("File cannot be used in this app");
}
}
}

Modify file using Files.lines

I'd like to read in a file and replace some text with new text. It would be simple using asm and int 21h but I want to use the new java 8 streams.
Files.write(outf.toPath(),
(Iterable<String>)Files.lines(inf)::iterator,
CREATE, WRITE, TRUNCATE_EXISTING);
Somewhere in there I'd like a lines.replace("/*replace me*/","new Code()\n");. The new lines are because I want to test inserting a block of code somewhere.
Here's a play example, that doesn't work how I want it to, but compiles. I just need a way to intercept the lines from the iterator, and replace certain phrases with code blocks.
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import static java.nio.file.StandardOpenOption.*;
import java.util.Arrays;
import java.util.stream.Stream;
public class FileStreamTest {
public static void main(String[] args) {
String[] ss = new String[]{"hi","pls","help","me"};
Stream<String> stream = Arrays.stream(ss);
try {
Files.write(Paths.get("tmp.txt"),
(Iterable<String>)stream::iterator,
CREATE, WRITE, TRUNCATE_EXISTING);
} catch (IOException ex) {}
//// I'd like to hook this next part into Files.write part./////
//reset stream
stream = Arrays.stream(ss);
Iterable<String> it = stream::iterator;
//I'd like to replace some text before writing to the file
for (String s : it){
System.out.println(s.replace("me", "my\nreal\nname"));
}
}
}
edit: I've gotten this far and it works. I was trying with filter and maybe it isn't really necessary.
Files.write(Paths.get("tmp.txt"),
(Iterable<String>)(stream.map((s) -> {
return s.replace("me", "my\nreal\nname");
}))::iterator,
CREATE, WRITE, TRUNCATE_EXISTING);
The Files.write(..., Iterable, ...) method seems tempting here, but converting the Stream to an Iterable makes this cumbersome. It also "pulls" from the Iterable, which is a bit odd. It would make more sense if the file-writing method could be used as the stream's terminal operation, within something like forEach.
Unfortunately, most things that write throw IOException, which isn't permitted by the Consumer functional interface that forEach expects. But PrintWriter is different. At least, its writing methods don't throw checked exceptions, although opening one can still throw IOException. Here's how it could be used.
Stream<String> stream = ... ;
try (PrintWriter pw = new PrintWriter("output.txt", "UTF-8")) {
stream.map(s -> s.replaceAll("foo", "bar"))
.forEachOrdered(pw::println);
}
Note the use of forEachOrdered, which prints the output lines in the same order in which they were read, which is presumably what you want!
If you're reading lines from an input file, modifying them, and then writing them to an output file, it would be reasonable to put both files within the same try-with-resources statement:
try (Stream<String> input = Files.lines(Paths.get("input.txt"));
PrintWriter output = new PrintWriter("output.txt", "UTF-8"))
{
input.map(s -> s.replaceAll("foo", "bar"))
.forEachOrdered(output::println);
}

WAV Audio recording for Sphinx-4 fail

I recorded a wav file using Audacity for testing transcriber demo from Sphinx-4, I followed the instruction in this post: Sphinx4 speech recognition trasncribe demo not working accurately for short wav file
especially in this answer:
It must be 16khz 16bit mono little-endian file.
I even reduced the noise afterward. But I get the null error when I try to print the hypothesis which mean there was a problem with my recording:
Loading models...
Exception in thread "main" java.lang.NullPointerException
at transcriber.Transcriber.main(Transcriber.java:41)
Java Result: 1
BUILD SUCCESSFUL (total time: 2 minutes 14 seconds)
Line 41 where I print the hypothesis. what can I do to get it work?
Thanks
Edit:
The code is:
package transcriber;
import java.net.URL;
import edu.cmu.sphinx.api.Configuration;
import edu.cmu.sphinx.api.SpeechResult;
import edu.cmu.sphinx.api.StreamSpeechRecognizer;
import edu.cmu.sphinx.result.WordResult;
/**
*
* #author ha
*/
public class Transcriber {
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws Exception {
System.out.println("Loading models...");
Configuration configuration = new Configuration();
// Load model from the jar
configuration.setAcousticModelPath("resource:/WSJ_8gau_13dCep_16k_40mel_130Hz_6800Hz");
configuration.setDictionaryPath("resource:/WSJ_8gau_13dCep_16k_40mel_130Hz_6800Hz/dict/cmudict.0.6d");
configuration.setLanguageModelPath("models/language/en-us.lm.dmp");
StreamSpeechRecognizer recognizer = new StreamSpeechRecognizer(configuration);
URL audioUrl = new URL("file:WAV/Hello.wav");
recognizer.startRecognition(audioUrl.openStream());
SpeechResult result = recognizer.getResult();
System.out.println(recognizer.getResult().getHypothesis());
while ((result = recognizer.getResult()) != null) {
System.out.format("Hypothesis: %s\n",
result.getHypothesis());
}
System.out.println("Stop Recognition..");
recognizer.stopRecognition();
}
}
Replace
System.out.println(recognizer.getResult().getHypothesis());
with
System.out.println(result.getHypothesis());

Resources