cython error unsupported operand type(s) for -: 'list' and 'int' - cython

I have the following function in cython (run from Jupyter notebooks)
##
%%cython
cimport numpy as np
cimport cython
import numpy as np
#cython.boundscheck(False)
#cython.wraparound(False)
def Variance_Filter_3D(float[:, :, :] image, kernel = 30):
cdef double min_var = 10000
cdef list min_var_coord = [0,0,0]
cdef Py_ssize_t[32] z,y,x = image.shape
cdef np.ndarray[np.int32_t, ndim=3] window = np.zeros(shape=(kernel,kernel,kernel), dtype=np.int32)
for i in np.arange(0,(x-kernel),1):
for j in np.arange(0,(y-kernel),1):
for k in np.arange(0,(z-kernel),1):
window = image[k:k+kernel,j:j+kernel,i:i+kernel]
var = np.var(window)
if var < min_var:
min_var = var
min_var_coord = [k,j,i]
print(min_var_coord)
return min_var,min_var_coord
When I call the function, I get the following error:
Variance_Filter_3D(fet_arr)
>>
Input In [136], in <cell line: 1>()
----> 1 Variance_Filter_3D(fet_arr)
File _cython_magic_adb8c2575881fd3a5d05f7bfdf76a7fa.pyx:13, in _cython_magic_adb8c2575881fd3a5d05f7bfdf76a7fa.Variance_Filter_3D()
TypeError: unsupported operand type(s) for -: 'list' and 'int'
However, the only list I have is min_var_coord. The only operation I execute on it is reassigning it's values. I'm not sure how else to do this in cython?
Any help would be appreciated.

I think that
cdef Py_ssize_t[32] z,y,x = image.shape
might not be doing what you expect it to
The following works for me:
%%cython
cimport numpy as np
cimport cython
import numpy as np
#cython.boundscheck(False)
#cython.wraparound(False)
def Variance_Filter_3D(double[:, :, :] image, kernel = 30):
cdef double min_var = 10000
cdef list min_var_coord = [0,0,0]
cdef Py_ssize_t z = image.shape[0]
cdef Py_ssize_t y = image.shape[1]
cdef Py_ssize_t x = image.shape[2]
cdef np.ndarray[np.int32_t, ndim=3] window = np.zeros(shape=(kernel,kernel,kernel), dtype=np.int32)
for i in np.arange(0,(x-kernel),1):
for j in np.arange(0,(y-kernel),1):
for k in np.arange(0,(z-kernel),1):
window[:] = image[k:k+kernel,j:j+kernel,i:i+kernel]
var = np.var(window)
if var < min_var:
min_var = var
min_var_coord = [k,j,i]
print(min_var_coord)
return min_var,min_var_coord
image = np.random.randn(100, 100, 100)
Variance_Filter_3D(image)

Related

How to create a vector of vector when I'm defining IO

