Avian VM and Bio-Formats

classic Classic list List threaded Threaded
23 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Avian VM and Bio-Formats

dscho
Administrator
Hi Ullrich,

a little background information for everybody else: Ullrich is the
inventor and maintainer of VIGRA, an incredibly powerful C++ library to
process and analyze images. Its design was the most important source of
inspiration for ImgLib2. As a consequence, I was really delighted to meet
Ullrich at the EuBIAS meeting in Barcelona last week. Among other things,
we talked extensively about ways to interoperate between ImgLib2 and
VIGRA, and the lack of support in VIGRA to read file formats via the
Bio-Formats library.

Also at that meeting, I got into contact with the OpenMole project, and in
particular with Mark Hammons who not only explained patiently the benefits
of the Scala language to me, but also pointed out the existence of the
Avian VM, a small, embeddable, BSD-licensed Java Virtual Machine written
in C++, with a tiny Just-In-Time compiler, just enough to make it a
practical choice for running limited Java inside a C++ program/library:
http://oss.readytalk.com/avian/

It is actually very, very, *very* limited, as I found out when I tried to
get it to run the bfconvert tool of Bio-Formats.

But I did get it to run bfconvert. To be precise, in my hands, the 5MB
executable compiled from my fork of Avian was able to run my
(minimally-diverging) Bio-Formats v4.4.8 fork's
loci.formats.tools.ImageConverter class to convert Fiji's icon.png (my
standard example) to a .tiff file (although the colors are off, but
running the same example with plain Java results in a byte-identical
file).

Although it is too early for proper benchmarking, things seem to be
comparable between Java and Avian: while Java is slightly faster in what
time(1) calls "real" time (~0.54s vs ~0.72s), in terms of "user" time
roles are reversed (~0.70s vs ~0.63s). Roughly the same holds true for the
dynamic Avian executable (which is only 11K and links to Avian's libjvm.so
weighing in with a whopping 1.2M). The major benefit will most likely be
space: linking to libjvm.so should be enough, the standard Java classes
are included therein. So you can get Java support in VIGRA (or any other
C++ project) by adding a library that is slightly larger than one
megabyte.

Now to some more detailed explanations about the challenges I faced, for
the technically-inclined.

On the Bio-Formats side, there are two major and one minor (and one micro)
issue:

- to enable logging, Bio-Formats uses a cute hack called
  ReflectedUniverse, which is basically a scripting language for Java
  itself. However, it uses regular expressions, something that Avian's
  class library does not yet support.

- Bio-Formats uses a concurrent hashmap in loci.common.Location.
  Concurrency (JSR-166) is not supported by Avian's class library yet.

- in loci.formats.gui.LegacyQTTools, the value of the java.library.path
  property is used without checking whether the property is null (unset).

- some debug logging in Bio-Formats uses String.format() (not yet
  supported by Avian's class library).

All of these issues could be worked around in the code calling
Bio-Formats: there is no need to use the ImageConverter class (which
enables the logging), the concurrent hashmap could be faked by extending
the non-concurrent hashmap (and just not bothering with the concurrency
because we will most likely instantiate one VM per Bio-Formats call), the
java.library.path property could be initialized to a dummy value and the
logging could be switched off completely.

On the Avian side, I am happy to report that I only had to extend the
class library (apart from one bug fix that I will contribute upstream
later this week). In particular, I had to

- make RandomAccessFile support writing

- provide three dummy AWT classes because Bio-Formats actually links to
  them, but does not use them by default

- provide a couple of interfaces and exceptions that were not yet included
  in Avian

- implement a minimal java.io.DataOutputStream

- provide a FileChannel for RandomAccessFiles (i.e. implement getChannel)

- implement java.lang.Boolean's parse(String) method

- implement java.lang.Character's isISOControl(char) method

- implement fake byte order methods for ByteBuffers (they are hardcoded to
  big endian, but that is what Bio-Formats required in my test)

- provide a dummy SimpleDateFormat which actually does not work, but does
  not need to

- add toString(long[]) to java.util.Arrays

- teach Avian's pseudo regular expressions about "\\", i.e. the backslash

For the moment, all of these changes are contained in hodge podge
work-in-progress commits which I will clean up over the next few days. You
can see them here (the linked pages will update whenever I get around to
clean up the commits):

https://github.com/dscho/avian/compare/bio-formats
https://github.com/dscho/bioformats/compare/v4.4.8...avian

Since VIGRA and ImgLib2 share design concepts, and since SCIFIO supports
ImgLib2 natively, I think that my plan to extend the test to SCIFIO after
cleaning up my Avian fork is sound.

Once that is done, I will add unit tests that our trusty Jenkins will run
whenever SCIFIO (or Avian) changes, to ensure that things continue to
work. These unit tests will be extended as needed, e.g. when someone finds
out that an important use case requires more changes in Avian, still.

This way to call Bio-Formats and SCIFIO could become the default C++ entry
point into those libraries.

Summary: I showed that Bio-Formats/SCIFIO support for VIGRA and other C++
libraries is feasible through the BSD-licensed embeddable Java virtual
machine "Avian". I am confident that I can clean up my patches this week
still, to be contributed to the Avian project.

Ciao,
Johannes

_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel
Reply | Threaded
Open this post in threaded view
|

Re: [VIGRA] Avian VM and Bio-Formats

dscho
Administrator
Hi Ulli,

On Thu, 17 Oct 2013, Ullrich Koethe wrote:

> thank you for this very encouraging effort! Do I understand correctly
> that you achieved the following:
>
> * embed Avian in a C++ program
> * call BioFormats via the embedded Avian to convert a file into another
> format

Yes, that is essentially what I did. Except that the C++ program was
Avian's default one.

> but you didn't yet try to use Avian/BioFormats to read the data directly
> into a C++ data structure (such as vigra::MultiArray)? Is this latter
> step easy to achieve using standard JNI tools once the embedding/running
> of BioFormats works?

That would be the next step after cleaning up my Avian patches and trying
to read files via SCIFIO.

Once I can call a Java class that uses SCIFIO to read a file, it should be
very, very easy to access the read data via C++. Of course, the ultimate
goal would be to let SCIFIO read the data *directly* into VIGRA's data
structures, something I hope ImgLib2 makes easy: I would simply wrap the
C++ arrays in an ImgLib2-compatible container and ask SCIFIO to use that
as the destination.

Step by step ;-)
Johannes

_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel
Reply | Threaded
Open this post in threaded view
|

Re: [VIGRA] Avian VM and Bio-Formats

Ullrich Koethe
Hi Johannes,

>> Is this latter
>> step easy to achieve using standard JNI tools once the embedding/running
>> of BioFormats works?
>
> That would be the next step after cleaning up my Avian patches and trying
> to read files via SCIFIO.
>

Please let me know if you need any help from my side. I'll be happy to
include your solution into VIGRA.

Best regards
Ulli

_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel
Reply | Threaded
Open this post in threaded view
|

Re: [ome-devel] Avian VM and Bio-Formats

Roger Leigh
In reply to this post by dscho
On 17/10/2013 01:28, Johannes Schindelin wrote:

> Also at that meeting, I got into contact with the OpenMole project, and in
> particular with Mark Hammons who not only explained patiently the benefits
> of the Scala language to me, but also pointed out the existence of the
> Avian VM, a small, embeddable, BSD-licensed Java Virtual Machine written
> in C++, with a tiny Just-In-Time compiler, just enough to make it a
> practical choice for running limited Java inside a C++ program/library:
> http://oss.readytalk.com/avian/
>
> It is actually very, very, *very* limited, as I found out when I tried to
> get it to run the bfconvert tool of Bio-Formats.
>
> But I did get it to run bfconvert. To be precise, in my hands, the 5MB
> executable compiled from my fork of Avian was able to run my
> (minimally-diverging) Bio-Formats v4.4.8 fork's
> loci.formats.tools.ImageConverter class to convert Fiji's icon.png (my
> standard example) to a .tiff file (although the colors are off, but
> running the same example with plain Java results in a byte-identical
> file).

Hi Johannes,

This looks very intereresting.  Do you think this could replace the
existing use of JACE to provide C++ bindings, or would we still require
something like JACE to provide all the bindings/entry points into the
Avian VM?  I assume you will still need C++ headers/wrapper proxies
generating somehow?

On a related note, over the last few weeks, the first parts of the
native Bio-Formats C++ implementation have been staged.  This includes
shared libraries for the OME-XML data model and bioformats, though more
work is pending review; it's not yet complete.  In terms of the work
done, this includes all the basic infrastructure (cmake, platform
compatibility code), generated data model, and base model
interfaces/classes.  The metadata store classes are pending, and once
those are done we'll have all the needed bits for native
OME-XML/OME-TIFF reading and writing.

It may be the case that something like the Avian VM would be very useful
in providing support for readers and writers which do not have a native
C++ implementation.


Regards,
Roger

--
Dr Roger Leigh -- Open Microscopy Environment
Wellcome Trust Centre for Gene Regulation and Expression,
College of Life Sciences, University of Dundee, Dow Street,
Dundee DD1 5EH Scotland UK   Tel: (01382) 386364

The University of Dundee is a registered Scottish Charity, No: SC015096

_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel
Reply | Threaded
Open this post in threaded view
|

Re: Avian VM and Bio-Formats

Yili Zhao
In reply to this post by dscho
Hi,
  >> Its design was the most important source of inspiration for ImgLib2.
  Thanks for this information.
  When I read ImgLib2, I have a impression that its design has some similar with other library.
  Now I know this library is VIGRA :)

  By the way, I can not access http://hci.iwr.uni-heidelberg.de/vigra/ currently. Do others have this problem?   


2013/10/17 Johannes Schindelin <[hidden email]>
Hi Ullrich,

a little background information for everybody else: Ullrich is the
inventor and maintainer of VIGRA, an incredibly powerful C++ library to
process and analyze images. Its design was the most important source of
inspiration for ImgLib2. As a consequence, I was really delighted to meet
Ullrich at the EuBIAS meeting in Barcelona last week. Among other things,
we talked extensively about ways to interoperate between ImgLib2 and
VIGRA, and the lack of support in VIGRA to read file formats via the
Bio-Formats library.

Also at that meeting, I got into contact with the OpenMole project, and in
particular with Mark Hammons who not only explained patiently the benefits
of the Scala language to me, but also pointed out the existence of the
Avian VM, a small, embeddable, BSD-licensed Java Virtual Machine written
in C++, with a tiny Just-In-Time compiler, just enough to make it a
practical choice for running limited Java inside a C++ program/library:
http://oss.readytalk.com/avian/

It is actually very, very, *very* limited, as I found out when I tried to
get it to run the bfconvert tool of Bio-Formats.

But I did get it to run bfconvert. To be precise, in my hands, the 5MB
executable compiled from my fork of Avian was able to run my
(minimally-diverging) Bio-Formats v4.4.8 fork's
loci.formats.tools.ImageConverter class to convert Fiji's icon.png (my
standard example) to a .tiff file (although the colors are off, but
running the same example with plain Java results in a byte-identical
file).

