Re: Generate doc comment from template?

2020-04-07 Thread solo989
You could do 


import macros
macro setDocComment(a : static[string]) : untyped =
  result = nnkCommentStmt.newTree()
  result.strVal = a
template foo(fn: untyped, doc: static[string]) =
  proc fn*(a: Foo) =
setDocComment(doc)
callfunc(fn, a)


Run

though it only immediately calls the macro setDoc if fn is a non generic proc

For a template or generic proc you could instead do 


import macros
macro foo(fn: untyped, doc: static[string]) =
  let
docString = nnkCommentStmt.newTree()
  docString.strVal = doc
  result = quote do:
proc `fn`*(a: Foo) =
  `docString`
  callfunc(`fn`, a)


Run


Generate doc comment from template?

2020-04-07 Thread spip
Is it possible to generate doc comments from templates? I have something like:


template foo(fn: untyped, doc: string) =
  template fn*(a: Foo) =
"## " & doc< I would like to inject doc comment here
callfunc(fn, a)


Run

> that is instantiated like this:


foo(bar, "Doc comment about bar")


Run


Re: UncheckedArray conversion

2020-04-07 Thread mratsim
I'm having a look at the moment, here are things that I find sketchy, note that 
I don't know the low-level VapourSynth API.

1\. You are not using `sampleType` or `bitsPerSample` in your example.

> From what I understood, those format fields are supposed to tell you what 
> your `ptr UncheckedArray[byte]` really is, if you are like in the C++ case, 
> it's a type-erased float pointer so you should use the same. Note that 
> float32 vs int might be very relevant as floating point vector operations are 
> way more optimized than integers (for matrix multiplication the ratio is 
> between 10x to 100x depending on SSE4.1 AVX2 / AVX512 and fused multiply add 
> support)

2\. Profiling shows that row0 access is a bottleneck

> 3\. Your iteration strategy seems problematic with repeated query to the API 
> to get the stride and pointer in vsframe.nim


proc getPtr(frame:ptr VSFrameRef, plane:cint):uint =
  ## Retrieves an `uint` rather than the pointer in order to perform 
pointer arithmetic with it
  cast[uint]( API.getWritePtr(frame, plane) )

proc stride(frame:ptr VSFrameRef, plane:cint):uint =
  API.getStride( frame, plane ).uint
#type
#  Row = ptr UncheckedArray[uint8]

proc `[]`*(frame:ptr VSFrameRef, plane:cint, row:uint):ptr 
UncheckedArray[uint8] =
  let ini:uint = frame.getPtr(plane)# Don't use other thing here
  let stride:uint = frame.getStride( plane )
  result = cast[ptr UncheckedArray[uint8]]( ini + row * stride )
  #assert(result != nil)

proc `[]`*(frame:ptr VSFrameRef, plane:cint, row:cint):ptr 
UncheckedArray[uint8] =
  let ini:uint = frame.getPtr(plane)# Don't use other thing here
  let stride:uint = frame.getStride( plane )
  result = cast[ptr UncheckedArray[uint8]]( ini + row.uint * stride )

proc `[]`*(frame:ptr VSFrameRef, plane:cint ):Plane =
  let ini = frame.getPtr(plane)
  let stride = frame.stride(plane)
  return Plane(ini:ini,stride:stride)

proc `[]`*(plane:Plane, row:cint):Row = #ptr UncheckedArray[uint8] =
  cast[ptr UncheckedArray[uint8]]( plane.ini + row.uint * plane.stride )


Run

Instead I suggest you use a scheme like this, only get the plane/query the API 
once and use the plane object that holds the metadata. This way the compiler 
can do inlining and loop hoisting on all those accesses.

The main issue with calling the VapourSynth API repeatedly is that all those 
function calls are just polluting your cache, requires the compiler to move the 
function parameter and result to and from the stack in an inner loop.


import ../src/vapoursynth

type Plane*[T: SomeNumber] = object
  # T depends on the frame format:
  # - sample_type (uint or float)
  # - bitsPerSample (8, 16, 32, 64)
  # The plane must be instantiated with
  # the proper uint8 ... 64, float32, float64
  data: ptr UncheckedArray[T]
  rows: int
  cols: int
  rowStride: int

