In Python we can do:
try:
import foo
# do stuff
except ImportError:
print("Consider installing package 'foo' for full functionality.")
Is it possible to catch a similar exception in Julia?
At this time Julia doesn't have an import exception mechanism, and you can't put using inside a try-catch block.
In the comments on this answer, the question is refined to really ask how to do conditional includes. Here is an example of how to do that:
# We are making a module that conditionally includes ImageView
module MyModule
# Optional plotting features using ImageView
# The view function is defined in ImageView
export view # Re-export ImageView.view (optional)
try
require("ImageView") # Will throw error if ImageView not installed
global view(args...) = Main.ImageView.view(args...)
catch
# Needs global to put it in the module scope, not the catch scope
global view(args...) = error("ImageView.jl required for drawing!")
# Alternatively, global view(args...) = nothing
end
# ....
end
Related
I'd like to automate as much as possible the instantiation of an ILA directly from the Chisel code. This means instantiating a module that looks like this:
i_ila my_ila(
.clk(clock),
.probe0(a_signal_to_monitor),
.probe1(another_signal_to_monitor),
// and so on
);
I'm planning to store the signals that I want to monitor in a list of UInt so that at the end of module elaboration I can generate the instantiation code above, which I will copy/paste in the final Verilog code (or write a Python script that does that automatically).
First, is there a better way of doing this, perhaps at the level of FIRRTL?
Even if I go with this semi-manual approach, I need to know what would be the name of the signals in the final Verilog, which is not necessarily the name of the UInt vals in the code (and which, besides, I don't know how to get automatically without having to retype the name of the variable as a string somewhere). How can I get them?
I'd like to provide a more complete example, but I wanted to make sure to at least write something up. This also needs to be fleshed out as a proper example/tutorial on the website.
FIRRTL has robust support for tracking names of signals across built-in and custom transformations. This is a case where the infrastructure is all there, but it's very much a power user API. In short, you can create FIRRTL Annotations that will track Targets. You can then emit custom metadata files or use the normal FIRRTL annotation file (try the CLI option -foaf / --output-annotation-file).
An example FIRRTL Annotation that has will emit a custom metadata file at the end of compilation:
// Example FIRRTL annotation with Custom serialization
// FIRRTL will track the name of this signal through compilation
case class MyMetadataAnno(target: ReferenceTarget)
extends SingleTargetAnnotation[ReferenceTarget]
with CustomFileEmission {
def duplicate(n: ReferenceTarget) = this.copy(n)
// API for serializing a custom metadata file
// Note that multiple of this annotation will collide which is an error, not handled in this example
protected def baseFileName(annotations: AnnotationSeq): String = "my_metadata"
protected def suffix: Option[String] = Some(".txt")
def getBytes: Iterable[Byte] =
s"Annotated signal: ${target.serialize}".getBytes
}
The case class declaration and duplicate method are enough to track a single signal through compilation. The CustomFileEmission and related baseFileName, suffix, and getBytes methods define how to serialize my custom metadata file. As mentioned in the comment, as implemented in this example we can only have 1 instance of this MyMetadataAnno or they will try to write the same file which is an error. This can be handled by customizing the filename based on the Target, or writing a FIRRTL transform to aggregate multiple of this annotation into a single annotation.
We then need a way to create this annotation in Chisel:
def markSignal[T <: Data](x: T): T = {
annotate(new ChiselAnnotation {
// We can't call .toTarget until end of Chisel elaboration
// .toFirrtl is called by Chisel at the end of elaboration
def toFirrtl = MyMetadataAnno(x.toTarget)
})
x
}
Now all we need to do is use this simple API in our Chisel
// Simple example with a marked signal
class Foo extends MultiIOModule {
val in = IO(Flipped(Decoupled(UInt(8.W))))
val out = IO(Decoupled(UInt(8.W)))
markSignal(out.valid)
out <> in
}
This will result in writing the file my_metadata.txt to the target directory with the contents:
Annotated signal: ~Foo|Foo>out_valid
Note that this is special FIRRTL target syntax saying that out_valid is the annotated signal that lives in module Foo.
Complete code in an executable example:
https://scastie.scala-lang.org/moEiIqZPTRCR5mLQNrV3zA
I have a module which builds up some levels of abstraction for a simulation I'd like to perform. Let's say the lowest level of abstraction is a node (which we build into systems, if we truncate this at two levels of abstraction), which is a subtype of an abstract type I define in the module. The nodes are updated with a user-defined update! function.
I want the user to be able to define a new node and update! function, but the update! function should be callable from the module's system_update! function. An example is provided below:
module test_pack
abstract type Node end
struct System{N<:Node}
nodes::Array{N,1}
end
function system_update!(s::System)
update!.(s.nodes)
end
export Node, System, system_update!
end
# import module
using Main.test_pack
# User-defined types and functions
mutable struct My_Node<:Node
state
end
function update!(n::My_Node)
n.state *= 2
end
# Define system of user defined nodes
sys = System([My_Node(1), My_Node(2)])
# Run the system
system_update!(sys)
Running this code gives
ERROR: LoadError: UndefVarError: update! not defined
However, if I move the definition of My_Node and update! to within the module and then export My_Node, the code executes and return the appropriate 2,4 output.
Is there a way I can enable the type of behavior I expect, where the user defines the type and update! function, but the module-defined System can call those functions?
One way of doing what you want would be to set things up in such a way that the update! function is defined by the module, and the code which defines the My_Node type (deriving from Node) also defines a specific method extending the update! function.
Here, since there is no default implementation for update! working on an argument of abstract type Node, an empty generic function can be defined to only mark the function as "belonging" to the module, without providing any implementation.
The implementation of the TestPack.update!(::My_Node) method explicitly extends this function, referring to it via a fully qualified name.
module TestPack
abstract type Node end
struct System{N<:Node}
nodes::Array{N,1}
end
function update! end
function system_update!(s::System)
update!.(s.nodes)
end
export Node, System, system_update!
end
# import module
using .TestPack
# User-defined types and functions
mutable struct My_Node<:Node
state
end
function TestPack.update!(n::My_Node)
n.state *= 2
end
sys = System([My_Node(1), My_Node(2)])
# Run the system
system_update!(sys)
The code above runs without problem and yields:
julia> sys
System{My_Node}(My_Node[My_Node(2), My_Node(4)])
As an aside, note that it is customary in Julia to use CamelCase notations for the name of modules; in the example above, I renamed your module to TestPack to follow this stylistic convention.
The module can also be referred to as using .TestPack instead of using Main.TestPack; this is called a relative module path.
I have a problem with basic module usage in Lua. I have one file "helloworld.lua" and a second file "main.lua". I would like to call a function from the first file inside the second file. But I am getting an error:
attempt to call field 'printText' (a nil value)
My actual code is below. Can someone tell me where the problem is?
helloworld.lua
local module = {}
function module.printText()
print("Hello world")
end
return module
main.lua
hello = require("helloworld")
hello.printText()
As mentioned in the comments, this is the right way to do it. This could be a problem if there is a conflicting helloworld module, or if you have a running lua state and are modifying the files without starting a new one.
require will only load the module passed with a string once. Check package.loaded["helloworld"]. You can set this to nil so that require will load the file again:
package.loaded["helloworld"] = nil
hello = require("helloworld") -- will load it for sure
EDIT I isolated a real minimal example which does not work (it is a part of more complex code); the culprit is the inputhook part after all:
def foo():
exec 'a=123' in globals()
from IPython.frontend.terminal.embed import InteractiveShellEmbed
ipshell=InteractiveShellEmbed()
ipshell()
# without inputhook, 'a' is found just fine
import IPython.lib.inputhook
IPython.lib.inputhook.enable_gui(gui='qt4')
foo()
Running with 0.12:
In [1]: a
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
/tmp/<ipython-input-1-60b725f10c9c> in <module>()
----> 1 a
NameError: name 'a' is not defined
What would be the way around?
The problem is due to this call to InteractiveShell.instance() in the qt integration, when called before IPython is initialized. If this is called before your embedded shell is created, then some assumptions are not met. The fix is to create your embedded shell object first, then you shouldn't have any issue. And you can retrieve the same object from anywhere else in your code by simply calling InteractiveShellEmbed.instance().
This version should work just fine, by creating the InteractiveShellEmbed instance first:
from IPython.frontend.terminal.embed import InteractiveShellEmbed
# create ipshell *before* calling enable_gui
# it is important that you use instance(), instead of the class
# constructor, so that it creates the global InteractiveShell singleton
ipshell = InteractiveShellEmbed.instance()
import IPython.lib.inputhook
IPython.lib.inputhook.enable_gui(gui='tk')
def foo():
# without inputhook, 'a' is found just fine
exec 'a=123' in globals()
# all calls to instance() will always return the same object
ipshell = InteractiveShellEmbed.instance()
ipshell()
foo()
I am trying to recreate SwiXML examples in JRuby. But the objects
created in JRuby never seem to be visible to SwiXML. Here is an example.
<frame size="200,200" title="Action Test">
<menubar>
<menu text="File">
<menuitem action="quit" accelerator="meta X" />
</menu>
</menubar>
<button action="quit" text="A Quit Button"
ToolTipText="This is a quit button." />
</frame>
The Java code from the SwiXML example is as follows:
public class ActionTest {
// Create an Action as a member variable
public Action quit = new AbstractAction() {
public void actionPerformed(ActionEvent evt) {
System.exit(0);
}
};
public ActionTest() throws Exception {
// set the Action's name
quit.putValue(Action.NAME, "Quit");
// build the GUI
new SwingEngine(this).render("ActionTest.xml")
.setVisible(true);
}
public static void main(String[] args) throws Exception {
new ActionTest();
}
}
I have created some JRuby code to correspond to this, but it seems as if
the #quit member is never seen. Also tried referencing other named
elements (not in this example):
require 'java'
require 'java/swixml.jar'
require 'java/jdom.jar'
include_class 'javax.swing.AbstractAction'
include_class 'javax.swing.Action'
include_class 'javax.swing.JButton'
class MyAction < AbstractAction
def actionPerformed(ae)
exit # puts "Clicked"
end
end
class Main < Object # Java::JavaLang::Object
def initialize
#quit = MyAction.new
#quit.putValue(Action.NAME, "Quit")
#f = java.io.File.new("sample.xml")
#se = org.swixml.SwingEngine.new(self).render(#f).setVisible(true)
end
end
Main.new
I've been struggling with integrating JRuby and SwiXml this week. I've come to the conclusion that you can't have SwiXml automatically bind your variables/actions from the XML. (I think this is because in Java the variables already exist, whereas in JRuby they are created 'on-the-fly', so SwiXml isn't sure what to do. That's my conclusion, anyway, after hours of digging through source code. JRuby is fairly new to me, so someone more advanced might be able to tell me why this won't work.)
The solution is to simply bind them manually in the JRuby code. It's actually fairly easy, since this is Ruby.
include Java
java_import 'org.swixml.SwingEngine'
class HelloWorld
def initialize
#swix = SwingEngine.new(self)
#swix.render("xml/helloworld.xml")
btn = #swix.find("submit")
btn.add_action_listener { |event| btn.text = 'Hi' }
end
def run
#swix.getRootComponent.setVisible(true)
end
end
See? Not too bad. In my case, "submit" is defined as the <button>'s ID attribute. So in my XML file I have <button text="Click Here" id="submit" /> Think of the find() method like a findById() method (if you're familiar with DOM manipulation through JavaScript...).
Note that since the add_action_listener takes a block, instance variables (ivars) can be included in the block (in other words, it acts like you would expect a Java anonymous class/block to work). There's other ways to implement/add an action listener. See this page: https://github.com/jruby/jruby/wiki/FAQs and scroll down to the section with a heading that says How can I implement a Java Interface using a Ruby Class?
Any element (as far as I know), can be retrieved by the SwingEngine class's find() method, as long as it's id is defined in the XML file.
A few minor things: include_class is now deprecated. You should use java_import instead. Also, your class that you're passing to SwingEngine does not need to inherit from Object or anything like that. JRuby is getting much better about making things more 'ruby-like' when integrating with Java.
Hope this helps. There's not much info out there about this stuff.
P.S. I found the info about 'manually binding' from this link: http://www.mail-archive.com/forum#carlsbadcubes.com/msg00062.html
I don't have your answer here (My Ruby isn't good enough) - but I having a similar issue trying to use Jython here; this example partially works (it picks up the 'quit' action).
from org.swixml.jsr296 import SwingApplication
from org.jdesktop.application import Application
from javax.swing import JButton, JFrame
class MyFrame(JFrame):
def __init__(self):
pass
class Tester(SwingApplication):
def __init__(self):
self.frame=MyFrame()
#self.frame=JFrame()
def startup(self):
print "Application Started"
self.render(self.frame,"frame.xml").show()
def shutdown(self):
print "Application Shutdown"
#def quit(self,evt):
# print "Over-ridden quit"
def action1(self,evt):
print "action1"
if __name__=='__main__':
Application.launch(Tester,None)
I added in a second button in the XML like this:
<button action="action1" text="action1" ToolTipText="action1" />
But the additional 'action1' method is never seen by swixml it seems, I get the following output when I start (and then quit) the application:
Application Started
SwixML 2.5
11-Nov-2011 12:10:38 org.swixml.XAction <init>
WARNING: error on Action initialization [org.python.proxies.__main__$MyFrame$1.action1()]
Application Shutdown
The interesting thing is, if you uncomment the 'def quit(self,evt)' method ; this method IS seen by SXIWML; and the behaviour of the 'quit' button changes from shutting down the Application to printing out a message.
So it seems that something about the way SWIXML reflects to look for actions fails when the action is purely defined in Jython (Method signatures?): but over-riding an existing action method does work.
It would be really nice to see what is going on here - I might log a new StackOverFlow question on this example and reference this one.
It would be great to be able to quickly throw together simple SWING apps using JRuby / Jython (etc) using SWIXMl; but a working template of how to do this is needed I think.
The other strange thing that I cannot explain ; if the line 'self.frame=MyFrame()' is changed to instantiate a standard JFrame: 'self.frame.JFrame()' - this results in classloader errors:
SwixML 2.5
11-Nov-2011 12:19:14 org.swixml.XAction <init>
WARNING: error on Action initialization [null ClassLoader]
11-Nov-2011 12:19:14 org.swixml.XAction <init>
WARNING: error on Action initialization [null ClassLoader]
11-Nov-2011 12:19:14 org.swixml.XAction <init>
WARNING: error on Action initialization [null ClassLoader]