Although it is too early for proper benchmarking, things seem to be
comparable between Java and Avian: while Java is slightly faster in what
time(1) calls "real" time (~0.54s vs ~0.72s), in terms of "user" time
roles are reversed (~0.70s vs ~0.63s). Roughly the same holds true for the
dynamic Avian executable (which is only 11K and links to Avian's libjvm.so
weighing in with a whopping 1.2M). The major benefit will most likely be
space: linking to libjvm.so should be enough, the standard Java classes
are included therein. So you can get Java support in VIGRA (or any other
C++ project) by adding a library that is slightly larger than one
megabyte.

Now to some more detailed explanations about the challenges I faced, for
the technically-inclined.

On the Bio-Formats side, there are two major and one minor (and one micro)
issue:

- to enable logging, Bio-Formats uses a cute hack called
  ReflectedUniverse, which is basically a scripting language for Java
  itself. However, it uses regular expressions, something that Avian's
  class library does not yet support.

- Bio-Formats uses a concurrent hashmap in loci.common.Location.
  Concurrency (JSR-166) is not supported by Avian's class library yet.

- in loci.formats.gui.LegacyQTTools, the value of the java.library.path
  property is used without checking whether the property is null (unset).

- some debug logging in Bio-Formats uses String.format() (not yet
  supported by Avian's class library).

All of these issues could be worked around in the code calling
Bio-Formats: there is no need to use the ImageConverter class (which
enables the logging), the concurrent hashmap could be faked by extending
the non-concurrent hashmap (and just not bothering with the concurrency
because we will most likely instantiate one VM per Bio-Formats call), the
java.library.path property could be initialized to a dummy value and the
logging could be switched off completely.

On the Avian side, I am happy to report that I only had to extend the
class library (apart from one bug fix that I will contribute upstream
later this week). In particular, I had to

- make RandomAccessFile support writing

- provide three dummy AWT classes because Bio-Formats actually links to
  them, but does not use them by default

- provide a couple of interfaces and exceptions that were not yet included
  in Avian

- implement a minimal java.io.DataOutputStream

- provide a FileChannel for RandomAccessFiles (i.e. implement getChannel)

- implement java.lang.Boolean's parse(String) method

- implement java.lang.Character's isISOControl(char) method

- implement fake byte order methods for ByteBuffers (they are hardcoded to
  big endian, but that is what Bio-Formats required in my test)

- provide a dummy SimpleDateFormat which actually does not work, but does
  not need to

- add toString(long[]) to java.util.Arrays

- teach Avian's pseudo regular expressions about "\\", i.e. the backslash

For the moment, all of these changes are contained in hodge podge
work-in-progress commits which I will clean up over the next few days. You
can see them here (the linked pages will update whenever I get around to
clean up the commits):

https://github.com/dscho/avian/compare/bio-formats
https://github.com/dscho/bioformats/compare/v4.4.8...avian

Since VIGRA and ImgLib2 share design concepts, and since SCIFIO supports
ImgLib2 natively, I think that my plan to extend the test to SCIFIO after
cleaning up my Avian fork is sound.

Once that is done, I will add unit tests that our trusty Jenkins will run
whenever SCIFIO (or Avian) changes, to ensure that things continue to
work. These unit tests will be extended as needed, e.g. when someone finds
out that an important use case requires more changes in Avian, still.

This way to call Bio-Formats and SCIFIO could become the default C++ entry
point into those libraries.

Summary: I showed that Bio-Formats/SCIFIO support for VIGRA and other C++
libraries is feasible through the BSD-licensed embeddable Java virtual
machine "Avian". I am confident that I can clean up my patches this week
still, to be contributed to the Avian project.

Ciao,
Johannes

_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel



--
Yili Zhao

_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel
Reply | Threaded
Open this post in threaded view
|

Re: Avian VM and Bio-Formats

Stephan Saalfeld
Hi Yili,

that is you didn't read beyond the first paragraph of the introduction:

http://bioinformatics.oxfordjournals.org/content/28/22/3009.full

, or the first paragraph of the conclusion in the ImgLib1 workshop
paper:

http://fly.mpi-cbg.de/~preibisch/pubs/imagejpaper2010.pdf

?  Depressing for the authors ;).

The other significant source of inspiration is ITK, if you don't know it
yet, check it out, also very cool stuff:

http://www.itk.org/

Best,
Stephan




On Sat, 2013-10-19 at 17:13 +0800, Yili Zhao wrote:

> Hi,
>   >> Its design was the most important source of inspiration for ImgLib2.
>   Thanks for this information.
>   When I read ImgLib2, I have a impression that its design has some similar
> with other library.
>   Now I know this library is VIGRA :)
>
>   By the way, I can not access
> http://hci.iwr.uni-heidelberg.de/vigra<http://hci.iwr.uni-heidelberg.de/vigra/%E2%80%8E>/
> currently.
> Do others have this problem?
>
>
> 2013/10/17 Johannes Schindelin <[hidden email]>
>
> > Hi Ullrich,
> >
> > a little background information for everybody else: Ullrich is the
> > inventor and maintainer of VIGRA, an incredibly powerful C++ library to
> > process and analyze images. Its design was the most important source of
> > inspiration for ImgLib2. As a consequence, I was really delighted to meet
> > Ullrich at the EuBIAS meeting in Barcelona last week. Among other things,
> > we talked extensively about ways to interoperate between ImgLib2 and
> > VIGRA, and the lack of support in VIGRA to read file formats via the
> > Bio-Formats library.
> >
> > Also at that meeting, I got into contact with the OpenMole project, and in
> > particular with Mark Hammons who not only explained patiently the benefits
> > of the Scala language to me, but also pointed out the existence of the
> > Avian VM, a small, embeddable, BSD-licensed Java Virtual Machine written
> > in C++, with a tiny Just-In-Time compiler, just enough to make it a
> > practical choice for running limited Java inside a C++ program/library:
> > http://oss.readytalk.com/avian/
> >
> > It is actually very, very, *very* limited, as I found out when I tried to
> > get it to run the bfconvert tool of Bio-Formats.
> >
> > But I did get it to run bfconvert. To be precise, in my hands, the 5MB
> > executable compiled from my fork of Avian was able to run my
> > (minimally-diverging) Bio-Formats v4.4.8 fork's
> > loci.formats.tools.ImageConverter class to convert Fiji's icon.png (my
> > standard example) to a .tiff file (although the colors are off, but
> > running the same example with plain Java results in a byte-identical
> > file).
> >
> > Although it is too early for proper benchmarking, things seem to be
> > comparable between Java and Avian: while Java is slightly faster in what
> > time(1) calls "real" time (~0.54s vs ~0.72s), in terms of "user" time
> > roles are reversed (~0.70s vs ~0.63s). Roughly the same holds true for the
> > dynamic Avian executable (which is only 11K and links to Avian's libjvm.so
> > weighing in with a whopping 1.2M). The major benefit will most likely be
> > space: linking to libjvm.so should be enough, the standard Java classes
> > are included therein. So you can get Java support in VIGRA (or any other
> > C++ project) by adding a library that is slightly larger than one
> > megabyte.
> >
> > Now to some more detailed explanations about the challenges I faced, for
> > the technically-inclined.
> >
> > On the Bio-Formats side, there are two major and one minor (and one micro)
> > issue:
> >
> > - to enable logging, Bio-Formats uses a cute hack called
> >   ReflectedUniverse, which is basically a scripting language for Java
> >   itself. However, it uses regular expressions, something that Avian's
> >   class library does not yet support.
> >
> > - Bio-Formats uses a concurrent hashmap in loci.common.Location.
> >   Concurrency (JSR-166) is not supported by Avian's class library yet.
> >
> > - in loci.formats.gui.LegacyQTTools, the value of the java.library.path
> >   property is used without checking whether the property is null (unset).
> >
> > - some debug logging in Bio-Formats uses String.format() (not yet
> >   supported by Avian's class library).
> >
> > All of these issues could be worked around in the code calling
> > Bio-Formats: there is no need to use the ImageConverter class (which
> > enables the logging), the concurrent hashmap could be faked by extending
> > the non-concurrent hashmap (and just not bothering with the concurrency
> > because we will most likely instantiate one VM per Bio-Formats call), the
> > java.library.path property could be initialized to a dummy value and the
> > logging could be switched off completely.
> >
> > On the Avian side, I am happy to report that I only had to extend the
> > class library (apart from one bug fix that I will contribute upstream
> > later this week). In particular, I had to
> >
> > - make RandomAccessFile support writing
> >
> > - provide three dummy AWT classes because Bio-Formats actually links to
> >   them, but does not use them by default
> >
> > - provide a couple of interfaces and exceptions that were not yet included
> >   in Avian
> >
> > - implement a minimal java.io.DataOutputStream
> >
> > - provide a FileChannel for RandomAccessFiles (i.e. implement getChannel)
> >
> > - implement java.lang.Boolean's parse(String) method
> >
> > - implement java.lang.Character's isISOControl(char) method
> >
> > - implement fake byte order methods for ByteBuffers (they are hardcoded to
> >   big endian, but that is what Bio-Formats required in my test)
> >
> > - provide a dummy SimpleDateFormat which actually does not work, but does
> >   not need to
> >
> > - add toString(long[]) to java.util.Arrays
> >
> > - teach Avian's pseudo regular expressions about "\\", i.e. the backslash
> >
> > For the moment, all of these changes are contained in hodge podge
> > work-in-progress commits which I will clean up over the next few days. You
> > can see them here (the linked pages will update whenever I get around to
> > clean up the commits):
> >
> > https://github.com/dscho/avian/compare/bio-formats
> > https://github.com/dscho/bioformats/compare/v4.4.8...avian
> >
> > Since VIGRA and ImgLib2 share design concepts, and since SCIFIO supports
> > ImgLib2 natively, I think that my plan to extend the test to SCIFIO after
> > cleaning up my Avian fork is sound.
> >
> > Once that is done, I will add unit tests that our trusty Jenkins will run
> > whenever SCIFIO (or Avian) changes, to ensure that things continue to
> > work. These unit tests will be extended as needed, e.g. when someone finds
> > out that an important use case requires more changes in Avian, still.
> >
> > This way to call Bio-Formats and SCIFIO could become the default C++ entry
> > point into those libraries.
> >
> > Summary: I showed that Bio-Formats/SCIFIO support for VIGRA and other C++
> > libraries is feasible through the BSD-licensed embeddable Java virtual
> > machine "Avian". I am confident that I can clean up my patches this week
> > still, to be contributed to the Avian project.
> >
> > Ciao,
> > Johannes
> >
> > _______________________________________________
> > ImageJ-devel mailing list
> > [hidden email]
> > http://imagej.net/mailman/listinfo/imagej-devel
> >
>
>
>
> _______________________________________________
> ImageJ-devel mailing list
> [hidden email]
> http://imagej.net/mailman/listinfo/imagej-devel


_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel
Reply | Threaded
Open this post in threaded view
|

Re: Avian VM and Bio-Formats

Yili Zhao
Hi Stephan,
  thanks for the information!

  I should have read them in more detail :)

  And thanks for the ITK introduction. I used VTK a bit, and CMake somtimes, and now I know they are trinity.