func getPlane*(frame: ptr VSFrameRef, plane: int, T: 
typedesc[SomeInteger]): Plane[T] {.inline.} =
  ## Extract a plane
  result.data = cast[ptr UncheckedArray[T]](API.getWritePtr(frame, plane))
  result.rows = API.getFrameHeight(frame, plane)
  result.cols = API.getFrameWidth(frame, plane)
  result.rowStride = API.getStride(frame, plane)

template `[]`*[T](plane: Plane[T], row: int, col: int): T =
  plane.data[plane.row * plane.rowStride + plane.col]

template `[]=`*[T](plane: Plane[T], row: int, col: int, val: T) =
  plane.data[plane.row * plane.rowStride + plane.col] = val


Run

Regarding iteration strategy, your scheme is doing 3 times more memory access 
than a basic scheme for each row and each column (total 9x). Instead you should 
iterate once per row/column but in-place accumulate with `dst[dstIdx] += 
src[srcIdx] * filter[filterIdx]`

A starter point could be my basic convolution scheme in Laser 
[https://github.com/numforge/laser/blob/d1e6ae61/benchmarks/convolution/conv2d_direct_convolution.nim#L8-L73](https://github.com/numforge/laser/blob/d1e6ae61/benchmarks/convolution/conv2d_direct_convolution.nim#L8-L73)

It's for batch of images with potentially different plane numbers (called 
channels) between in and out (for example RGB --> Grayscale) but the iteration 
should be faster than yours:

Note that here I tracked the indices manually instead of using an intermediate 
`Plane` object but both methods should be the same with an optimizing compiler.