I'm trying to define Vector of Vector for my IO, but I'm getting an error from the chisel saying:
vec element 'Vec(chisel3.util.DecoupledIO#2b57)' must be hardware, not a bare Chisel type
The code which I've written is like the following:
//Module's argument
,val ArgsOut: Array[Int]
...
...
val Args = for (i <- 0 until ArgsOut.length) yield {
val arg = Vec(ArgsOut(i), Decoupled(UInt()))
arg
}
val outputArg = Vec(Args)
Some things to consider
IO ports, i.e. members of the IO Bundle, must be chisel hardware constructs, Args is a scala Vector type, it needs to be chisel Vec
All elements of a Vec must be the same size, mostly a consequence of the need to be able to index elements of the Vec. You have each element of Args as a Vec whos's length is determined by some the elements of ArgsOut. Vec(n, type) will not
Do really mean to have a 2D Vec(Vec( of decoupled IO's?
Your UInt in the Decoupled has an unknown width. This is not strictly speaking an error, because Firrtl can infer the width in most situations. But again this can be a problem for the requirement that a Vec's element are all the same length. Inferred widths in IOs should be used cautiously.
I was able to construct at IOBundle like this
val io = IO(new Bundle {
val args = Vec(ArgsOut.length, Vec(ArgsOut(0), Decoupled(UInt(18.W))))
val outputArg = Flipped(args)
})
Which compiles but may not quite be what you had in mind. I was able to connect the io's using
io.outputArg <> io.args
If this doesn't seem to fit your use case, I need to know a bit more how you intend to use the fields and we should be able to figure out how to wire them up.
Here is an illustration of how to use a subclass of Record to manage a virtual array of Vectors of varying length. This example runs for me. It is not exactly the same as your examples. But I think it makes things clearer. This is for the use case where you do not need to access your Vecs via a UInt, but is for when you need to match a heterogenous mix of Vectors.
import chisel3._
import chisel3.iotesters.PeekPokeTester
import org.scalatest.{FreeSpec, Matchers}
import scala.collection.immutable.ListMap
final class VariableBundle(elts: (String, Vec[UInt])*) extends Record {
val elements = ListMap(elts map { case (field, elt) => field -> elt.chiselCloneType }: _*)
def apply(elt: String): Vec[UInt] = elements(elt)
override def cloneType = (new VecVecBundle(elements.toList: _*)).asInstanceOf[this.type]
}
class SeqIO(val sizes: Array[Int]) extends Module {
val io = IO(new VariableBundle(Seq.tabulate(sizes.length) { i =>
s"vec_in_$i" -> Input(Vec(sizes(i), UInt(8.W)))
} ++
Seq.tabulate(sizes.length) { i =>
s"vec_out_$i" -> Output(Vec(sizes(i), UInt(8.W)))
}:_*
)
)
for(i <- sizes.indices) {
io(s"vec_out_$i") := io(s"vec_in_$i")
}
}
class SeqIOTester(c: SeqIO) extends PeekPokeTester(c) {
for(i <- c.sizes.indices) {
for(j <- 0 until c.sizes(i)) {
poke(c.io(s"vec_in_$i")(j), j)
}
}
step(1)
for(i <- c.sizes.indices) {
for(j <- 0 until c.sizes(i)) {
expect(c.io(s"vec_out_$i")(j), j)
}
}
}
class SeqIOSpec extends FreeSpec with Matchers {
"illustrate how to build bundles that have vecs wrapping different sized vecs" in {
iotesters.Driver.execute(Array.empty[String], () => new SeqIO(Array(1, 2, 3, 4))) { c =>
new SeqIOTester(c)
} should be (true)
}
}
Let me write the actual code:
class LoopLatch(val NumInputs: Int,
val ArgsOut: Array[Int],
val ID: Int)
(implicit val p: Parameters) extends Module with CoreParams with UniformPrintfs {
val io = IO(new Bundle {
val inputArg = Vec(NumInputs, Flipped(Decoupled(new DataBundle())))
val Args = Vec(for (i <- 0 until ArgsOut.length) yield {
val arg = Vec(ArgsOut(i), Decoupled(new DataBundle()))
arg
})
DataBundle() is a custom data type which I have defined it in a separate file. What I really want to do is that. I want to pass an array to the module like ArgsOut and then build a vector of vector of Databundle and each subsequent vector has its own number of Databundle which comes from the input array.
The loopLatch module is a wrapper for other module, LiveInNode which I have designed. Actually the LoopLatch module only has a vector of this elements and then provide an IO for it.
Here is the actual code:
class LoopStart(val NumInputs: Int,
val ArgsOut: Array[Int],
val ID: Int)
(implicit val p: Parameters) extends Module with CoreParams with UniformPrintfs {
val io = IO(new Bundle {
val inputArg = Vec(NumInputs, Flipped(Decoupled(new DataBundle())))
val Args = Vec(ArgsOut.length, Vec(ArgsOut(0), Decoupled(new DataBundle())))
val Out = new VecVecBundle(
Seq("inputArg" -> Vec(NumInputs, Flipped(Decoupled(new DataBundle())))) ++
(ArgsOut.indices).map { i =>
val arg = Vec(ArgsOut(i), Decoupled(new DataBundle()))
s"Args_$i" -> arg
}:_*
)
val pSignal = Vec(NumInputs, Flipped(Decoupled(Bool())))
val Finish = Vec(NumInputs, Flipped(Decoupled(new ControlBundle())))
}
)
val Args = for (i <- 0 until NumInputs) yield {
val arg = Module(new LiveInNode(NumOuts = 1, ID = i))
arg
}
//Iterating over each loopelement and connect them to the IO
for (i <- 0 until NumInputs) {
Args(i).io.InData <> io.inputArg(i)
Args(i).io.Finish <> io.Finish(i)
Args(i).io.pred <> io.pSignal(i)
}
for (i <- 0 until ArgsOut.length) {
io.Out("Args_0") <> Args(i).io.Out
}
}

Chisel3: False Combinational Loop in Fixed Priority Arbiter

The following code implements a n N-bit fixed priority arbiter.
import chisel3._
import chisel3.util._
class fixedPriorityArbiter(val n_reqs:Int = 4) extends Module {
val NO_OF_REQS = n_reqs
val io = IO(new Bundle {
val req = Input(UInt(NO_OF_REQS.W))
val grant = Output(UInt(NO_OF_REQS.W))
})
val higherPriReq = Wire(UInt(NO_OF_REQS.W))
higherPriReq := Cat((higherPriReq(NO_OF_REQS-2, 0) | io.req(NO_OF_REQS-2, 0)), UInt(0,1.W))
io.grant := io.req & ~higherPriReq
}
object main_obj extends App {
val DUT = () => new fixedPriorityArbiter()
val margs = Array("--compiler", "verilog")
chisel3.Driver.execute(args= margs, dut= DUT)
}
Inexistent combinatorial loops are reported for this code. The chisel source mirrors a Verilog implementation of the circuit below which doesn't report any combinatorial loops when synthesized in Synopsys Synplify.
The following compile error is reported by FIRRTL in Eclipse IDE on Windows without any Verilog source being generated by FIRRTL
FIRRTL does not support subword analysis so by using a UInt here you are creating what appears to be a combinational loop even though it actually isn't. To get around this, you can use aggregate types like Vecs to make it explicit to Firrtl that you are doing work on the individual bits. Here's an equivalent implementation using a Vec:
class FixedPriorityArbiter(val n_reqs: Int = 4) extends Module {
val NO_OF_REQS = n_reqs
val io = IO(new Bundle {
val req = Input(UInt(NO_OF_REQS.W))
val grant = Output(UInt(NO_OF_REQS.W))
})
val higherPriReq = Wire(Vec(NO_OF_REQS, Bool()))
// Vec implements scala.collection.Seq so you can use such operations as slice and map
val upperOr = higherPriReq.slice(0, NO_OF_REQS-1).zip(io.req(NO_OF_REQS-2, 0).toBools)
.map { case (l, r) => l | r }
higherPriReq := false.B +: upperOr
io.grant := io.req & ~higherPriReq.asUInt
}

Haskell REST Service with Scotty: Convert JSON back to to Data

I built a REST Service with Haskell and Scotty and have the following code:
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DeriveGeneric #-}
module Main where
import Data.Monoid ((<>))
import Data.Aeson (FromJSON, ToJSON)
import Data.Text.Lazy
import GHC.Generics
import Web.Scotty
data Point = Point { x :: Int, y :: Int } deriving (Generic, Show)
instance ToJSON Point
instance FromJSON Point
movePoint :: Point -> Int -> Int -> Point
movePoint (Point x y) dx dy = Point (x + dx) (y + dy)
data Rectangle = Rectangle { width :: Int, height :: Int, point :: Point } deriving (Generic, Show)
instance ToJSON Rectangle
instance FromJSON Rectangle
move :: Rectangle -> Int -> Int -> Rectangle
move r#(Rectangle {point = p}) dx dy = r { point = movePoint p dx dy }
main = do
putStrLn "Starting Server..."
scotty 3000 $ do
get "/rectangle/:id" $ do
id <- param "id"
text id
post "/rectangle" $ do
rectangle <- jsonData :: ActionM Rectangle
json rectangle
post "rectangle/move/:dx/:dy" $ do
dx <- param "dx"
dy <- param "dy"
rectangle <- jsonData :: ActionM Rectangle
move rectangle dx dy
json rectangle
When compiling i get this error:
Couldn't match expected type `Web.Scotty.Internal.Types.ActionT
Text IO a0'
with actual type `Rectangle'
In a stmt of a 'do' block: move rectangle dx dy
In the second argument of `($)', namely
`do { dx <- param "dx";
dy <- param "dy";
rectangle <- jsonData :: ActionM Rectangle;
move rectangle dx dy;
.... }'
What am i missing? I would like to call the "move" function and then send the moved rectangle back...

3? ways in scala to return a function from a function - 1 doesn't compile - don't understand why

I'm learning Scala. I have a Scala function which can return another function. I've come across 3 ways to do this in Scala (there may be more). In this particular code the 3rd option doesn't seem to compile but I've seen this technique used elsewhere but can't work out why it isn't working in this case.
In this fairly contrived example I have a function that takes an Int and returns a function that maps an Int to Boolean.
def intMapper1(elem: Int): Int => Boolean = {
def mapper(x: Int): Boolean =
x == elem
mapper
}
def intMapper2(elem: Int): Int => Boolean = (x: Int) => x == elem
def intMapper3(elem: Int)(x: Int) = x == elem
val m1 = intMapper1(2)
val m2 = intMapper2(4)
val m3 = intMapper3(6)
I get the compile error:
Error:(35, 22) missing arguments for method intMapper3 in object FunSets;
follow this method with `_' if you want to treat it as a partially applied function
val m3 = intMapper3(6)
^
The method def intMapper3(elem: Int)(x: Int) = x == elem has two parameter list, you are passing only one parameter(i.e. elem), the second parameter (x) is missing here. And intMapper3 is not a higher order function. It is not taking any function as argument and not returning a function. It is a normal method, taking two parameter list and returns a Boolean value.
You can derive a partially applied function from m3 as val m3 = intMapper3(6)_. That is what compiler telling you.
Your Method def intMapper3(elem: Int)(x: Int) = x == elem is a simple function in scala. it takes two parameters "elem" and "x" and computes the result.
It can be used as :
scala> intMapper3(2)(2)
res2: Boolean = true
scala> intMapper3(2)(1)
res3: Boolean = false
But if you pass only one argument it will show an error because intMapper3 requires two parameters.
"intMapper1" function can be called in these following ways:
scala> intMapper1(1)(2)
res0: Boolean = false
scala> intMapper1(1)(1)
res1: Boolean = true
In this case the output of "intMapper1" is a function that takes and argument of Int type and returns a boolean result.
scala> val m1 = intMapper1(2)
m1: Int => Boolean = <function1>
scala> m1(2)
res1: Boolean = true

When do I have to treat my methods as partially applied functions in Scala?

I noticed that when I'm working with functions that expect other functions as parameters, I can sometimes do this:
someFunction(firstParam,anotherFunction)
But other times, the compiler is giving me an error, telling me that I should write a function like this, in order for it to treat it as a partially applied function:
someFunction(firstParam,anotherFunction _)
For example, if I have this:
object Whatever {
def meth1(params:Array[Int]) = ...
def meth2(params:Array[Int]) = ...
}
import Whatever._
val callbacks = Array(meth1 _,meth2 _)
Why can't I have the code like the following:
val callbacks = Array(meth1,meth2)
Under what circumstances will the compiler tell me to add _?
The rule is actually simple: you have to write the _ whenever the compiler is not explicitly expecting a Function object.
Example in the REPL:
scala> def f(i: Int) = i
f: (i: Int)Int
scala> val g = f
<console>:6: error: missing arguments for method f in object $iw;
follow this method with `_' if you want to treat it as a partially applied function
val g = f
^
scala> val g: Int => Int = f
g: (Int) => Int = <function1>
In Scala a method is not a function. The compiler can convert a method implicitly in a function, but it need to know which kind. So either you use the _ to convert it explicitly or you can give some indications about which function type to use:
object Whatever {
def meth1(params:Array[Int]): Int = ...
def meth2(params:Array[Int]): Int = ...
}
import Whatever._
val callbacks = Array[ Array[Int] => Int ]( meth1, meth2 )
or:
val callbacks: Array[ Array[Int] => Int ] = Array( meth1, meth2 )
In addition to what Jean-Philippe Pellet said, you can use partially applied functions, when writing delegate classes:
class ThirdPartyAPI{
def f(a: Int, b: String, c: Int) = ...
// lots of other methods
}
// You want to hide all the unnecessary methods
class APIWrapper(r: ThirdPartyAPI) {
// instead of writing this
def f(a: Int, b: String, c: Int) = r.f(a, b, c)
// you can write this
def f(a: Int, b: String, c: Int) = r.f _
// or even this
def f = r.f _
}
EDIT added the def f = r.f _ part.