2013/10/19 Stephan Saalfeld <[hidden email]>
Hi Yili,

that is you didn't read beyond the first paragraph of the introduction:

http://bioinformatics.oxfordjournals.org/content/28/22/3009.full

, or the first paragraph of the conclusion in the ImgLib1 workshop
paper:

http://fly.mpi-cbg.de/~preibisch/pubs/imagejpaper2010.pdf

?  Depressing for the authors ;).

The other significant source of inspiration is ITK, if you don't know it
yet, check it out, also very cool stuff:

http://www.itk.org/

Best,
Stephan




On Sat, 2013-10-19 at 17:13 +0800, Yili Zhao wrote:
> Hi,
>   >> Its design was the most important source of inspiration for ImgLib2.
>   Thanks for this information.
>   When I read ImgLib2, I have a impression that its design has some similar
> with other library.
>   Now I know this library is VIGRA :)
>
>   By the way, I can not access
> http://hci.iwr.uni-heidelberg.de/vigra<http://hci.iwr.uni-heidelberg.de/vigra/%E2%80%8E>/
> currently.
> Do others have this problem?
>
>
> 2013/10/17 Johannes Schindelin <[hidden email]>
>
> > Hi Ullrich,
> >
> > a little background information for everybody else: Ullrich is the
> > inventor and maintainer of VIGRA, an incredibly powerful C++ library to
> > process and analyze images. Its design was the most important source of
> > inspiration for ImgLib2. As a consequence, I was really delighted to meet
> > Ullrich at the EuBIAS meeting in Barcelona last week. Among other things,
> > we talked extensively about ways to interoperate between ImgLib2 and
> > VIGRA, and the lack of support in VIGRA to read file formats via the
> > Bio-Formats library.
> >
> > Also at that meeting, I got into contact with the OpenMole project, and in
> > particular with Mark Hammons who not only explained patiently the benefits
> > of the Scala language to me, but also pointed out the existence of the
> > Avian VM, a small, embeddable, BSD-licensed Java Virtual Machine written
> > in C++, with a tiny Just-In-Time compiler, just enough to make it a
> > practical choice for running limited Java inside a C++ program/library:
> > http://oss.readytalk.com/avian/
> >
> > It is actually very, very, *very* limited, as I found out when I tried to
> > get it to run the bfconvert tool of Bio-Formats.
> >
> > But I did get it to run bfconvert. To be precise, in my hands, the 5MB
> > executable compiled from my fork of Avian was able to run my
> > (minimally-diverging) Bio-Formats v4.4.8 fork's
> > loci.formats.tools.ImageConverter class to convert Fiji's icon.png (my
> > standard example) to a .tiff file (although the colors are off, but
> > running the same example with plain Java results in a byte-identical
> > file).
> >
> > Although it is too early for proper benchmarking, things seem to be
> > comparable between Java and Avian: while Java is slightly faster in what
> > time(1) calls "real" time (~0.54s vs ~0.72s), in terms of "user" time
> > roles are reversed (~0.70s vs ~0.63s). Roughly the same holds true for the
> > dynamic Avian executable (which is only 11K and links to Avian's libjvm.so
> > weighing in with a whopping 1.2M). The major benefit will most likely be
> > space: linking to libjvm.so should be enough, the standard Java classes
> > are included therein. So you can get Java support in VIGRA (or any other
> > C++ project) by adding a library that is slightly larger than one
> > megabyte.
> >
> > Now to some more detailed explanations about the challenges I faced, for
> > the technically-inclined.
> >
> > On the Bio-Formats side, there are two major and one minor (and one micro)
> > issue:
> >
> > - to enable logging, Bio-Formats uses a cute hack called
> >   ReflectedUniverse, which is basically a scripting language for Java
> >   itself. However, it uses regular expressions, something that Avian's
> >   class library does not yet support.
> >
> > - Bio-Formats uses a concurrent hashmap in loci.common.Location.
> >   Concurrency (JSR-166) is not supported by Avian's class library yet.
> >
> > - in loci.formats.gui.LegacyQTTools, the value of the java.library.path
> >   property is used without checking whether the property is null (unset).
> >
> > - some debug logging in Bio-Formats uses String.format() (not yet
> >   supported by Avian's class library).
> >
> > All of these issues could be worked around in the code calling
> > Bio-Formats: there is no need to use the ImageConverter class (which
> > enables the logging), the concurrent hashmap could be faked by extending
> > the non-concurrent hashmap (and just not bothering with the concurrency
> > because we will most likely instantiate one VM per Bio-Formats call), the
> > java.library.path property could be initialized to a dummy value and the
> > logging could be switched off completely.
> >
> > On the Avian side, I am happy to report that I only had to extend the
> > class library (apart from one bug fix that I will contribute upstream
> > later this week). In particular, I had to
> >
> > - make RandomAccessFile support writing
> >
> > - provide three dummy AWT classes because Bio-Formats actually links to
> >   them, but does not use them by default
> >
> > - provide a couple of interfaces and exceptions that were not yet included
> >   in Avian
> >
> > - implement a minimal java.io.DataOutputStream
> >
> > - provide a FileChannel for RandomAccessFiles (i.e. implement getChannel)
> >
> > - implement java.lang.Boolean's parse(String) method
> >
> > - implement java.lang.Character's isISOControl(char) method
> >
> > - implement fake byte order methods for ByteBuffers (they are hardcoded to
> >   big endian, but that is what Bio-Formats required in my test)
> >
> > - provide a dummy SimpleDateFormat which actually does not work, but does
> >   not need to
> >
> > - add toString(long[]) to java.util.Arrays
> >
> > - teach Avian's pseudo regular expressions about "\\", i.e. the backslash
> >
> > For the moment, all of these changes are contained in hodge podge
> > work-in-progress commits which I will clean up over the next few days. You
> > can see them here (the linked pages will update whenever I get around to
> > clean up the commits):
> >
> > https://github.com/dscho/avian/compare/bio-formats
> > https://github.com/dscho/bioformats/compare/v4.4.8...avian
> >
> > Since VIGRA and ImgLib2 share design concepts, and since SCIFIO supports
> > ImgLib2 natively, I think that my plan to extend the test to SCIFIO after
> > cleaning up my Avian fork is sound.
> >
> > Once that is done, I will add unit tests that our trusty Jenkins will run
> > whenever SCIFIO (or Avian) changes, to ensure that things continue to
> > work. These unit tests will be extended as needed, e.g. when someone finds
> > out that an important use case requires more changes in Avian, still.
> >
> > This way to call Bio-Formats and SCIFIO could become the default C++ entry
> > point into those libraries.
> >
> > Summary: I showed that Bio-Formats/SCIFIO support for VIGRA and other C++
> > libraries is feasible through the BSD-licensed embeddable Java virtual
> > machine "Avian". I am confident that I can clean up my patches this week
> > still, to be contributed to the Avian project.
> >
> > Ciao,
> > Johannes
> >
> > _______________________________________________
> > ImageJ-devel mailing list
> > [hidden email]
> > http://imagej.net/mailman/listinfo/imagej-devel
> >
>
>
>
> _______________________________________________
> ImageJ-devel mailing list
> [hidden email]
> http://imagej.net/mailman/listinfo/imagej-devel




--
Yili Zhao

_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel
Reply | Threaded
Open this post in threaded view
|

SCIFIO via Avian, was Re: [VIGRA] Avian VM and Bio-Formats

dscho
Administrator
In reply to this post by dscho
Hi Ulli,

since you had the impression in a recent Skype chat that nothing has
happened with this project of mine since the last time I wrote a mail, let
me clarify the status, and add a few questions of my own.

[sorry for the long mail, everyone, I tried to make it more succinct, but
despite spending three hours on this mail, I did not succeed.]

On Thu, 17 Oct 2013, Johannes Schindelin wrote:

> On Thu, 17 Oct 2013, Ullrich Koethe wrote:
>
> > thank you for this very encouraging effort! Do I understand correctly
> > that you achieved the following:
> >
> > * embed Avian in a C++ program
> > * call BioFormats via the embedded Avian to convert a file into
> > another format
>
> Yes, that is essentially what I did. Except that the C++ program was
> Avian's default one.

I still use Avian's default executable (which essentially is a Java
look-alike) for the moment, so the main program is still a Java one, the
plan being to make this a C++ library that starts the Avian VM on demand.

But in the meantime, I use SCIFIO instead of Bio-Formats. The reason is
that Bio-Formats was not designed with a flexible data store in mind.
SCIFIO (which is essentially to Bio-Formats what ImageJ2 is to ImageJ1: a
complete overhaul of the architecture, applying lessons learned over the
years) offers a very convenient ImgOpener interface that works on ImgLib2
data structures (which are, as I pointed out at EuBIAS in Barcelona, at
least partially modeled after VIGRA). In particular, SCIFIO does no
dictate what data storage should be used, but instead uses the interfaces
defined by ImgLib2 to access whatever data storage you throw at it.

The good news first: I essentially got SCIFIO running in an Avian VM on
top of data structures backed by VIGRA (see below for more about the
backing data structures).

To be able to do that, I had to work quite a bit on Avian and got already
18 pull requests merged into the official Avian's master branch, with
three still waiting to be reviewed and merged. There are basically only
two changes I still need to implement/clean up and submit pull requests
for: Proper support for Runtime#availableMemory() and
Field#getGenericType().

Among other things, I even had to implement a full regular expression
engine (technically, I could have punted on that and only provided
handling for special cases but that is a very fragile solution and prone
to break; besides, I always wanted to implement a regex engine to
understand how these things work). So while there were some serious
obstacles, I am starting to see the sun. In fact, the remaining parts are
so easy, a first-year student could finish this project (under my
guidance, at least).

To put things into perspective, and also to correct your impression how
dedicated I am to this project: My first commit in the Avian project was
on October 17th -- the earliest date I could afford to work on this topic
after coming back from the EuBIAS meeting -- and in Avian's master branch
I am already the top #5 committer with 86 non-merge commits -- despite a
full week dedicated to a KNIME hackathon, and some intense release
engineering for the nar-maven-plugin mentioned below. The outstanding pull
requests should soon add 41 commits to that so that I'll be within 17
commits to tie top committer #3. For the record, Avian's initial commit
dates May 21st, 2007, i.e. within less than three percent of Avian's life
time, I made the top 5 of 44 committers in total. You see: I am dead set
to see VIGRA/SCIFIO integration working via Avian.

I also had to work on SCIFIO a little bit -- mainly bugs that were outside
the default call path, easily fixed with the awesome help of Mark Hiner
and Curtis Rueden.

To compile the native part, I use the nar-maven-plugin (which I foolishly
took maintainership of, but at least we have something pretty reliable now
both as plugin and as project). Tobias pointed out a few problems (due to
very unfortunate timing, I did not have the chance to fix them other than
suggest to use a stable Linux to compile rather than updating to a
just-released XCode and expect things to work flawlessly -- history be
ignored) that are mostly fixed now, thanks to the awesome Curtis Rueden
who cannot be thanked enough for all his help!