proc conv2d_direct*[T](
oim: var Tensor[T], # Output images
iim: Tensor[T], # Input images
ishape: TensorShape,# Shape of a single image
kernel: Tensor[T],  # filter kernel
kshape: KernelShape,# kernel shape (should be const)
padding: Padding,   # Padding (should be const)
strides: Strides# Strides (should be 

Re: Calling C function causes Sigsegv

2020-04-07 Thread shashlick
[Here's](http://nimgen.genotrance.com/nimbass/bass.html#BASS_Init,cint,DWORD,DWORD,DWORD,pointer)
 what BASS_Init looks like in the wrapper I made some years ago.


proc BASS_Init(device: cint; freq: DWORD; flags: DWORD; win: DWORD; dsguid: 
pointer): BOOL {...}{.
stdcall, importc: "BASS_Init", dynlib: dynlibbass.}


Run

Bass will need stdcall on Windows.

[https://github.com/genotrance/nimbass](https://github.com/genotrance/nimbass)


Re: Calling C function causes Sigsegv

2020-04-07 Thread treeform
I have wrapped plenty of C programs with Nim. My experience is that sig faults 
are caused by some thing simple ... like me not understanding the parameters.

An equivalent C program should crash with a sig fault there too. I bet 
BASS_Init(-1, 44100, 0, 0, nil) would crash in C as well. 


Re: UncheckedArray conversion

2020-04-07 Thread mantielero
**C++ stuff**

In order to test the C++ version:

  1. The code can be downloaded from 
[here](https://github.com/IFeelBloated/test_c_filters).
  2. I compiled it like:

$ g++ -Wall -O3 -shared -fPIC -I. -o libfilter.so GaussBlur.cxx




3\. Create a VapourSynth python filter like test_filter.vpy:


import vapoursynth as vs
core = vs.get_core()
core.std.LoadPlugin(path='./libfilter.so')
core.std.SetMaxCPU('none')
clip = core.std.BlankClip(format=vs.GRAYS, length=10, fpsnum=24000, 
fpsden=1001, keep=True)
clip = core.testc.GaussBlur(clip)
clip.set_output()

Run

4\. Testing:


$ vspipe test_filter.vpy /dev/null
Output 10 frames in 29.53 seconds (3386.27 fps)

So I am just getting 3386fps with the pure C++ version while I am getting 
1200fps with the Nim version.

I am not comparing apples to apples here:

  1. The Nim version uses int32 while the C++ version uses float.
  2. The Nim version is not using getFrameAsync, so it is not taking advantage 
of multithreading as discussed 
[here](https://github.com/vapoursynth/vapoursynth/issues/551#issuecomment-610473633).




Re: Nim programming book for kids

2020-04-07 Thread cantanima
What is your definition of a "kid"? I don't think 99.9% of kids will want to 
read it. Back in the 80s I tried to learn BASIC using the TRS-80 Color Computer 
manuals, which were considered very high quality at the time. I didn't succeed, 
in part because I couldn't be bothered to read the text. There was too much of 
it. This text has even more.

Last summer I had my older daughter (13) learn some Ada using a free online 
text I'd found. It was based on introducing ideas via a sequence of games. She 
did pretty well at it, but again, she didn't want to read it very much. She'd 
done some programming already with CSFirst, I think it's called, and that's a 
visual-oriented programming where you connect blocks. It did what she wanted: 
let her make animation with songs. Ada demanded too much of her just to get a 
simple text-based game.

On the other hand, there seems to be disagreement between title and text. In 
your text you seem to walk back the title, and suggest that this is only an 
introduction to programming using Nim, a book for beginners. That's another 
matter, I guess, but the headline is a bit misleading then.


Calling C function causes Sigsegv

2020-04-07 Thread Keithcat1
Hi, I'm trying to wrap a function of BASS sound library so I can learn how it 
works. My code is:


#{. emit: """#include "bass.h" """ .}
type dword {. importc: "DWORD" .} = uint32
type hwnd {. importc: "HWND" .} = uint32
type guid {. importc: "struct GUID" .}= object
type cbool {. importc: "BOOL" .} = uint32

proc BASS_Init* (device: cint, frequency, flags: cuint, win: hwnd, guid: ptr 
guid): cbool {. importc, cdecl, header: "bass.h" .} echo $int(BASS_Init(-1, 
44100, 0, 0, nil))

The function I'm wrapping is:


BOOL BASSDEF(BASS_Init)(int device, DWORD freq, DWORD flags, HWND win, 
const GUID *dsguid);

The reason I'm passing a nil pointer in the call to BASS_Init is because BASS 
will use the default value if it's null. Any hints?


Re: Nim programming book for kids

2020-04-07 Thread DanielSokil
Really grateful for this effort.


Re: Having problems with concepts that won't finish compiling

2020-04-07 Thread hugogranstrom
Ahh, yes that is more convenient then passing all the fields manually!

Thank you very much for the help :-D


Re: Having problems with concepts that won't finish compiling

2020-04-07 Thread mratsim
Yes, either you use a template or if your object carries all the required data 
your handler can just have the type


type Handler = proc(obj: MyObj) {.nimcall.}


Run


Re: Nim programming book for kids

2020-04-07 Thread spip
That's a very nice draft!

It starts basic and soft but then it jumps to _high-level_ notions. I don't 
know if average children will understand. For instance, in the _What is a 
Programming Language_ section, you could explain what a compiler is compared 
with other way to run code, and what is the compilation process. Or before 
starting with syntax in _Part II: The basics_ , perhaps introduce what is the 
general structure of a Nim program, single or multiple sources. Last example, 
is explaining pointers in _References and Pointers_ a notion that must be 
introduced to child-programmers? I would wait until _Part V: Advanced topics_ 
section to write about pointers...

A way to reach for children and beginners is to become quickly practical with 
examples or projects that they can try and extend on their computers. An 
example from Canada: 
[https://kidscodejeunesse.org/resources-for-educators](https://kidscodejeunesse.org/resources-for-educators).
 There must be other resources in other countries.

Is there a way to report more precise critics directly in the text and help you?


Re: Nim programming book for kids

2020-04-07 Thread leorize
This looks awesome.

I found a small issue while skiming the book: The example 
[here](http://ssalewski.de/nimprogramming.html#_input_and_output) don't need 
`import streams`, as `readLine` for `File` is in `io` and that one is imported 
by default.


Re: How do I pass Nim functions to C code as callbacks?

2020-04-07 Thread Keithcat1
OK, here is an example. logic.c: typedef int (adder)(int, int);

int run(adder fn, int a, int b) {
return fn(a, b);

}

logic.nim: {. compile: "logic.c" .} type adder {. importc .} = proc(a, b: 
cint): cint proc run(fn: adder, a, b: cint): cint {. importc, cdecl, nodecl .} 
proc add(a, b: cint): cint {. cdecl .} = a+b

var res=int(run(add, cint(100), cint(5125))) echo $res 


Re: How do I pass Nim functions to C code as callbacks?

2020-04-07 Thread Araq
Do not call `tearDownForeignThreadGc`.


Re: How do I pass Nim functions to C code as callbacks?

2020-04-07 Thread mantielero
I was just looking into this at this very moment and I am not sure if I use it 
well.

I was reading the [Thread 
coordination](https://nim-lang.org/docs/backends.html#memory-management-thread-coordination)
 section and this [forum entry](https://forum.nim-lang.org/t/3965#24714).

So I was implementing the following:


proc callback( userData: pointer,
f: ptr VSFrameRef,
n: cint,
a4: ptr VSNodeRef,
errorMsg: cstring) {.cdecl.} =
setupForeignThreadGc() #<-
API.freeFrame( f )
tearDownForeignThreadGc()#<-


proc NullAsync*(vsmap:ptr VSMap):int =
let node = getFirstNode(vsmap)
#API.freeMap(vsmap)
let vinfo = API.getVideoInfo(node) # video info pointer
let nframes = vinfo.numFrames
for i in 0..

Re: Having problems with concepts that won't finish compiling

2020-04-07 Thread hugogranstrom
Interesting! If I understand you correctly, I should make a SplineType type 
with a handler field to hold the eval proc. And then newHermiteSpline() would 
return a SplineType with handler set to the Hermite's eval proc. Have I 
understood you correctly then?

> How would you go about accessing the other variables of the Node in your 
> case? When you call the backward proc you would have to do something like 
> this right?:


node.backward(node.gate, node.payload)


Run

Could that be shortened down to something that resembles node.backward()? A 
template could work I'd guess, something along the lines of: 


template eval*[T](spline: SplineType[T], x: float): untyped =
  spline.handler(spline.X, spline.coeffs, x)
template eval*[T](spline: SplineType[T], x: openArray[float]): untyped =
  spline.handler_seq(spline.X, spline.coeffs, x)


Run

Could this work or did you have anything different in mind? :-)


Re: How do I pass Nim functions to C code as callbacks?

2020-04-07 Thread Araq

proc callback(arg: cint; arg2: cstring) {.cdecl.} =
  setupForeignThreadGc()
  # ... more code here


toC(callback)


Run


Re: UncheckedArray conversion

2020-04-07 Thread mantielero
**Nim stuff**

I have updated the [repository](https://github.com/mantielero/VapourSynth.nim). 
I have a local package.json with:


[
{
"name": "vapoursynth",
"url": "https://github.com/mantielero/VapourSynth.nim;,
"method": "git",
"tags": [
"video",
"vapoursynth"
],
"description": "Video processing based on Vapoursynth",
"license": "BSD"

}
]

With that you only need:


nimble install vapoursynth

The files to play with are 
[custom_filter.nim](https://github.com/mantielero/VapourSynth.nim/blob/master/test/custom_filter.nim)
 which makes use of 
[DrawFrame.nim](https://github.com/mantielero/VapourSynth.nim/blob/master/test/DrawFrame.nim).
 So you need these two files in the same folder and compile them like:


nim c -d:release -d:danger custom_filter

And in order to get the performance, just run it:


$ ./custom_filter

I will check how to do the same in C++. 


Re: ggplotnim - pretty native plots for us

2020-04-07 Thread Vindaar
Ok, so I just merged the arraymancer backend PR, which includes the PR for 
version v0.2.0.

v0.2.0 was mainly ridgeline plots and scale_*_reverse. Note that due to there 
is currently no recipe for a ridgeline plot. That will be added in the next few 
days. Also they are not as nice as they should be (essentially the top ridge 
doesn't change its height depending on the max values in the ridge if 
overflowing of ridges into one another is allowed).

scale_*_reverse just allows to reverse scales as the name suggests.

Aside from that a few smaller things were added (theme_void) and a few recipes 
that use geom_tile (annotated heatmap and plotting the periodic table).

I'm not entirely happy with the state of version v0.3.0 though, since the 
formula mechanism introduces several breaking changes. Arguably reading 
formulas is now clearer (see the beginning of the README and especially the 
recipes, since they all have to be compliant with the new mechanism!), but it 
still requires code to be changed.

I think the amount of breakage is probably not that large, since not that many 
people will have used formulas for things anyways yet. Also because the DF was 
discouraged before, since it was slow.

Simple formulas e.g. f{"hwy"} remains unchanged anyways, same as f{5} to set 
some constant value to an aesthetic. But for these things formulas were 
previously only required for numbers and not referring to columns, since the 
aes proc took string | FormulaNode. Now also numbers are actually supported, so 
to set some constant value, you can just do aes(width = 0.5) instead of 
aes(width = f{0.5}).

In any case, I wanted to get this PR off my chest, since it was way too large. 
I tried to avoid breaking changes as much as possibly by macro magic, but this 
issue:

[https://github.com/nim-lang/Nim/issues/13913](https://github.com/nim-lang/Nim/issues/13913)

was the nail in the coffin. So I just release it now.

Feel free to open issues, because I broke your code. :)


Re: Nim programming book for kids

2020-04-07 Thread juancarlospaco
PDF Download would be cool. Awesome work!. :D 


Nim programming book for kids

2020-04-07 Thread Stefan_Salewski
We had the discussion a few times in the last years -- if Nim is really a good 
start for kids and other people with absolutely no knowledge about CS.

Nim is fine for bright kids, sure.

But I hesitated generally to really recommend Nim for beginners, knowing that 
starting with the popular languages may be easier.

On the other hand -- generally Nim would be a fine beginner languages, with 
fine teaching materials and always an experienced Nim dev sitting beside you.

And when languages like C or Python are taught at school it seems to occur that 
that is sometimes done in a really bad and stupid fashion, and both of that 
languages are not perfect for teaching beginners.

The Nim situation has indeed improved in the last years, Nim community has 
grown a bit, and the number of tutorials has grown a lot.

Well, now there is one more. At least the first draft. Basically the result of 
maybe 10 days of work only. All was streamed directly from my head to the 
keyboard, so there may be some errors, due to the fine weather I have not done 
proofreading yet. But generally I am really satisfied with that start. Have no 
idea if I will work on it over the summer -- at least it is a start.

[http://ssalewski.de/nimprogramming.html](http://ssalewski.de/nimprogramming.html)


How do I pass Nim functions to C code as callbacks?

2020-04-07 Thread Keithcat1
H. I've looked around and I can't answer this. I want to be able to pass a Nim 
function / proc to C as a function pointer and get C to call it. I don't have a 
specific reason I want to do this, but I might need it soon. Thanks


Re: UncheckedArray conversion

2020-04-07 Thread mratsim
If you have instructions to reproduce the benchmark in Nim and C++ I can help.

I just need a repo to clone, the scripts to run and the dataset. I already have 
Vapoursynth working.

Ideally you have a profiler like Intel Instruments or Apple VTune to dive into 
assembly.

For example this is my approach in debugging performance issue: 
[https://github.com/nim-lang/Nim/issues/9514](https://github.com/nim-lang/Nim/issues/9514)

For memory bottlenecks it's a bit different, I use the roofline model as 
mentioned in my convolution optimization resources: 
[https://github.com/numforge/laser/blob/master/research/convolution_optimisation_resources.md#computational-complexity](https://github.com/numforge/laser/blob/master/research/convolution_optimisation_resources.md#computational-complexity)

For example I know that matrix multiplication and convolution can reach 90% of 
the peak CPU GFlop because their arithmetic intensity is high (i.e. you do over 
10 operations (add/mul) per byte) so if you don't reach that perf it's because 
you are moving bytes to much instead of computing with them.

The theoretical peak of your CPU is easy to compute:

  * single threaded:

> `CpuGhz * VectorWidth * InstrCycle * FlopInstr`

> for a CPU that supports AVX2 on float32 (so packing 8 float32) that can issue 
> 2 Fused-Multiply-Add per cycle at 3GHz we have

`3 (GHz) * 8 (packed float32 in AVX) * 2 (FMA per cycle) * 2 (FMA = 1 add + 1 
mul)` `= 96 GFlops`

  * multithreaded: Just multiply the single result by the number of cores. For 
example 10 cores would be 960 GFlops or 0.9 TFlops



And then the usual way to benchmark numerical algorithm is, you know the number 
of operations required by your algorithm, you divide that by the time spent to 
do them and you have your actual flops. And you compare your actual Flops with 
the theoretical peak. If you only reach 20% of the peak, you have a memory 
bottleneck and probably need to repack before processing to optimize cache 
usage, if not you need to look into SIMD vectorization, prefetching, ...

All of that is quite complex so what I can do is reach the naive C++ 
implementation performance.

Going beyond is something that I want to do but it's time-consuming and I feel 
that it would be better to spend my time on an image processing compiler 
similar to what's discussed here: 
[https://github.com/mratsim/Arraymancer/issues/347#issuecomment-459351890](https://github.com/mratsim/Arraymancer/issues/347#issuecomment-459351890)
 and with a proof of concept here:

  * 
[https://github.com/numforge/laser/tree/master/laser/lux_compiler](https://github.com/numforge/laser/tree/master/laser/lux_compiler)
  * 
[https://github.com/numforge/laser/tree/master/laser/lux_compiler/core](https://github.com/numforge/laser/tree/master/laser/lux_compiler/core)




Re: Help with hash sets needed

2020-04-07 Thread Pixeye
thanks guys, make sense!


Re: Help with hash sets needed

2020-04-07 Thread thenjip
Hello again !

A hash set is pretty much a hash table where the key and value types are the 
same.

So, checking for the existence of an element in a hash set will do the 
following :

  * Check for the existence of the key based on its hash.
  * Compare the associated value with the element.



This explains the results you had with that piece of code.


Re: Help with hash sets needed

2020-04-07 Thread cblake
Oh, and of course `a == b` must imply `hash(a) == hash(b)`.


Re: Help with hash sets needed

2020-04-07 Thread cblake
`hash` and `==` must agree. So, you need: 


proc `==`(a, b: ComponentPoint): bool =
  a.id == b.id


Run


Help with hash sets needed

2020-04-07 Thread Pixeye
Hi everyone : ) 


type
  ComponentPoint* = object
point: int
id: int

## I want to calculate hash by only one variable
proc hash(x: ComponentPoint): Hash =
  result = x.id

var pp = ComponentPoint()
pp.id = 1000
pp.point = 1000
var pp2 = ComponentPoint()
pp2.id = 1000
pp2.point = 0

var hset= initHashSet[ComponentPoint](512)
hset.incl(pp)

# I suppose it must be true as the hashes are equal, but it's false
assert pp2 in sss == true


Run

What's wrong with my code? ( Aside of primitive hash proc ) the thing is that 
is I set pp2.point to 1000 it gives the true. But Then I don't understand how 
things work under the hood. I thought that there is hash check and it must be 
valid.


Re: UncheckedArray conversion

2020-04-07 Thread mantielero
You are probably right. For me is the first time doing this sort of stuff. But 
the feeling that I have is that even small modifications in the algorithm 
(avoiding conversions as much as possible, for example) has a significant 
impact. I think that the reason is that I am interating on 100_000 frames of 
640x480 pixels.

For instance I have just reached 1200fps just by replacing how the rows numbers 
are calculated. Changing this:


template clamp(val:cint, max_val:cint):untyped =
   min( max(val, 0), max_val).uint
 
 .
for row1 in 0..(vsapi->getReadPtr(frame, plane));
auto dstp = reinterpret_cast(vsapi->getWritePtr(dst, plane));
auto h = vsapi->getFrameHeight(frame, plane);
auto w = vsapi->getFrameWidth(frame, plane);

auto gauss = [&](auto y, auto x) {

auto clamp = [&](auto val, auto bound) {
return std::min(std::max(val, 0), bound - 1);
};

auto above = srcp + clamp(y - 1, h) * w;
auto current = srcp + y * w;
auto below = srcp + clamp(y + 1, h) * w;

auto conv = above[clamp(x - 1, w)] + above[x] * 2 + above[clamp(x + 1, 
w)] +
current[clamp(x - 1, w)] * 2 + current[x] * 4 + current[clamp(x + 
1, w)] * 2 +
below[clamp(x - 1, w)] + below[x] * 2 + below[clamp(x + 1, w)];
return conv / 16;
};

for (auto y = 0; y < h; y++)
for (auto x = 0; x < w; x++)
(dstp + y * w)[x] = gauss(y, x);

Run

When you mention memory bottleneck, what do you mean? Where should I look at?

Thanks a lot


Re: UncheckedArray conversion

2020-04-07 Thread mratsim
Type conversion from uint8 to uint32 (or uint64) is technically free because 
registers have a size of 32-bit or 64-bit.

If anything it's less costly because at a low-level loading a 8-bit value 
requires movzb (mov to register and zero extend the byte) which has a slightly 
high latency than plain mov for uint32 and uint64.

The issue in your convolutions is memory bottleneck not compute.


Re: Having problems with concepts that won't finish compiling

2020-04-07 Thread mratsim
They are strongly discouraged.

The most resilient way is probably to store your proc/method in a field and do 
the dynamic dispatch yourself, see `Backward` here: 
[https://github.com/mratsim/Arraymancer/blob/2c89da87/src/autograd/autograd_common.nim#L85-L96](https://github.com/mratsim/Arraymancer/blob/2c89da87/src/autograd/autograd_common.nim#L85-L96)


`{}` syntax

2020-04-07 Thread cblake
Some people don't read the RFCs often while everyone working with some new 
prog.lang _loves_ syntax debates. :-) So, to get broader exposure, here: 
[https://github.com/nim-lang/RFCs/issues/207](https://github.com/nim-lang/RFCs/issues/207)


Re: UncheckedArray conversion

2020-04-07 Thread mantielero
This is part of a convolution filter. The result is in the same order of 
magnitude (uint8):


let value:int32  = r0[col0].int32 + r0[col1].int32 * 2 + r0[col2].int32 
+
   r1[col0].int32 * 2 + r1[col1].int32 * 4 + r1[col2].int32 
* 2 +
   r2[col0].int32 + r2[col1].int32 * 2 + r2[col2].int32
w1[col1] = (value  / 16.0).uint8

Run

I am looking how to improve performance-wise without entering into SIMD stuff 
(that I have never used by the way). I think that all those type conversions 
are killing the performance that I should achieve. 


Re: Is there non-broken serialization of complex types in nim?

2020-04-07 Thread b3liever
my 
[package]([https://github.com/b3liever/eminim](https://github.com/b3liever/eminim))
 mostly works


Re: Nim 1.2 is here

2020-04-07 Thread andrea
By the way, if Nim 1.2 requires a specific version of OpenSSL, this should be 
mentioned in 
[https://nim-lang.org/blog/2020/04/03/version-120-released.html](https://nim-lang.org/blog/2020/04/03/version-120-released.html)


Re: Is there non-broken serialization of complex types in nim?

2020-04-07 Thread readysloth
Forgive me, I spotted where i messed up! I made table with `new_table` 
function, which produces `ref Table`, but deserialized it as `Table`


Re: Is there non-broken serialization of complex types in nim?

2020-04-07 Thread cdome
I was using marshal quite successfully before. I also use samson 
[https://github.com/GULPF/samson](https://github.com/GULPF/samson).


Is there non-broken serialization of complex types in nim?

2020-04-07 Thread readysloth
Hi all.

I resently asked a [question](https://forum.nim-lang.org/t/6153) about how can 
i serialize type like `table[A, Hash_set[A]]` in nim. I used standard marhal 
package (and still want to stick to standard library), but i can't deserialize 
it after serialization.

When i try to, runtime crashes with 


/usr/lib/nim/pure/marshal.nim (333) to
/usr/lib/nim/pure/marshal.nim (266) loadAny
/usr/lib/nim/pure/marshal.nim (179) loadAny
/usr/lib/nim/pure/parsejson.nim (522) raiseParseErr
Error: unhandled exception: unknown file(1,1) Error: '{' expected for an 
object expected [JsonParsingError]


Run

But '{' is in place!

This is how i try to deserialize it: 


let deserialized = read_file("serialized.json").to[:Table[A, Hash_set[A]]


Run

BTW it doesn't work even for simple types like strings or ints :(


Re: Another state of generating Android APK thread...

2020-04-07 Thread GordonBGood
So here is my version of a [Maximally Factorized Sieve of Eratosthenes 
Benchmark as an Android 
app](https://github.com/GordonBGood/SieveofEratosthenesBenchmark) using an 
algorithm which is at least as fast as [Kim Walich's 
primesieve](https://github.com/kimwalisch/primesieve) on platforms on which 
they run in common up to the range of about 65 billion or so; it lacks the 
optimizations for more efficient sieving above this point in order to keep the 
code simpler and easier to understand. The required optimizations in order to 
extend the range to be the same are explained in the README file of the repo.

This work was done to show that one doesn't need to write code in C/C++ in 
order to be fast as per [a Quora question on prime 
sieving](https://www.quora.com/Can-you-write-a-C-program-that-finds-all-prime-numbers-from-2-to-2-billion-in-under-1-second-on-an-average-500-PC),
 but the Quorum Moderators didn't accept my 
[answer](https://www.quora.com/Can-you-write-a-C-program-that-finds-all-prime-numbers-from-2-to-2-billion-in-under-1-second-on-an-average-500-PC/answer/W-Gordon-Goodsman),
 likely because it uses Nim rather than C++ and shows that it doesn't take a 
€500 PC to perform the task of sieving to two billion in under one second but 
that it can be done on the least expensive of currently available smartphones 
and not using C++.

You can try this app by [downloading the zip file from 
here](https://github.com/GordonBGood/SieveofEratosthenesBenchmark/blob/master/app/release/SoEBenchmarkAndroid.zip),
 extracting the APK file, and side loading the APK file to an Android 
smartphone. The results should look something like the following:

> 


Re: UncheckedArray conversion

2020-04-07 Thread lucian
out of curiosity, isn't this prone to integer overflow or are you using value 
in fact as an uint32 ?


Re: Nim 1.2 is here

2020-04-07 Thread andrea
Isn't OpenSSL a system library? I am not sure how to update it without breaking 
a lot of things. I am using MacOS Sierra, this is probably why I am having 
trouble


template/generic instantiation of `initTable` from here - DateTime issue

2020-04-07 Thread SFR0815
Hi!

I am trying to do the following:


import tables, times

type
  Person* = object
name*: string
birth_date_time*: DateTime

proc newPerson(name: string,
   birth_date_time: DateTime): Person =
  return Person(name: name,
birth_date_time: birth_date_time)

var family = initTable[string, Person]()

let papa = newPerson(name = "Udo",
birth_date_time = initDateTime(1, mJan, 1980, 12, 0, 0, 
0, utc()))
family["Udo"] = papa
let mama = newPerson(name = "Ida",
birth_date_time = initDateTime(15, mApr, 1981, 12, 0, 
0, 0, utc()))
family["Ida"] = mama


echo "Papa: " & family["Udo"].name & " - born: " & 
$family["Udo"].birth_date_time
echo "Mama: " & family["Ida"].name & " - born: " & 
$family["Ida"].birth_date_time


Run

It works but y get

`d:\Documents\Jobs\WTS\InvReporting\Prototype 
II\Research\DateTimeInTable\objects.nim(13, 23) template/generic instantiation 
of `initTable` from here 
C:\ProgramData\nim\lib\pure\collections\tables.nim(308, 12) Warning: Cannot 
prove that 'result' is initialized. This will become a compile time error in 
the future. [ProveInit] d:\Documents\Jobs\WTS\InvReporting\Prototype 
II\Research\DateTimeInTable\objects.nim(17, 7) template/generic instantiation 
of `[]=` from here C:\ProgramData\nim\lib\pure\collections\tableimpl.nim(49, 
12) template/generic instantiation of `enlarge` from here 
C:\ProgramData\nim\lib\pure\collections\tables.nim(269, 10) Warning: Cannot 
prove that 'n' is initialized. This will become a compile time error in the 
future. [ProveInit] CC: objects.nim Hint: [Link] Hint: operation successful 
(42006 lines compiled; 1.295 sec total; 58.184MiB peakmem; Debug Build) 
[SuccessX] Hint: "d:\Documents\Jobs\WTS\InvReporting\Prototype 
II\Research\DateTimeInTable\objects.exe" [Exec] Papa: Udo - born: 
1980-01-01T12:00:00Z Mama: Ida - born: 1981-04-15T12:00:00Z`

This warning seems to be linked to the usage of DateTime as part of the object 
properties (It does not show up if e.g. using a string to represent the 
birth_date_time).

Should I just ignore the warning, or better try a workaround?

Background: I am building a solution that controls timing of data provision and 
time series type changes. Thus, a lot of DateTime type information flying 
around. Would rather prefer not messing around with strings all the time.