Release of G'MIC 3.1

That is a good suggestion indeed. Thinking about that, I would propose a syntax like this:

foo :
  eval "
    func([arg]) = (
      res = 0; repeat (size(arg), k, res+=arg[k]^2);
      res;
    )
    a = func(1,2,3);             # OK
    b = func(1,2,3,4,5);         # OK
    V = [ 0,1,2,3,4,5,6,7 ];
    c = func(V);                 # OK
  "

where func must be defined with a single argument name between brackets to specify this is a vector of arguments.

1 Like

With all these changes, I’m also breaking the great tutorials by @grosgood :frowning:
I’ll take my time before releasing 3.1.0, just to be sure we don’t have regressions compared to 3.0.2.

There’s one more thing, you know how eval is single-threaded? What I want to do is to do multi-threaded looping within dynamic array, and based on the code inside said function, you can define what get inserted based on condition or removed. I have no idea what should be the function for this though or how should it be implemented.

The reason I want something like this is because in one of my challenge, it involves connecting lines from series of coordinates with distance condition. So, basically, you can do this with norm(point_coordinates-reference_coordinates) and da_insert() in a single-threaded fashion. But, doing it in a multi-threaded fashion would greatly speed it up.

This also would greatly speed up rep_dla too, and maybe even make it cleaner as I don’t have to generate string for multi-threaded processing. Just really wish I knew what should be the syntax for this.

I think this should be after 3.1 as the syntax is something we need to agree on.

My starting point is:

da_mt_process_push(reference_ind,condition,push_to_ind);
da_mt_process_remove(reference_ind,condition,remove_arr_from_ind);

mt stands for multi-threaded.

There is no ways multiple threads can insert elements in a dynamic array at the same time.
But you can still use a ‘critical’ section to do so : critical(da_insert(...)) .
Note then that the order of the inserted elements will be quite random.

So, there’s no way to split dynamic array for each thread, and then store the ones that meets condition per threads, and then combine them as a temporary set of array via single-thread method, and then push it? On the remove part, I think it’s possible to store the positions as an array, and then remove each array going from backward using the position array. That’s not possible either?

I’d like details on the critical part. I didn’t have much success with that.

Even if you could thread some parts, you’d probably lose any gains due to the overhead. At some point, you’re going to have to return to a single thread anyway (what critical does). Threading and dynamic array are pretty much two conflicting ideas…

1 Like

I do agree that in these cases, you will eventually have to resort to single-thread to perform manipulation of dynamic array.

Using multiple threads for dynamic array is possible. rep_dla does it with tricks involved. And there is some speed gains there.

I think I’ll just add this in the list of editing cimg.h to see if what I’m thinking in my head is possible.

Sometimes, it can be compatible, for instance when inserting an element is a quite rare event compared to the amount of computing needed to take the decision, or compared to the large amount of input data to process.
But in this case, critical() is the solution.

@Reptorian , it is also possible to create as many dynamic arrays as you have cores available (see pre-defined variable $_cpus), and use da_push(#t + offset) where t is the thread number and offset is the index of the first dynamic array.
If each thread fill its own dynamic array, then everything can be done in parallel without having to use critical().
Merging the information given by each array can be done later after all threads have finished.

I’ve done a first POC implementation, that allows variadic macros in the math parser :

foo :
  eval "
    func(arg...) = ( # Return sum of squared arguments
      ref([ arg ],X);
      sum(X^2);
    );

    print( func(4) );
    print( func(1,2,3) );
    print( func(1,2,3,4,5) );
  "

The new allowed syntax is then func(arg...) and arg is replaced inside the macro body by the “raw” list of arguments when the function is called.
A variadic macro can define only one argument name: func(arg1,arg2,args...) is not allowed.

Will try to build new packages with the feature tonight.

Is GIMP 2.99.10 compatible with GMIC 3.1 ?

As usual with core releases, you will have to update (as in replace) gmic-qt or whatever it is called on your OS.

1 Like

@hover
Bonjour,
I think it’s compatible and today’s version works well :o)
Win 64 : You can try samj Créations: G'MIC 3.1.0_pre220302 GMIC CLI , GMIC-QT , GMIC-GIMP-2.99

1 Like

[quote=“David_Tschumperle, post:88, topic:28221”]

  • local { ... }
  • for (cond) { ... }
  • foreach[selection] { ... }
  • repeat $N { ... }

A bit dangerous IMHO that the starting bracket can be avoided or multiplied, e.g. foreach[selection] { { { ... } works and is like a ,. I think it should better be some sort of begin...done, although begin still does not exist, hence some forced {...}.

I see it rather as a code decoration, to write code that is more readable. What would be the point of putting multiple { in the code ? The risk someone does this by accident is close to zero, so I don’t see any problem here.

For instance, in C, you can voluntary write ugly code if you wish, but almost nobody does this intentionally (except maybe for the code obfuscation contests).

1 Like

It probably is low risk, but I think @KaRo does have a point that braces matching is a common sense check. However, many code editors are braces aware - which is not something we had before - so I’m not too worried.

Something I have wondered about is a way to list commands which have multiple definitions. Often that’s intentional, but sometimes if you have a very large local file they can get lost by mistake. I’ll probably just make a shell script to do it in the mean time…

No worries, mate. Breakage in a good way. What is worse than no documentation? Wrong documentation.

2 Likes

Thank you for this!

@samj
I got message
Skipping potential plug-in ‘C:\GIMP 2.99\gmic_2.99_Win64\lisez-moi.txt’: plug-ins must be installed in subdirectories.
GIMP-Error: Unable to run plug-in “goat-exercise-lua.lua”
(C:\GIMP 2.99\lib\gimp\2.99\extensions\org.gimp.extension.goat-exercises\goat-exercise-lua.lua)

What do I have to do ?

I have some problem with l[] , an empty selection, seemingly since that new syntax vectors in functions.

[gmic] *** Error in ./cli_start/*if/ *** Command 'elif': Invalid argument 'l[]': Value accessor '[]': Array brackets used on non-vector variable 'l', in expression 'l[]'.

What is the content of your cli_start function?