If you want to try things out, you will need to

- have compiled and installed VIGRA (I actually tested with revision
  494bd66423782280f31239b12dd2e7a6184d916b and had no reason to update so
  far)

- have an Oracle JDK for compiling (*not* for running)

- have a working Maven (e.g. from
  http://www.apache.org/dyn/closer.cgi/maven/maven-3/3.0.4/binaries/apache-maven-3.0.4-bin.tar.gz);
  Maven is essentially for Java what CMake tries to be for C++, but Maven
  is both easier to use and to extend.

- have the following branches of the following projects built (just call "mvn
  install" after cloning and switching to the correct branch):

  'avian' of https://github.com/scifio/scifio
  'debug/scifio' of https://github.com/dscho/avian
  'wip' of https://github.com/dscho/vigra-imglib2

After that, 'avian-run.sh' in the vigra-imglib2 directory should be able
to convert any given grayscale /tmp/img.pgm into a /tmp/img.tiff (being
read by SCIFIO, written by VIGRA). Yes, this does not do anything
interesting, but the example was designed to demonstrate the interaction
between SCIFIO and VIGRA, nothing else.

Depending on how fast we can resolve the questions below, I estimate that
we can have a stable C++ library offering SCIFIO to VIGRA (based on
'master' or even release versions of scifio, avian and vigra-imglib2)
early next year.

> > but you didn't yet try to use Avian/BioFormats to read the data
> > directly into a C++ data structure (such as vigra::MultiArray)? Is
> > this latter step easy to achieve using standard JNI tools once the
> > embedding/running of BioFormats works?
>
> That would be the next step after cleaning up my Avian patches and
> trying to read files via SCIFIO.

As I said, Bio-Formats does not lend itself to that kind of usage. It will
always require you to copy the data after reading them. SCIFIO, in
contrast, allows you to specify the factory to make instances of the
backing data store, including VIGRA-backed ones. This, BTW, is working now.

> Once I can call a Java class that uses SCIFIO to read a file, it should be
> very, very easy to access the read data via C++. Of course, the ultimate
> goal would be to let SCIFIO read the data *directly* into VIGRA's data
> structures, something I hope ImgLib2 makes easy: I would simply wrap the
> C++ arrays in an ImgLib2-compatible container and ask SCIFIO to use that
> as the destination.

I had a proof-of-concept of that VIGRA-backed ImgFactory already on
October 24th, thinking that maybe you'd have a glimpse at the progress in
my (public) GitHub repository ;-)

So now -- as promised -- the questions:

* SCIFIO's jpg and png support rely on Java Advanced Imaging which in turn
  relies on AWT (which is not available in Avian's class path library).
  While my long-term plan is to implement enough of AWT to support JAI,
  would it be okay to punt on jpg/png support via SCIFIO for now?

* as discussed in Skype, I am a bit lost (seven years after my last
  serious design of a C++-based architecture) how to make sure that once
  created in the Java part, the data structures are actually handled using
  the correct specializations of the C++ templates: SCIFIO can return images
  of any number of dimensions and any data type.

  My first idea would be to have the callback into C++ that creates the
  data structure (and needs to know the number of dimensions and the data
  type, of course) not only create the data structure but also provide
  kind of a virtual function table associated with said data structure. In
  essence, the C++ caller would pass a container to SCIFIO which would not
  only contain a pointer to the MultiArray upon return but also a pointer to
  the virtual function table of functions that are to be called on the
  loaded image.

  However, since you have waaay more extensive experience with this type of
  interfacing, may I ask you to whip up a quick mockup of the C++ side of
  this? IOW: how would you like the C++ side of the SCIFIO opener to look
  like?

* also as discussed in Skype, there is the issue whose responsibility it
  is to allocate and hold the data (including reference counting and
  especially releasing the memory at the appropriate time): Java's, or
  C++'s?

  For the benefit of those who have not been in that Skype chat, let me
  summarize the options we discussed (note that I make no distinction
  between Avian or Oracle JRE because Tobias wants to make the
  VIGRA/ImgLib2 bridge work in the other direction, using Oracle Java):

  From Java's perspective, the easiest would be if Java would allocate the
  memory because Java's memory management is pretty adamant about full
  control: to avoid memory fragmentation, Java's garbage collector wants
  to be able to shift data around (and therefore, it not only needs a
  reference *count* but a *list* of references and the ability to update
  them). For interaction with C/C++, Java has the notion of "pinning",
  i.e. telling the garbage collector that no, this chunk of memory needs to
  stay *exactly* where it is, right now, until I say otherwise. The API
  calls are named Get*ArrayElements()/Release*ArrayElements() for "pin"
  and "unpin" respectively. *All* the documentation referring to this feature
  say that pinning should be avoided, hampering performance of Java rather
  badly.

  From my own perspective, the easiest seemed to be to let VIGRA do all
  the data management and provide accessors for Java. Currently, still
  being in proof-of-concept phase, I was satisfied with individual JNI
  calls accessing the pixels individually, content with the notion that
  Avian (and most likely also Oracle's JRE) would be clever enough to
  optimize most of the call chain, even if the C++ function wrapping the
  call to MultiArray's [] operator will not be inlined, of course. Tobias
  pointed out correctly that we should be able to make use of the
  DirectByteBuffer feature to make this faster. And indeed, it is very
  easy: standard JNI provides the NewDirectByteBuffer() function accepting
  an address and a capacity and that's that. No pinning needed. Just your
  responsibility to make sure that endian issues do not bite you (I almost
  wrote "byte you" here...): Java handles *all* data as big endian.

  From Tobias' perspective, it looked the best to use the sun.misc.Unsafe
  class to allocate the memory (which would give us both an
  eternally-pinned C++ byte array as well as a Java byte[] access), then map
  it into VIGRA via a custom allocator. As I pointed out, my gut feeling
  strongly suggested this to be a finicky solution. In the meantime, I can
  put this into more coherent words (it does help that I thought these
  thoughts in a different week now than the one that was theoretically
  dedicated to the KNIME hackathon): if Unsafe is used to allocate the
  memory, the responsibility for releasing the memory should logically
  *also* be on the Java side, but by calling this from a C++ allocator, the
  roles are now confused: if C++ allocates the data structure, the C++
  destructor *needs* to release the memory, too.

  So the three options are:

        1) allocating/deallocating in Java, pinning whenever we call C++
           (making sure that C++ does not keep any references after
           returning)

        2) allocating/deallocating in C++, providing Java with access to
           the allocated memory

        3) allocating/deallocating in C++, except allocating the pixel
           array using Java's Unsafe class (requiring the Java VM to
           continue up and running during the complete life time of the
           image)

  I actually see the need for both 1) and 2) because we either start the
  bridge from C++ (in which case we'll want to let go of the VM as soon as
  the image is read/processed) or from Java (in which case we'll want the
  optimal performance of the Java code), but my experience tells me that
  3) will only lead to problems because of muddled responsibilities and
  therefore ample opportunity for race conditions.

  Having said that, quite often elegant design does not quite provide the
  performance we need. Therefore, I believe that we absolutely require a
  performance testing framework and preferably implementations of all
  three allocation methods mentioned above, to be pitted against each
  other (and may the fastest survive).

  Tobias, I guess this means you: you mentioned that you wrote such a
  performance test already (but I vaguely remember that you said you no
  longer have it, which means that you'll have to do it again). It will be
  essential to be able to test performance regularly, not only to test
  existing allocation strategies against each other, but new ones, too,
  and also different virtual machines (or versions thereof, think of the
  different performance characteristics of different versions of Oracle's
  JRE).

  So here the question: Tobias, where is that performance testing
  framework? If it is no longer there, when do you think you will have it
  again?

- from day one of my project, I developed this project in the open, for
  everybody to see, with at least three status updates. I understand that
  you worked on very related things, but instead of going on a hunt through
  your combined GitHub repositories to find it and try to avoid duplicating
  your work, may I ask you to tell me what you did so far, where I can
  find it, and where you want to go with it?

Happy thanksgiving!
Johannes

_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel
Reply | Threaded
Open this post in threaded view
|

Re: SCIFIO via Avian, was Re: [VIGRA] Avian VM and Bio-Formats

dscho
Administrator
Hi Ulli,

On Thu, 28 Nov 2013, Ullrich Koethe wrote:

> I checked out the repos you mentioned, but couldn't compile:
>
> > - have the following branches of the following projects built (just call
> > "mvn
> >    install" after cloning and switching to the correct branch):
> >
> >    'avian' of https://github.com/scifio/scifio
>
> 'mvn install' runs through.
>
> >    'debug/scifio' of https://github.com/dscho/avian
>
> 'mvn install' stops with
>
> [ERROR] The goal you specified requires a project to execute but there is no
> POM in this directory.

I am an idiot! Avian uses the "make" command. That will compile things
into a subdirectory of build/. It actually requires JAVA_HOME to point to
a JDK and javac to be in the PATH. Sorry for not describing this
correctly.

> >    'wip' of https://github.com/dscho/vigra-imglib2
>
> 'mvn install' stops with
>
> [ERROR] Error: Class net.imglib2.Interval could not be found.

That is funny. It works here without a hitch, but maybe only because I had
cloned and "mvn install"ed https://github.com/imagej/imglib earlier. Will
investigate.

> BTW, Tobias' VIGRA bindings work on my machine (Windows 7 with Visual
> Sudio 2012).

Okay. I fear that he duplicated a large part of my work to get there, but
then, I cannot look at it anyway :-)

Ciao,
Johannes

_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel
Reply | Threaded
Open this post in threaded view
|

Re: SCIFIO via Avian, was Re: [VIGRA] Avian VM and Bio-Formats

Ullrich Koethe
Hi Johannes,

thanks for the suggestions.

 >> 'mvn install' stops with
 >>
 >> [ERROR] The goal you specified requires a project to execute but
there is no
 >> POM in this directory.
 >
 > I am an idiot! Avian uses the "make" command. That will compile things
 > into a subdirectory of build/. It actually requires JAVA_HOME to point to
 > a JDK and javac to be in the PATH. Sorry for not describing this
 > correctly.
 >

OK, I tried make, but the makefile doesn't support Visual Studio (only
on Windows Phone, not on Windows 7). So I guess I'll have to start over
on a Linux box, because a mingw build will most certainly be
incompatible with the maven-compiled stuff, which used Visual Studio.
And anyway, mingw64 isn't supported either, only mingw32. cmake is not
that bad, after all...

 >>>     'wip' of https://github.com/dscho/vigra-imglib2
 >>
 >> 'mvn install' stops with
 >>
 >> [ERROR] Error: Class net.imglib2.Interval could not be found.
 >
 > That is funny. It works here without a hitch, but maybe only because
I had
 > cloned and "mvn install"ed https://github.com/imagej/imglib earlier. Will
 > investigate.
 >

When Tobias tried his code on my machine, we had a similar problem. We
solved it by adding some paths explicitly (vigra-imglib2/target/classes
and
$HOME/.m2/repository/net/imglib2/imglib2/2.0.0-SNAPSHOT/imglib2-2.0.0-SNAPSHOT.jar).
I applied the same change to your pom file, and got a bit further. The
error message is now

[ERROR] Error: Could not find class file for
'net.imglib2.vigra.VigraImg3DUnsignedByte'.

 >> BTW, Tobias' VIGRA bindings work on my machine (Windows 7 with Visual
 >> Sudio 2012).
 >
 > Okay. I fear that he duplicated a large part of my work to get there, but
 > then, I cannot look at it anyway
 >

No, there is no duplication. The two approaches are completely
complementary -- yours is for embedding Java in a VIGRA program, and
Tobias' is to call VIGRA code from Java. You can have a look at
   https://github.com/tpietzsch/vigra-imglib2/tree/buffer

Best regards
Ulli

_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel
Reply | Threaded
Open this post in threaded view
|

Re: SCIFIO via Avian, was Re: [VIGRA] Avian VM and Bio-Formats

dscho
Administrator
Hi Ulli,

On Fri, 29 Nov 2013, Ullrich Koethe wrote:

> > > 'mvn install' stops with
> > >
> > > [ERROR] The goal you specified requires a project to execute but
> > > there is no POM in this directory.
> >
> > I am an idiot! Avian uses the "make" command. That will compile things
> > into a subdirectory of build/. It actually requires JAVA_HOME to point
> > to a JDK and javac to be in the PATH. Sorry for not describing this
> > correctly.
> >
>
> OK, I tried make, but the makefile doesn't support Visual Studio (only on
> Windows Phone, not on Windows 7). So I guess I'll have to start over on a
> Linux box, because a mingw build will most certainly be incompatible with the
> maven-compiled stuff, which used Visual Studio.

There are ways to use GCC with the nar-maven-plugin. The ImageJ launcher
uses that method for a long time already, so I am certain that it works.

> And anyway, mingw64 isn't supported either, only mingw32. cmake is not
> that bad, after all...

Again, I did not have problems with ming64 with nar-maven-plugin. But
maybe you are referring to Avian?

And why are you trying to get things to work on the platform that is
notorious for being the most difficult to develop platform-independently
for? Is Windows not something that we should try to support *after*
everything else works instead of *before*? If you want to have a realistic
chance to get things going, always try Linux first. It is *the*
best-supported platform for cross-platform development. I know, I am
writing this on a Mac, but even on a Mac you can install Linux in a
VirtualBox, so there is really no excuse for making this harder to get
going than necessary.

Sorry if this sounds harsh, but I am trying to get the VIGRA/ImgLib2
bridge going, not the *Windows* VIGRA/ImgLib2 bridge. Of course, my
extensive knowledge with cross-platform development will be helpful to
resolve that problem, too, but should we not rather try to solve the
current problems first before we tackle the problem called Windows? I
mean, I am happy to help you with that, sure, but I would really like to
get at the meat of the current problem first, and solve it, so that that
is said and done.

> > > >     'wip' of https://github.com/dscho/vigra-imglib2
> > >
> > > 'mvn install' stops with
> > >
> > > [ERROR] Error: Class net.imglib2.Interval could not be found.
> >
> > That is funny. It works here without a hitch, but maybe only because I
> > had cloned and "mvn install"ed https://github.com/imagej/imglib
> > earlier. Will investigate.
> >
>
> When Tobias tried his code on my machine, we had a similar problem.

As I said, Windows is notorious for being hard to compile
platform-independent code on. It is not only the insistence on a
non-standard C++ ABI (you cannot mix and match Visual C++-compiled code
with GNU C++-compiled code because GNU C++ *adheres* to the standard while
Visual C++ does not). It is also the chronical problems with a lack of
standardized installation paths for headers and libraries, the lack of
speed with its filesystem drivers (and as a consequence insane runtimes of
compilation and Git operations compared to every other operating system).
And of course it is the complete and utter lack of POSIX routines,
something industry outside Microsoft's area of influence settled on a long
time ago.

So maybe it would really be a good idea to follow my suggestion and tackle
the real problems first, and only then the WIndows-specific ones?

> We solved it by adding some paths explicitly
> (vigra-imglib2/target/classes and
> $HOME/.m2/repository/net/imglib2/imglib2/2.0.0-SNAPSHOT/imglib2-2.0.0-SNAPSHOT.jar).

Oh, I misunderstood  what you meant by "similar problem" above, then.

> I applied the same change to your pom file, and got a bit further. The
> error message is now
>
> [ERROR] Error: Could not find class file for
> 'net.imglib2.vigra.VigraImg3DUnsignedByte'.

Yes, there is another thing I completely forgot to mention: in
vigra-imglib2, I ran "mvn dependency:copy-dependencies" a long time ago
(back when I mentioned to Tobias that I was working on this),
so long ago that I forgot in the meantime. Very sorry for this!

> > > BTW, Tobias' VIGRA bindings work on my machine (Windows 7 with
> > > Visual Sudio 2012).
> >
> > Okay. I fear that he duplicated a large part of my work to get there, but
> > then, I cannot look at it anyway
> >
>
> No, there is no duplication. The two approaches are completely complementary
> -- yours is for embedding Java in a VIGRA program, and Tobias' is to call
> VIGRA code from Java. You can have a look at
>   https://github.com/tpietzsch/vigra-imglib2/tree/buffer

Thank you for sharing that information with me.

Ciao,
Dscho

_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel
Reply | Threaded
Open this post in threaded view
|

Re: SCIFIO via Avian, was Re: [VIGRA] Avian VM and Bio-Formats

Ullrich Koethe
Hi Johannes,

>>> I am an idiot! Avian uses the "make" command. That will compile things
>>> into a subdirectory of build/. It actually requires JAVA_HOME to point
>>> to a JDK and javac to be in the PATH. Sorry for not describing this
>>> correctly.
>>
>> OK, I tried make, but the makefile doesn't support Visual Studio (only on
>> Windows Phone, not on Windows 7). So I guess I'll have to start over on a
>> Linux box, because a mingw build will most certainly be incompatible with the
>> maven-compiled stuff, which used Visual Studio.
>
> Again, I did not have problems with ming64 with nar-maven-plugin. But
> maybe you are referring to Avian?
>

Indeed, I was referring to the make-based compilation of Avian, not to
maven.

> And why are you trying to get things to work on the platform that is
> notorious for being the most difficult to develop platform-independently
> for?

Last week, we simply tried Tobias' code on my Windows box, and (thanks
to maven) it worked more or less out of the box, except for the extra
paths we had to add to pom.xml (see my earlier mail) and an
incompatibility in some macro magic that turned out to be easy to fix.
Encouraged by this success, I simply tried your code as well.

I don't mind switching to Linux for the time being, it just means that I
have to install all prerequisites again, which will take some time.

> As I said, Windows is notorious for being hard to compile
> platform-independent code on. It is not only the insistence on a
> non-standard C++ ABI (you cannot mix and match Visual C++-compiled code
> with GNU C++-compiled code because GNU C++ *adheres* to the standard while
> Visual C++ does not).

GNU's standard adherence notwithstanding, different versions of gcc
still produce mutually incompatible shared libraries, see our other
conversation on the VIGRA mailing list. So Linux and Mac are not really
much better in this respect. In the end, it is the complexity of C++
that bites everyone.

> It is also the chronical problems with a lack of
> standardized installation paths for headers and libraries,

Indeed. I opted for a Unix-like path structure according to
c:\install\bin, c:\install\include etc., which makes life a lot easier.

> the lack of
> speed with its filesystem drivers (and as a consequence insane runtimes of
> compilation and Git operations compared to every other operating system).

VIGRA compilation takes about the same time on Windows and Linux, and I
haven't experienced any latency in git either. In contrast, maven did
indeed seem to be a bit on the slow side.

> And of course it is the complete and utter lack of POSIX routines,
> something industry outside Microsoft's area of influence settled on a long
> time ago.
>

I guess, the boost libraries have solved this problem for most purposes,
and better than POSIX for that matter.

> Yes, there is another thing I completely forgot to mention: in
> vigra-imglib2, I ran "mvn dependency:copy-dependencies" a long time ago
> (back when I mentioned to Tobias that I was working on this),
> so long ago that I forgot in the meantime. Very sorry for this!
>

OK. I executed "mvn dependency:copy-dependencies", followed by "mvn
install", and am back to

[ERROR] Error: Class net.imglib2.Interval could not be found.

But since Avian won't work easily on this machine anyway, it's probably
not worth fixing now.

Best regards
Ulli

_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel
Reply | Threaded
Open this post in threaded view
|

Re: SCIFIO via Avian, was Re: [VIGRA] Avian VM and Bio-Formats

Tobias Pietzsch
Hi Johannes and Ulli,

with respect to the need to set up the paths in the pom.xml:
This is an issue with the nar-maven-plugin, which compiles and packages the native code.
With Johannes' help, I submitted an integration test to the nar-maven-plugin project, that illustrates this problem. So hopefully it will be fixed at some point in the future.
Ulli, I remember that there was another issue on Windows: The dll was named differently to what the NarHelper class expects. Could you elaborate on that?

With respect to what we did on the vigra-imglib2 project. I forked your project, Johannes, https://github.com/tpietzsch/vigra-imglib2.
We worked on the "buffer" branch.
This is using direct buffers as the underlying data structure for both ImgLib2's ArrayImg and VIGRA's MultiArrayView. At the moment, the direct buffer is allocated on the Java side, but as you pointed out, one can use JNI's NewDirectByteBuffer() from the C++ side. I think this is a good solution, because it leaves the option for both scenarios, Java embedded in C++ and C++ embedded in Java. The ByteBuffer is wrapped in a ImgLib2 Access (e.g. IntAccess for Imgs of IntType. It is easy to provide two constructors there, one which allocates the buffer and one which takes an existing buffer. Responsibility for freeing the memory is not a problem. Note that JNI NewDirectByteBuffer is constructed with already allocated memory. So, if C++ allocated the memory, Java may garbage-collect the ByteBuffer, but will not free the memory block. If creating the ByteBuffer form Java, Java will also free the memory.
The good thing is that both ImgLib ArrayImgs and VIGRA MultiArrayViews were designed to wrap flat arrays, which is what is happening here.

The ByteBuffer code came from the ImgLib2 branch "buffer-and-unsafe", where I played with using direct buffers and sun.misc.Unsafe to back ArrayImgs instead of Java primitive arrays.
sun.misc.Unsafe is the other viable option. In contrast to primitive arrays and direct buffers it does not suffer from the 2G size limit of Java arrays. Of course, if we put it behind an ArrayImg, we cannot make use of that fact yet. So we could have a BigArrayImg at some point in the future (which would be useful in its own right). Otherwise, same advantages as explained above.
The benchmark that Johannes mentioned was comparing the speed of ArrayImgs backed by primitive arrays, direct buffers, and sun.misc.Unsafe, respectively. I just had a look and I couldn't find it. I'll recreate it next week.

Note, that I copied the byte buffer stuff from the ImgLib2 branch "buffer-and-unsafe", so that vigra-imglib2 works with the current ImgLib2 beta.

But wrapping the images back and forth was only part of what we did. An important point is to make it easy to make bindings to VIGRA functions withou writing lots of boilderplate code on either side of JNI. Based on earlier VIGRA-Matlab wrapper we made some macros that allow to write on the C++ side

JNIEXPORT void JNICALL Java_net_imglib2_vigra_VigraWrapper_gaussianSmoothMultiArray
  (JNIEnv *env, jclass, jlongArray shape, jint typeId, jobject sourceData, jobject destData, jdouble sigma)
{
    using namespace vigra; // to get UInt8 and Int32
    #define F(T) gaussianSmoothMultiArray<T>(env, shape, typeId, sourceData, destData, sigma)
    ALLOW_TYPES(typeId, UInt8, Int32, float)
    #undef F
}

This creates a switch statement that instantiates the VIGRA template function for the specified C++ types and dispatches to these according to the corresponding ImgLib type.
The same is done for supported dimensionalities (because with templates we have to specify that at compile time).

The plan is to directly pass in the ArrayImg jobject (and maybe even views later) and extract the type and dimension etc directly from that.
This would mean, that on the Java side, we only have one native method for each exported VIGRA function, basically with the same signature and just replacing MultiArrayView with Img.

best regards,
Tobias


_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel

signature.asc (465 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: SCIFIO via Avian

Tobias Pietzsch
Hi guys,

I made a benchmark for ArrayImg backed by
- primitive arrays
- direct buffers
- sun.misc.Unsafe (off-heap memory)
(in branch "buffer-and-unsafe")

On my computer, the result is that Unsafe is the about the same speed as primitive arrays. Direct buffers are consistently slower:

copy image using class net.imglib2.img.array.ArrayImgFactory
median: 52 ms

copy image using class net.imglib2.img.array.ArrayImgUnsafeFactory
median: 52 ms

copy image using class net.imglib2.img.array.ArrayImgBufferFactory
median: 59 ms

The not-so-good news is that using the same type backed by different accesses will make the calls into the ByteAccess (or whatever the type is) polymorphic, spoiling it for the JIT (at least if both are used from the same call-site).
This is visible in the second part of the benchmark. Here, a constant UnsignedByteType is added to every pixel of the image. Because the new UnsignedByteType(1) is always backed by a primitive array, we hit the bimorphic case for Unsafe and direct buffer, and this results in a big slowdown:

add constant to image using class net.imglib2.img.array.ArrayImgFactory
median: 22 ms

add constant to image using class net.imglib2.img.array.ArrayImgUnsafeFactory
median: 122 ms

add constant to image using class net.imglib2.img.array.ArrayImgBufferFactory
median: 186 ms

We can try some tricks to make UnsignedByteType constants backed by the other ByteAccess types, but in general I see no easy way around this.
Maybe someone has a few months to spare to make imglib3 using ASM or Javassist to manually inline this stuff (that would solve the bottleneck in making a proper bidirectional read/write type hierarchy…) Of course, we can always hope that the JIT will "get it" at some point in the future, but I think this is quite a pathological case.

I think, we should go for the sun.misc.Unsafe for now.
If it really turns out to be a show-stopper, we will have to look into using primitive arrays and pinning. One downside of that would be that then the memory must be owned by Java, so it would be a problem for the Avian integration. Another downside is that JNI implementations are not forced to pin the array, they may just decide to copy the data.

I also made a imglib2-vigra branch that uses Unsafe https://github.com/tpietzsch/vigra-imglib2/commits/unsafe (requires the buffer-and-unsafe branch of imglib2).

best regards,
Tobias

On Nov 30, 2013, at 12:36 AM, Tobias Pietzsch <[hidden email]> wrote:

Hi Johannes and Ulli,

with respect to the need to set up the paths in the pom.xml:
This is an issue with the nar-maven-plugin, which compiles and packages the native code.
With Johannes' help, I submitted an integration test to the nar-maven-plugin project, that illustrates this problem. So hopefully it will be fixed at some point in the future.
Ulli, I remember that there was another issue on Windows: The dll was named differently to what the NarHelper class expects. Could you elaborate on that?

With respect to what we did on the vigra-imglib2 project. I forked your project, Johannes, https://github.com/tpietzsch/vigra-imglib2.
We worked on the "buffer" branch.
This is using direct buffers as the underlying data structure for both ImgLib2's ArrayImg and VIGRA's MultiArrayView. At the moment, the direct buffer is allocated on the Java side, but as you pointed out, one can use JNI's NewDirectByteBuffer() from the C++ side. I think this is a good solution, because it leaves the option for both scenarios, Java embedded in C++ and C++ embedded in Java. The ByteBuffer is wrapped in a ImgLib2 Access (e.g. IntAccess for Imgs of IntType. It is easy to provide two constructors there, one which allocates the buffer and one which takes an existing buffer. Responsibility for freeing the memory is not a problem. Note that JNI NewDirectByteBuffer is constructed with already allocated memory. So, if C++ allocated the memory, Java may garbage-collect the ByteBuffer, but will not free the memory block. If creating the ByteBuffer form Java, Java will also free the memory.
The good thing is that both ImgLib ArrayImgs and VIGRA MultiArrayViews were designed to wrap flat arrays, which is what is happening here.

The ByteBuffer code came from the ImgLib2 branch "buffer-and-unsafe", where I played with using direct buffers and sun.misc.Unsafe to back ArrayImgs instead of Java primitive arrays.
sun.misc.Unsafe is the other viable option. In contrast to primitive arrays and direct buffers it does not suffer from the 2G size limit of Java arrays. Of course, if we put it behind an ArrayImg, we cannot make use of that fact yet. So we could have a BigArrayImg at some point in the future (which would be useful in its own right). Otherwise, same advantages as explained above.
The benchmark that Johannes mentioned was comparing the speed of ArrayImgs backed by primitive arrays, direct buffers, and sun.misc.Unsafe, respectively. I just had a look and I couldn't find it. I'll recreate it next week.

Note, that I copied the byte buffer stuff from the ImgLib2 branch "buffer-and-unsafe", so that vigra-imglib2 works with the current ImgLib2 beta.

But wrapping the images back and forth was only part of what we did. An important point is to make it easy to make bindings to VIGRA functions withou writing lots of boilderplate code on either side of JNI. Based on earlier VIGRA-Matlab wrapper we made some macros that allow to write on the C++ side

JNIEXPORT void JNICALL Java_net_imglib2_vigra_VigraWrapper_gaussianSmoothMultiArray
  (JNIEnv *env, jclass, jlongArray shape, jint typeId, jobject sourceData, jobject destData, jdouble sigma)
{
    using namespace vigra; // to get UInt8 and Int32
    #define F(T) gaussianSmoothMultiArray<T>(env, shape, typeId, sourceData, destData, sigma)
    ALLOW_TYPES(typeId, UInt8, Int32, float)
    #undef F
}

This creates a switch statement that instantiates the VIGRA template function for the specified C++ types and dispatches to these according to the corresponding ImgLib type.
The same is done for supported dimensionalities (because with templates we have to specify that at compile time).

The plan is to directly pass in the ArrayImg jobject (and maybe even views later) and extract the type and dimension etc directly from that.
This would mean, that on the Java side, we only have one native method for each exported VIGRA function, basically with the same signature and just replacing MultiArrayView with Img.

best regards,
Tobias

_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel


_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel

signature.asc (465 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: SCIFIO via Avian

dscho
Administrator
Hi Tobi,

On Thu, 5 Dec 2013, Tobias Pietzsch wrote:

> I made a benchmark for ArrayImg backed by
> - primitive arrays
> - direct buffers
> - sun.misc.Unsafe (off-heap memory)
> https://github.com/imagej/imglib/blob/2e1929873e2f4bafcfe9d90ad616fedb8b7ed4f0/tests/src/test/java/net/imglib2/img/BufferAndUnsafeBenchmark.java
> (in branch "buffer-and-unsafe")

Thanks!

> On my computer, the result is that Unsafe is the about the same speed as primitive arrays. Direct buffers are consistently slower:
>
> copy image using class net.imglib2.img.array.ArrayImgFactory
> median: 52 ms
>
> copy image using class net.imglib2.img.array.ArrayImgUnsafeFactory
> median: 52 ms
>
> copy image using class net.imglib2.img.array.ArrayImgBufferFactory
> median: 59 ms

Okay. But please, do not use the Median for measuring the performance. All
you are doing is to confuse the benchmark with noise: the theoretically
optimal runtime can really not be measured in multi-process environments,
but at least we know that it can only be reached, never succeeded. For
that reason, best-of-5 is a well-established technique to measure
performance. (By necessity, the Median will be a worse approximation to
the time you would like to determine than the best time...)

> The not-so-good news is that using the same type backed by different
> accesses will make the calls into the ByteAccess (or whatever the type
> is) polymorphic, spoiling it for the JIT (at least if both are used from
> the same call-site).

Yes, this is something we will need to address sooner or later. As I
demonstrated at our hackathon in Madison, I have a couple of good ideas.
It just needs a proper home for them, and I think scijava-ops is actually
the best place.

> I think, we should go for the sun.misc.Unsafe for now.

Fair enough.

> If it really turns out to be a show-stopper, we will have to look into
> using primitive arrays and pinning. One downside of that would be that
> then the memory must be owned by Java, so it would be a problem for the
> Avian integration.

No, not at all. Avian has very good memory management.

But Avian also supports Unsafe, even if other JVMs might not (Unsafe is
not a part of the official Java API, after all, with Oracle's JVM you
still have to play dirty tricks to access Unsafe).

In contrast to Oracle's JVM, Avian makes accessing Unsafe very easy and
not only that: Avian's JIT will completely inline the memory accesses via
Unsafe:

        https://github.com/ReadyTalk/avian/blob/master/src/compile.cpp#L3965

In effect, Avian's access via Unsafe is -- apart from the one-time cost of
JITting the code at the start of the program -- *as* performant as native
C accesses would be.

> Another downside is that JNI implementations are not forced to pin the
> array, they may just decide to copy the data.

That's not quite correct: the larger the data structure you are accessing,
the more less possible it is that the JNI implementation can move the data
around. This is not dictated by the standard, but by simple considerations
of practicability.

> I also made a imglib2-vigra branch that uses Unsafe
> https://github.com/tpietzsch/vigra-imglib2/commits/unsafe (requires the
> buffer-and-unsafe branch of imglib2).

Great!

In related news, I managed to get literally all the important changes into
Avian that are required to run SCIFIO (in the process being the top #4
committer of Avian).

Also in related news, the nar-maven-plugin is already at version
3.0.0-rc-2, available via Maven Central (Tobi, rc-2 already has the
changes you wanted for javah, no need to depentd on a SNAPSHOT release
that was never deployed). Just for the record, I am top #3 committer of
the nar-maven-plugin project and now co-maintainer with Curtis Rueden,
all driven by the vigra-imglib2 project.

My next steps will be a little slower because real work caught up with me.
But my plan is to provide an easy way to compile the native part of
vigra-imglib2. Part of the solution will be to have Avian and VIGRA as
submodules (I know, Git submodules could have been designed much better,
but for the task at hand, they come in handy). To address the rest of the
problem Ulli faced, I will modify the Maven project so that the output
will be a C++ library that has Avian and SCIFIO/ImgLib2 compiled-in,
without the need to compile other stuff manually or install too many other
components (although C++ compiler and CMake will always have to be
installed by the user, unfortunately).

Ciao,
Johannes

_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel
Reply | Threaded
Open this post in threaded view
|

Re: [VIGRA] Avian VM and Bio-Formats

Ullrich Koethe
In reply to this post by dscho
Hi Johannes and Tobias,

following your instructions, I now installed all dependencies on Linux
(64-bit Ubuntu, gcc 4.7.3). Here is what I got:

In scifio, maven compiles, but then complains

    Failed tests:   testDefaultEnabled(io.scif.filters.utests.FilterTest)

In vigra-imglib2 (branch 'wip'), 'mvn install' compiles and produces a
number of compiler warnings which seem to be uncritical on first glance,
but are confusingly flagged as "[ERROR]" in the maven output.

When I finally run './avian-run.sh', I get the following output

java.io.EOFException
   at java.util.zip.InflaterInputStream.read (line 54)
   at java.util.zip.ZipFile$1.read (line 120)
   at java.util.zip.ZipFile$1.read (line 114)
   at java.util.zip.InflaterInputStream.read (line 39)
   at java.util.zip.ZipFile$1.read (line 106)
   at java.util.Properties$InputStreamParser.readCharacter (line 192)
   at java.util.Properties$Parser.parse (line 106)
   at java.util.Properties.load (line 21)
   at net.imglib2.vigra.NarHelper.loadLibrary (line 41)
   at net.imglib2.vigra.VigraImg3DUnsignedByte.<clinit> (line 23)
   at net.imglib2.vigra.VigraImgFactory3DUnsignedByte.create (line 19)
   at net.imglib2.vigra.VigraImgFactory3DUnsignedByte.create (line 14)
   at io.scif.img.ImgOpener.openImg (line 301)
   at io.scif.img.ImgOpener.openImg (line 217)
   at io.scif.img.ImgOpener.openImg (line 200)
   at Example.main (line 34)
   at Example.main (line 22)
java.lang.ExceptionInInitializerError
   at net.imglib2.vigra.VigraImgFactory3DUnsignedByte.create (line 19)
   at net.imglib2.vigra.VigraImgFactory3DUnsignedByte.create (line 14)
   at io.scif.img.ImgOpener.openImg (line 301)
   at io.scif.img.ImgOpener.openImg (line 217)
   at io.scif.img.ImgOpener.openImg (line 200)
   at Example.main (line 34)
   at Example.main (line 22)
caused by: java.lang.UnsatisfiedLinkError: Could not find native library
   at net.imglib2.vigra.NarHelper.loadLibrary (line 78)
   at net.imglib2.vigra.VigraImg3DUnsignedByte.<clinit> (line 23)
   at net.imglib2.vigra.VigraImgFactory3DUnsignedByte.create (line 19)
   at net.imglib2.vigra.VigraImgFactory3DUnsignedByte.create (line 14)
   at io.scif.img.ImgOpener.openImg (line 301)
   at io.scif.img.ImgOpener.openImg (line 217)
   at io.scif.img.ImgOpener.openImg (line 200)
   at Example.main (line 34)
   at Example.main (line 22)

No image is created. The input image I used is attached.

When I try to compile Tobias' code (branch 'buffer'), I get

[WARNING] The POM for
com.github.maven-nar:nar-maven-plugin:jar:3.0.0-rc-3-SNAPSHOT is
missing, no dependency information available
[ERROR] The build could not read 1 project -> [Help 1]
[ERROR]
[ERROR]   The project net.imglib2.vigra:vigra-imglib2:1.0.0-SNAPSHOT
(/home/ukoethe/src/vigra-imglib2/pom.xml) has 2 errors
[ERROR]     Unresolveable build extension: Plugin
com.github.maven-nar:nar-maven-plugin:3.0.0-rc-3-SNAPSHOT or one of its
dependencies could not be resolved: Failure to find
com.github.maven-nar:nar-maven-plugin:jar:3.0.0-rc-3-SNAPSHOT in
http://mvnplugins.fusesource.org/repo/release was cached in the local
repository, resolution will not be reattempted until the update interval
of mvnplugins.fusesource.org has elapsed or updates are forced -> [Help 2]

Best regards
Ulli

_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel

img.pgm (87K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [VIGRA] Avian VM and Bio-Formats

Mark Hiner-2
Hi Ullrich,

 I found this issue a while ago on my Windows 8 (64-bit) laptop, but stopped looking at it after a brief investigation, since the test was passing on our Win7 VM (and every other system I've tried it on).

 Anyway, Curtis and I are trying to reproduce on other systems right now to figure out what's going on.

 Which Java version are you using?

The issue can be found here:
https://github.com/scifio/scifio/issues/79

Thanks for bringing it to our attention!

- Mark


On Thu, Dec 5, 2013 at 12:15 PM, Ullrich Koethe <[hidden email]> wrote:
Hi Johannes and Tobias,

following your instructions, I now installed all dependencies on Linux (64-bit Ubuntu, gcc 4.7.3). Here is what I got:

In scifio, maven compiles, but then complains

   Failed tests:   testDefaultEnabled(io.scif.filters.utests.FilterTest)

In vigra-imglib2 (branch 'wip'), 'mvn install' compiles and produces a number of compiler warnings which seem to be uncritical on first glance, but are confusingly flagged as "[ERROR]" in the maven output.

When I finally run './avian-run.sh', I get the following output

java.io.EOFException
  at java.util.zip.InflaterInputStream.read (line 54)
  at java.util.zip.ZipFile$1.read (line 120)
  at java.util.zip.ZipFile$1.read (line 114)
  at java.util.zip.InflaterInputStream.read (line 39)
  at java.util.zip.ZipFile$1.read (line 106)
  at java.util.Properties$InputStreamParser.readCharacter (line 192)
  at java.util.Properties$Parser.parse (line 106)
  at java.util.Properties.load (line 21)
  at net.imglib2.vigra.NarHelper.loadLibrary (line 41)
  at net.imglib2.vigra.VigraImg3DUnsignedByte.<clinit> (line 23)
  at net.imglib2.vigra.VigraImgFactory3DUnsignedByte.create (line 19)
  at net.imglib2.vigra.VigraImgFactory3DUnsignedByte.create (line 14)
  at io.scif.img.ImgOpener.openImg (line 301)
  at io.scif.img.ImgOpener.openImg (line 217)
  at io.scif.img.ImgOpener.openImg (line 200)
  at Example.main (line 34)
  at Example.main (line 22)
java.lang.ExceptionInInitializerError
  at net.imglib2.vigra.VigraImgFactory3DUnsignedByte.create (line 19)
  at net.imglib2.vigra.VigraImgFactory3DUnsignedByte.create (line 14)
  at io.scif.img.ImgOpener.openImg (line 301)
  at io.scif.img.ImgOpener.openImg (line 217)
  at io.scif.img.ImgOpener.openImg (line 200)
  at Example.main (line 34)
  at Example.main (line 22)
caused by: java.lang.UnsatisfiedLinkError: Could not find native library
  at net.imglib2.vigra.NarHelper.loadLibrary (line 78)
  at net.imglib2.vigra.VigraImg3DUnsignedByte.<clinit> (line 23)
  at net.imglib2.vigra.VigraImgFactory3DUnsignedByte.create (line 19)
  at net.imglib2.vigra.VigraImgFactory3DUnsignedByte.create (line 14)
  at io.scif.img.ImgOpener.openImg (line 301)
  at io.scif.img.ImgOpener.openImg (line 217)
  at io.scif.img.ImgOpener.openImg (line 200)
  at Example.main (line 34)
  at Example.main (line 22)

No image is created. The input image I used is attached.

When I try to compile Tobias' code (branch 'buffer'), I get

[WARNING] The POM for com.github.maven-nar:nar-maven-plugin:jar:3.0.0-rc-3-SNAPSHOT is missing, no dependency information available
[ERROR] The build could not read 1 project -> [Help 1]
[ERROR]
[ERROR]   The project net.imglib2.vigra:vigra-imglib2:1.0.0-SNAPSHOT (/home/ukoethe/src/vigra-imglib2/pom.xml) has 2 errors
[ERROR]     Unresolveable build extension: Plugin com.github.maven-nar:nar-maven-plugin:3.0.0-rc-3-SNAPSHOT or one of its dependencies could not be resolved: Failure to find com.github.maven-nar:nar-maven-plugin:jar:3.0.0-rc-3-SNAPSHOT in http://mvnplugins.fusesource.org/repo/release was cached in the local repository, resolution will not be reattempted until the update interval of mvnplugins.fusesource.org has elapsed or updates are forced -> [Help 2]

Best regards
Ulli

_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel



_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel
Reply | Threaded
Open this post in threaded view
|

Re: [VIGRA] Avian VM and Bio-Formats

Tobias Pietzsch
In reply to this post by Ullrich Koethe
Hi Ulli,

> When I try to compile Tobias' code (branch 'buffer'), I get
>
> [WARNING] The POM for com.github.maven-nar:nar-maven-plugin:jar:3.0.0-rc-3-SNAPSHOT is missing, no dependency information available
> [ERROR] The build could not read 1 project -> [Help 1]


my bad, I set a version of the nar-maven-plugin that cannot be obtained from the public maven repository but must be build locally.
I reverted to version 3.0.0-rc-2. It should work now. Can you try again?
best regards,
Tobias

On Dec 5, 2013, at 7:15 PM, Ullrich Koethe <[hidden email]> wrote:

> Hi Johannes and Tobias,
>
> following your instructions, I now installed all dependencies on Linux (64-bit Ubuntu, gcc 4.7.3). Here is what I got:
>
> In scifio, maven compiles, but then complains
>
>   Failed tests:   testDefaultEnabled(io.scif.filters.utests.FilterTest)
>
> In vigra-imglib2 (branch 'wip'), 'mvn install' compiles and produces a number of compiler warnings which seem to be uncritical on first glance, but are confusingly flagged as "[ERROR]" in the maven output.
>
> When I finally run './avian-run.sh', I get the following output
>
> java.io.EOFException
>  at java.util.zip.InflaterInputStream.read (line 54)
>  at java.util.zip.ZipFile$1.read (line 120)
>  at java.util.zip.ZipFile$1.read (line 114)
>  at java.util.zip.InflaterInputStream.read (line 39)
>  at java.util.zip.ZipFile$1.read (line 106)
>  at java.util.Properties$InputStreamParser.readCharacter (line 192)
>  at java.util.Properties$Parser.parse (line 106)
>  at java.util.Properties.load (line 21)
>  at net.imglib2.vigra.NarHelper.loadLibrary (line 41)
>  at net.imglib2.vigra.VigraImg3DUnsignedByte.<clinit> (line 23)
>  at net.imglib2.vigra.VigraImgFactory3DUnsignedByte.create (line 19)
>  at net.imglib2.vigra.VigraImgFactory3DUnsignedByte.create (line 14)
>  at io.scif.img.ImgOpener.openImg (line 301)
>  at io.scif.img.ImgOpener.openImg (line 217)
>  at io.scif.img.ImgOpener.openImg (line 200)
>  at Example.main (line 34)
>  at Example.main (line 22)
> java.lang.ExceptionInInitializerError
>  at net.imglib2.vigra.VigraImgFactory3DUnsignedByte.create (line 19)
>  at net.imglib2.vigra.VigraImgFactory3DUnsignedByte.create (line 14)
>  at io.scif.img.ImgOpener.openImg (line 301)
>  at io.scif.img.ImgOpener.openImg (line 217)
>  at io.scif.img.ImgOpener.openImg (line 200)
>  at Example.main (line 34)
>  at Example.main (line 22)
> caused by: java.lang.UnsatisfiedLinkError: Could not find native library
>  at net.imglib2.vigra.NarHelper.loadLibrary (line 78)
>  at net.imglib2.vigra.VigraImg3DUnsignedByte.<clinit> (line 23)
>  at net.imglib2.vigra.VigraImgFactory3DUnsignedByte.create (line 19)
>  at net.imglib2.vigra.VigraImgFactory3DUnsignedByte.create (line 14)
>  at io.scif.img.ImgOpener.openImg (line 301)
>  at io.scif.img.ImgOpener.openImg (line 217)
>  at io.scif.img.ImgOpener.openImg (line 200)
>  at Example.main (line 34)
>  at Example.main (line 22)
>
> No image is created. The input image I used is attached.
>
> When I try to compile Tobias' code (branch 'buffer'), I get
>
> [WARNING] The POM for com.github.maven-nar:nar-maven-plugin:jar:3.0.0-rc-3-SNAPSHOT is missing, no dependency information available
> [ERROR] The build could not read 1 project -> [Help 1]
> [ERROR]
> [ERROR]   The project net.imglib2.vigra:vigra-imglib2:1.0.0-SNAPSHOT (/home/ukoethe/src/vigra-imglib2/pom.xml) has 2 errors
> [ERROR]     Unresolveable build extension: Plugin com.github.maven-nar:nar-maven-plugin:3.0.0-rc-3-SNAPSHOT or one of its dependencies could not be resolved: Failure to find com.github.maven-nar:nar-maven-plugin:jar:3.0.0-rc-3-SNAPSHOT in http://mvnplugins.fusesource.org/repo/release was cached in the local repository, resolution will not be reattempted until the update interval of mvnplugins.fusesource.org has elapsed or updates are forced -> [Help 2]
>
> Best regards
> Ulli
> <img.pgm>

_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel

signature.asc (465 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [VIGRA] Avian VM and Bio-Formats

Mark Hiner
Hello again Ullrich,

 I believe the SCIFIO test failure is fixed on the latest master (commit 877bf5). Note to self: don't rely on annotations in src/test/java.

 Sorry for the inconvenience, but thanks again for bringing it up.

- Mark


On Thu, Dec 5, 2013 at 2:06 PM, Tobias Pietzsch <[hidden email]> wrote:
Hi Ulli,

> When I try to compile Tobias' code (branch 'buffer'), I get
>
> [WARNING] The POM for com.github.maven-nar:nar-maven-plugin:jar:3.0.0-rc-3-SNAPSHOT is missing, no dependency information available
> [ERROR] The build could not read 1 project -> [Help 1]


my bad, I set a version of the nar-maven-plugin that cannot be obtained from the public maven repository but must be build locally.
I reverted to version 3.0.0-rc-2. It should work now. Can you try again?
best regards,
Tobias

On Dec 5, 2013, at 7:15 PM, Ullrich Koethe <[hidden email]> wrote:

> Hi Johannes and Tobias,
>
> following your instructions, I now installed all dependencies on Linux (64-bit Ubuntu, gcc 4.7.3). Here is what I got:
>
> In scifio, maven compiles, but then complains
>
>   Failed tests:   testDefaultEnabled(io.scif.filters.utests.FilterTest)
>
> In vigra-imglib2 (branch 'wip'), 'mvn install' compiles and produces a number of compiler warnings which seem to be uncritical on first glance, but are confusingly flagged as "[ERROR]" in the maven output.
>
> When I finally run './avian-run.sh', I get the following output
>
> java.io.EOFException
>  at java.util.zip.InflaterInputStream.read (line 54)
>  at java.util.zip.ZipFile$1.read (line 120)
>  at java.util.zip.ZipFile$1.read (line 114)
>  at java.util.zip.InflaterInputStream.read (line 39)
>  at java.util.zip.ZipFile$1.read (line 106)
>  at java.util.Properties$InputStreamParser.readCharacter (line 192)
>  at java.util.Properties$Parser.parse (line 106)
>  at java.util.Properties.load (line 21)
>  at net.imglib2.vigra.NarHelper.loadLibrary (line 41)
>  at net.imglib2.vigra.VigraImg3DUnsignedByte.<clinit> (line 23)
>  at net.imglib2.vigra.VigraImgFactory3DUnsignedByte.create (line 19)
>  at net.imglib2.vigra.VigraImgFactory3DUnsignedByte.create (line 14)
>  at io.scif.img.ImgOpener.openImg (line 301)
>  at io.scif.img.ImgOpener.openImg (line 217)
>  at io.scif.img.ImgOpener.openImg (line 200)
>  at Example.main (line 34)
>  at Example.main (line 22)
> java.lang.ExceptionInInitializerError
>  at net.imglib2.vigra.VigraImgFactory3DUnsignedByte.create (line 19)
>  at net.imglib2.vigra.VigraImgFactory3DUnsignedByte.create (line 14)
>  at io.scif.img.ImgOpener.openImg (line 301)
>  at io.scif.img.ImgOpener.openImg (line 217)
>  at io.scif.img.ImgOpener.openImg (line 200)
>  at Example.main (line 34)
>  at Example.main (line 22)
> caused by: java.lang.UnsatisfiedLinkError: Could not find native library
>  at net.imglib2.vigra.NarHelper.loadLibrary (line 78)
>  at net.imglib2.vigra.VigraImg3DUnsignedByte.<clinit> (line 23)
>  at net.imglib2.vigra.VigraImgFactory3DUnsignedByte.create (line 19)
>  at net.imglib2.vigra.VigraImgFactory3DUnsignedByte.create (line 14)
>  at io.scif.img.ImgOpener.openImg (line 301)
>  at io.scif.img.ImgOpener.openImg (line 217)
>  at io.scif.img.ImgOpener.openImg (line 200)
>  at Example.main (line 34)
>  at Example.main (line 22)
>
> No image is created. The input image I used is attached.
>
> When I try to compile Tobias' code (branch 'buffer'), I get
>
> [WARNING] The POM for com.github.maven-nar:nar-maven-plugin:jar:3.0.0-rc-3-SNAPSHOT is missing, no dependency information available
> [ERROR] The build could not read 1 project -> [Help 1]
> [ERROR]
> [ERROR]   The project net.imglib2.vigra:vigra-imglib2:1.0.0-SNAPSHOT (/home/ukoethe/src/vigra-imglib2/pom.xml) has 2 errors
> [ERROR]     Unresolveable build extension: Plugin com.github.maven-nar:nar-maven-plugin:3.0.0-rc-3-SNAPSHOT or one of its dependencies could not be resolved: Failure to find com.github.maven-nar:nar-maven-plugin:jar:3.0.0-rc-3-SNAPSHOT in http://mvnplugins.fusesource.org/repo/release was cached in the local repository, resolution will not be reattempted until the update interval of mvnplugins.fusesource.org has elapsed or updates are forced -> [Help 2]
>
> Best regards
> Ulli
> <img.pgm>


_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel



_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel
Reply | Threaded
Open this post in threaded view
|

Re: [VIGRA] Avian VM and Bio-Formats

dscho
Administrator
In reply to this post by Ullrich Koethe
Hi Ulli,

On Thu, 5 Dec 2013, Ullrich Koethe wrote:

> following your instructions, I now installed all dependencies on Linux
> (64-bit Ubuntu, gcc 4.7.3). Here is what I got:
>
> In scifio, maven compiles, but then complains
>
>    Failed tests:   testDefaultEnabled(io.scif.filters.utests.FilterTest)

Hopefully you will not need to compile SCIFIO yourself anymore soon (I
require https://github.com/scifio/scifio/pull/98 or something similar to
be merged for that).

> In vigra-imglib2 (branch 'wip'), 'mvn install' compiles and produces a
> number of compiler warnings which seem to be uncritical on first glance,
> but are confusingly flagged as "[ERROR]" in the maven output.

Which ones? (Please just paste such errors when you encounter them, of
course I could reproduce, if only I had more time!)

> When I finally run './avian-run.sh', I get the following output
>
> java.io.EOFException
>   at java.util.zip.InflaterInputStream.read (line 54)
>   at java.util.zip.ZipFile$1.read (line 120)
>   at java.util.zip.ZipFile$1.read (line 114)
>   at java.util.zip.InflaterInputStream.read (line 39)
>   at java.util.zip.ZipFile$1.read (line 106)
>   at java.util.Properties$InputStreamParser.readCharacter (line 192)
>   at java.util.Properties$Parser.parse (line 106)
>   at java.util.Properties.load (line 21)
>   at net.imglib2.vigra.NarHelper.loadLibrary (line 41)
>   at net.imglib2.vigra.VigraImg3DUnsignedByte.<clinit> (line 23)
>   at net.imglib2.vigra.VigraImgFactory3DUnsignedByte.create (line 19)
>   at net.imglib2.vigra.VigraImgFactory3DUnsignedByte.create (line 14)
>   at io.scif.img.ImgOpener.openImg (line 301)
>   at io.scif.img.ImgOpener.openImg (line 217)
>   at io.scif.img.ImgOpener.openImg (line 200)
>   at Example.main (line 34)
>   at Example.main (line 22)
> java.lang.ExceptionInInitializerError
>   at net.imglib2.vigra.VigraImgFactory3DUnsignedByte.create (line 19)
>   at net.imglib2.vigra.VigraImgFactory3DUnsignedByte.create (line 14)
>   at io.scif.img.ImgOpener.openImg (line 301)
>   at io.scif.img.ImgOpener.openImg (line 217)
>   at io.scif.img.ImgOpener.openImg (line 200)
>   at Example.main (line 34)
>   at Example.main (line 22)
> caused by: java.lang.UnsatisfiedLinkError: Could not find native library

I will make that error message more informative. Thanks for testing.

Hopefully I will be able to set aside time to work on this project next
week.

Ciao,
Dscho

_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel
12