Re: Passing D reimplementation of C++ template as argument to a C++ function

2022-09-25 Thread Nicholas Wilson via Digitalmars-d-learn
On Saturday, 24 September 2022 at 07:04:34 UTC, Gregor Mückl 
wrote:

Hi!

I have a D template struct that reimplements a C++ class 
template with identical memory layout for a set of types that 
matter to me. Now, I want to use some C++ functions and classes 
that use these template instances, from D. For that, I want to 
purposefully alias the D and C++ types. However, with the C++ 
type being templated, I don't know how to name that type in a 
extern declaration in D.


[...]


```
extern(C++) extern(C++, class) struct Foo(T) {
   T a, b;
}

alias FooFloat = Foo!float;

extern(C++) void bar(FooFloat f);
```


Re: how to install the new dmd on Mac M1?

2022-08-25 Thread Nicholas Wilson via Digitalmars-d-learn

On Friday, 26 August 2022 at 00:34:30 UTC, MichaelBi wrote:
when using ldc2, has this error "ld: library not found for 
-lssl" after dub build --compiler=ldc2


So where is your ssl library located and how (if at all) are you 
telling the compiler/linker where to find it?




Re: Using LDC2 with --march=amdgcn

2022-07-26 Thread Nicholas Wilson via Digitalmars-d-learn

On Sunday, 24 July 2022 at 18:44:42 UTC, realhet wrote:

Hello,

I noticed that the LDC2 compiler has an architecture target 
called "AMD GCN".


Is there an example code which is in D and generates a working 
binary of a hello world kernel.


I tried it, and just failed at the very beginning: How can I 
specify __kernel and __global in D?


As mentioned by Johan, LDC in conjunction with dcompute is the 
closest thing.


You can use LDC to generate SPIR-V binaries with which I believe 
you should be able to use with the OpenCL implementation for that 
platform using dcompute to drive OpenCL.


Re: Obtain pointer from static array literal

2021-10-08 Thread Nicholas Wilson via Digitalmars-d-learn

On Friday, 8 October 2021 at 05:31:21 UTC, codic wrote:
On Friday, 8 October 2021 at 05:01:00 UTC, Nicholas Wilson 
wrote:
note that if the pointer is not escaped from the function 
(i.e. thing is void thing(scope int* abc)note the addition of 
scope) LDC will perform promotion of GC allocation to stack of 
the array literal even if you don't use .staticArray.


Interesting, I think you meant "even if you do use 
.staticArray";


No, I meant what I said. The array literal will cause a GC 
allocation, unless it is assigned to a static array of the same 
length or is inferred to be a static array. The latter happens 
when you pass it to `staticArray` because staticArray takes a 
static array as a parameter and the literal is inferred to be 
static array instead of a dynamic array, which is the default.



not sure why it would do that,


When you _don't_ use staticArray, what happens is LDC looks at 
the allocation and the fact that the allocated memory does not 
escape the passed to function (because the argument is annotated 
with `scope`) and turns the GC allocated dynamic array literal 
into a stack allocation (assuming that the array is of 
sufficiently small size as to not blow the stack).



but it doesn't  matter because my code is betterC


I guess the point is moot

and therefore nogc so it  *should* allocate it on the stack, I 
think


No, you can still try to use the GC in betterC but you will get a 
compile time error if you do so. Passing `-betterC` does not 
cause GC to stack promotion, it issues errors if you try to use 
GC (or any other feature that requires druntime like associative 
arrays or typeinfo).


Re: Obtain pointer from static array literal

2021-10-07 Thread Nicholas Wilson via Digitalmars-d-learn

On Friday, 8 October 2021 at 02:49:17 UTC, codic wrote:
I am working with a C API (XCB) which uses `void*` a lot to 
obtain parameter packs; these are very small and throwaway so I 
want them to be allocated to the stack.


CUDA has something similar that I have to deal with for 
dcompute[1]. The trick is that the parameter packs always have 
some sort of underlying structure to them and in D it is possible 
to exploit that structure at compile time to ensure that you 
don't break type safety. I can't give a more specific answer 
without some more concrete examples from XCB, but for CUDA the 
function signature of the kernel you are trying to launch 
dictates what goes into the parameter pack.


The best way is to generate (or write) wrapper functions that do 
this for you such that you can call `wrappedFunc(x,y,w,h)` and 
statically verify through its type signature that



uint[4] params=[x,y,width,height];
func(params.ptr);


is a valid call to func.


Of course, this is valid, but a bit painful:
```d
uint[4] params=[x,y,width,height];
func(params.ptr);
```
especially when you have lots of calls. now, this compiles:
```d
// (import std.array)
func([x,y,width,height].staticArray.ptr);
```
but is it well-formed? or is it UB because it is a rvalue and 
scope ends?


For simple types (i.e. ones with no destructor), like int, IIRC 
this is fine.
When you have a static array of objects that need to be 
destructed, then end of scope becomes important.



i.e. here is an example program, is it well formed?
```d
import core.stdc.stdio, std.array;

void thing(int* abc) {
  printf("%d\n", *abc);
}

extern(C) void main() {
  thing([1].staticArray.ptr);
}
```
At any rate, it runs fine consistently with ldc:
```
$ ldc2 test.d -fsanitize=address
$ ./test
1
```

I don't know if it is spec-compliant though, or if it is 
actually causing UB here and I don't notice it.


note that if the pointer is not escaped from the function (i.e. 
`thing` is `void thing(scope int* abc)`note the addition of 
`scope`) LDC will perform promotion of GC allocation to stack of 
the array literal even if you don't use `.staticArray`.


https://github.com/libmir/dcompute/blob/master/source/dcompute/driver/cuda/queue.d#L80-L92


Re: How can we view source code that has been generated (say via "static foreach") ?

2021-09-17 Thread Nicholas Wilson via Digitalmars-d-learn
On Thursday, 16 September 2021 at 04:54:21 UTC, james.p.leblanc 
wrote:
Thank you for your kind response.  Wow, at first the large 
output file
from a small test program was a bit surprising .., but actually 
it is

manageable to dig through to find the interesting bits.

So, this is quite useful!  Thanks again, now I am off to do 
some digging...


Best Regards,
James


Note that that will only give the expansions from string mixins, 
not from template mixins, templates and other things.




Re: yet another segfault - array out of bound is not caught by try catch

2021-09-17 Thread Nicholas Wilson via Digitalmars-d-learn

On Friday, 17 September 2021 at 11:10:33 UTC, seany wrote:

I have now this function, as a private member in a Class :
} catch (RangeError er) {


I can't remember if you can catch an index OOB error but try 
`catch (Throwable er)` will work if it is catchable at all and 
you can figure out what kind of Error you have by printing its 
name.


 "Attempt to take address of value not located in memory" ? I 
am not even calling / accessing a pointer. I am trying to 
extract a value outside an array bound.


`Type[]` arrays in D are effectively struct {size_t length; Type* 
ptr; } under the hood. Your problem is the array has no elements 
which is why trying to extract a value outside an array bound is 
an irrecoverable error.


with the bound checking operation in place, would the bound 
error be triggered before the attempt to take unavailable 
address error has a chance to trigger?


with a null array of zero length `arr`, `arr[0]` with bounds 
check enabled will fail the bounds check before it tries to 
dereference the pointer. if you try `arr.ptr[0]` to bypass the 
bounds checking (which is a very bad idea!) you will then try to 
load from an invalid memory address and crash.




Re: Now can build and run d on RISC-V arch?

2021-06-05 Thread Nicholas Wilson via Digitalmars-d-learn

On Sunday, 6 June 2021 at 04:14:20 UTC, lili wrote:
I want learn RISC-V and write a simple kernel on it using d. 
but can not find any support about RISC-V.


LDC can compile for riscv 32 and 64 bit.

https://github.com/ldc-developers/ldc/releases/tag/v1.26.0

use `-mtriple=riscv32` or `-mtriple=riscv32` as the arch for the 
triple. I'm not sure what you should put for the `os` and `env` 
fields of the triple. The vendor field can be left as `unknown`. 
Do a search for triples people use to target riscv and use that 
if the above doesn't work.


Re: Strange error

2021-03-23 Thread Nicholas Wilson via Digitalmars-d-learn

On Monday, 22 March 2021 at 07:52:14 UTC, MichaelJames wrote:


Tell me, did you manage to solve this problem?


https://github.com/dlang/dmd/pull/12300


synthesising instantiated template parameters and arguments

2020-10-27 Thread Nicholas Wilson via Digitalmars-d-learn

Given

template ScopeClass(C)
{
//...
}


where C is a, possibly templated, class I want the eponymous 
member of ScopeClass!(C) to have the same templatedness (both 
parameters and arguments)as C.

For a non-template C this is a simple as:

template ScopeClass(C)
{
class ScopeClass
{
 // implement members with compile time reflection
}
}

but for a templated C this is tricker as I can't use a template 
sequence parameter (...) unless C uses it in the same position 
(I'm trying to generate a mangle from it so it needs to be 
exact). Given


class A(T,int,args...) {}
alias C = A!(int, 0, float);

I need `ScopeClass!C` to be

template ScopeClass(C)
{
class Anon(T,int,args...) // name doesn't matter
{
 // implement members with compile time reflection
}

alias ScopeClass = Anon!(int, 0, float);
}

How do I do this?


Re: Two ways of receiving arrays on the C ABI

2020-10-19 Thread Nicholas Wilson via Digitalmars-d-learn

On Tuesday, 20 October 2020 at 00:16:48 UTC, Ali Çehreli wrote:
On the D side, both of the following extern(C) functions take 
the same arguments.


https://github.com/dlang/dmd/pull/8120

there are issues with structs. Not sure about length/ptr.




Re: Asserting that a base constructor is always called

2020-05-24 Thread Nicholas Wilson via Digitalmars-d-learn

On Sunday, 24 May 2020 at 06:38:46 UTC, Tim wrote:
Oh right. I mean it makes sense but I got confused when super() 
is valid syntax. Why would you need to call the super 
constructor when it's called automatically?


A base class with a constructor that has no args will 
automatically get called at the start of a child class if it is 
not explicitly called. You can call it yourself anywhere in an 
always executed branch of the constructor. As for why, if you 
wanted to do some logging before the base constructor was called.


You need to call the base class's constructor explicitly when it 
has arguments and there is no default constructor in the base 
class. This must be done in an always executed branch. This must 
be called or the compiler will issue an error.





Re: determine ldc version in static if or version?

2020-04-01 Thread Nicholas Wilson via Digitalmars-d-learn

On Wednesday, 1 April 2020 at 21:19:54 UTC, Adam D. Ruppe wrote:

I want to do like

static if(__LDC_VERSION == 1.19) {
  // declaration
}


All the tricks I know that I have tried so far give the dmd 
numbers. Perhaps I could use that to identify a particular 
version as a hack, but I specifically am curious about the ldc 
version because of a change they made there independently of D.


Is there something I don't know about?


https://github.com/ldc-developers/druntime/blob/ldc/src/ldc/intrinsics.di#L22-L34

 version (LDC_LLVM_309)  enum LLVM_version =  309;
else version (LDC_LLVM_400)  enum LLVM_version =  400;
else version (LDC_LLVM_500)  enum LLVM_version =  500;
else version (LDC_LLVM_600)  enum LLVM_version =  600;
else version (LDC_LLVM_700)  enum LLVM_version =  700;
else version (LDC_LLVM_701)  enum LLVM_version =  701;
else version (LDC_LLVM_800)  enum LLVM_version =  800;
else version (LDC_LLVM_900)  enum LLVM_version =  900;
else version (LDC_LLVM_1000) enum LLVM_version = 1000;
else version (LDC_LLVM_1100) enum LLVM_version = 1100;
else static assert(false, "LDC LLVM version not supported");

enum LLVM_atleast(int major) = (LLVM_version >= major * 100);


Re: No UFCS with nested functions?

2019-11-04 Thread Nicholas Wilson via Digitalmars-d-learn

On Monday, 4 November 2019 at 19:51:26 UTC, Tobias Pankrath wrote:
Why does the following not work? It works, if I move the 'prop' 
out of 'foo'.


---
struct S {
ubyte[12] bar;
}

bool foo (ref S s)
{
   static bool prop(const(ubyte)[] f) {
  return f.length > 1;
   }
return s.bar[].prop;
}
---

Thanks!


https://blog.thecybershadow.net/2015/04/28/the-amazing-template-that-does-nothing/

struct S {
ubyte[12] bar;
}

alias I(alias f) = f;

bool foo (ref S s)
{
   static bool prop(const(ubyte)[] f) {
  return f.length > 1;
   }
return s.bar[].I!prop;
}


Re: exceptions and optimization

2019-10-21 Thread Nicholas Wilson via Digitalmars-d-learn

On Monday, 21 October 2019 at 21:09:32 UTC, Peter Jacobs wrote:
On Monday, 21 October 2019 at 20:37:32 UTC, Nicholas Wilson 
wrote:


What kind of conditions are you wanting to throw exception on? 
infinities, NaNs, ill conditioning, something else?


As always the best way to check is to mark the function of 
interest, nothrow take a look at the disassembly and compare 
to without nothrow. You may also want to look to the 
optimisation summary that I _think_ you can get LDC to 
generate.


Our methods take a few short cuts and occasionally step over a 
stability boundary, so I guess that it may look like 
ill-conditioning.


The reason I asked that is to see what sort of action you take 
because there may be better architectures that you can use to 
handle that kind of change.


For example, you are integrating with some scheme and hit a 
region of high curvature and need to rollback and change scheme 
(to either a less coarse time step or better integrator). In 
which case it may be best to take a page out of databases and use 
a change-commit kind of approach to short circuit through your 
calculations and if at the end of your update loop a flag is set 
that says this update is invalid then retry with another scheme.



Thank you for the explanation and suggestions.




Re: contains method on immutable sorted array

2019-10-21 Thread Nicholas Wilson via Digitalmars-d-learn

On Monday, 21 October 2019 at 10:14:54 UTC, Andrey wrote:

Hello,
I have got a global constant immutable array:
immutable globalvalues = sort(cast(wstring[])["й", "ц", "ук", 
"н"]);


Somewhere in program I want to check an existance:

globalvalues.contains("ук"w).writeln;


But get an error:
Error: template std.range.SortedRange!(wstring[], "a < 
b").SortedRange.contains cannot deduce function from argument 
types !()(wstring) immutable, candidates are:

/dlang/ldc-1.17.0/bin/../import/std/range/package.d(10993):
std.range.SortedRange!(wstring[], "a < 
b").SortedRange.contains(V)(V value) if 
(isRandomAccessRange!Range)


Why I can't check?


pragma(msg,typeof(globalvalues));

gives immutable(SortedRange!(wstring[], "a < b"))

and

(cast(SortedRange!(wstring[], "a < 
b"))globalvalues).contains("ук"w).writeln;


works, so I guess contains doesn't work with immutable?
If you can do some more research into this and confirm it then, 
please file a bug report.


Re: exceptions and optimization

2019-10-21 Thread Nicholas Wilson via Digitalmars-d-learn

On Monday, 21 October 2019 at 20:12:19 UTC, Peter Jacobs wrote:
Toward the end of Walter's recent talk, D at 20, he says 
something to the effect that optimizations are disabled when 
exceptions can be thrown.  We have a compressible flow solver 
in which it is very convenient to be able to throw an exception 
from deep within the code and catch it at a relatively high 
level where we can partially recover and continue the 
calculation.  Because our calculations can run for days across 
hundreds of processors, we also care about letting the 
optimizer do its best. In what parts of our program would the 
optimizer be disabled because of the presence of the exception 
and its handling code?  How do we tell?


It really comes into effect if you use:

a) structs with destructors
b) scope(exit) and scope(failure)

as these need to be run, regardless of the return mode of the 
function i.e. normally or via an exception.


Also if the function is nothrow (possibly inferred because its a 
template, n.b. also that nothrow function can throw Errors as 
these are considered terminal) then you should also be fine. The 
effect of exceptions on optimisation effect logic heavy code a 
lot more that math heavy code.


What kind of conditions are you wanting to throw exception on? 
infinities, NaNs, ill conditioning, something else?


As always the best way to check is to mark the function of 
interest, nothrow take a look at the disassembly and compare to 
without nothrow. You may also want to look to the optimisation 
summary that I _think_ you can get LDC to generate.




Re: Is there a way to do the same thing in entry and return of a bunch of functions?

2019-09-17 Thread Nicholas Wilson via Digitalmars-d-learn
On Tuesday, 17 September 2019 at 17:11:09 UTC, Stefanos Baziotis 
wrote:
I think it's better to give a concrete example rather than 
explaining this vaguely.


-- The question --
Can we do better ? For one, I believe that because D does not 
have a preprocessor,
we have to do an actual declaration which would be somewhat 
more verbose.
Or do a mixin that does it. mixin can help as it can be more 
complicated
and also we can access local scope (although I don't think this 
is a good idea).


But in both cases, they're not totally invisible.

Can we do something like: func1, func2 and func3, when they 
enter do the X

and when they return, they do the Y.

Thanks,
Stefanos


I think a mixin that does

string LOG_SCOPE = q{
callDepth++;
scope(exit) callDepth--;
}

is probably the easiest. for bonus points

string LOG_SCOPE = q{
callDepth++;
debug_log(__FUNCTION__);// or __PRETTY_FUNTION__
scope(exit) callDepth--;
}

and the mixin(LOG_SCOPE);

I mean you _could_ do some UDA reflection to generate wrapping 
function that do the indentation, bit that is overkill.


Re: LDC asm for int128

2019-09-10 Thread Nicholas Wilson via Digitalmars-d-learn

On Tuesday, 10 September 2019 at 06:18:05 UTC, Newbie2019 wrote:
I want to translate this c code into d (build with ldc), so I 
can use -flto and inline with other code.


uint64_t _wymum(uint64_t A, uint64_t B){
__uint128_t r = A ;
r *= B;
return  (r>>64)^r;
}

Do i need ASM or is there a easy way to implement it ?


Easiest way is to use GFM's[1] 128bit integers.

[1]:http://code.dlang.org/packages/gfm


Re: Undefined reference - built from source DMD

2019-09-10 Thread Nicholas Wilson via Digitalmars-d-learn
On Tuesday, 10 September 2019 at 11:12:30 UTC, Stefanos Baziotis 
wrote:

I don't if this the right group to post this.

DMD built from source fails to link / find `main`. The error is:
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o: In function 
`_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
Error: linker exited with status 1

Does anyone know how this could have happened?


Is this you have built your own DMD and using it to compile a 
test program and you get that error, or you get that error trying 
to build DMD?


Re: Why is sformat and formattedWrite (appender) allocating GC mem here?

2019-08-31 Thread Nicholas Wilson via Digitalmars-d-learn

On Saturday, 31 August 2019 at 21:12:32 UTC, ag0aep6g wrote:

I've made a pull request to get rid of those allocations:
https://github.com/dlang/phobos/pull/7163


Merged.


Re: Shadertoy in Dcompute?

2019-08-21 Thread Nicholas Wilson via Digitalmars-d-learn

On Thursday, 22 August 2019 at 00:57:26 UTC, Bert wrote:
How hard would it be to do something like Shadertoy in Dcompute 
and would it be any faster?


I don't like the basics of Shadertoy, lots of nonsense to do 
basic stuff. E.g., to work with complex numbers one must 
essentially do everything manually.


Would there be any benefit using Dcompute(last time I tried it 
I couldn't get it to work).


DCompute is primarily for compute at the moment, and not 
graphics. It targets OpenCL and CUDA, not 
OpenGL/WebGL/Vulkan/DirectX. Thats not to say that you can't use 
it for computational graphics but you wouldn't be utilising the 
specialised hardware for the rendering pipeline, so it would 
probably be slower.


If you want to have a crack at it, I'd take a look at how to do 
graphics with OpenCL or CUDA and adapt what you can. I haven't 
tested OpenCL/OpenGL interop at all (with or without DCompute) 
but it is a thing.


Re: Wrong vtable for COM interfaces that don't inherit IUnknown

2019-07-15 Thread Nicholas Wilson via Digitalmars-d-learn

On Monday, 15 July 2019 at 22:01:25 UTC, KytoDragon wrote:
I am currently trying to write a XAudio2 backend and have come 
across the problem, that some of the interfaces for XAudio2's 
COM objects seem to be missing the first entry in their vtable. 
After reading the iterface article in the spec 
(https://dlang.org/spec/interface.html#com-interfaces) it seems 
that only interfaces inheriting from 
core.stdc.windows.com.IUnknown (or any interface named 
"IUnknown") get the COM interface layout instead of the D 
layout.


What can I do to get the COM layout on interfaces that don't 
inherit IUnknown?
Examples: IXAudio2Voice or any of the IXAudio2*Callback 
interfaces. I have already declared everything extern(Windows), 
but that does not fix it.


From memory COM interfaces are really just `extern(C++) 
interface`s, so


extern(C++) interface IXAudio2Voice
{
//methods...
}

should do the trick




Re: D on ARM laptops?

2019-07-03 Thread Nicholas Wilson via Digitalmars-d-learn

On Wednesday, 3 July 2019 at 20:49:20 UTC, JN wrote:
Does anyone know if and how well D works on ARM laptops (such 
as Chromebooks and similar)?


For example this one https://www.pine64.org/pinebook/ . Can it 
compile D? Obviously DMD is out because it doesn't have ARM 
builds. Not sure about GDC. How about LDC?


Haven't tried on laptops, but I can't imagine it would be too 
different to RasPi which LDC worked fine on.


Re: Illegal Filename after basic install and trying Hello World

2019-06-26 Thread Nicholas Wilson via Digitalmars-d-learn
On Wednesday, 26 June 2019 at 13:57:22 UTC, Gilbert Fernandes 
wrote:

I am using VS 2019 into which I have C# and C++ active.
Installed the following : DMD 2.086.1 then Visual D 0.50.0
DMD has been installed at the base of C:\ at C:\D

Created a D project, which contains a default Hello world 
program.

Build fails. Running the program fails.

VS displays the following error :

-- Build started: Project: Test2, Configuration: Debug x64 
--

Building x64\Debug\Test2.exe...
OPTLINK (R) for Win32  Release 8.00.17
Copyright (C) Digital Mars 1989-2013  All rights reserved.
http://www.digitalmars.com/ctg/optlink.html
OPTLINK : Error 8: Illegal Filename
== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 
skipped ==


Besides installing Visual D and creating a new project, done 
nothing.


I have searched the forum for people with the same problem and 
found two threads.

https://forum.dlang.org/post/poq048$28mm$1...@digitalmars.com
https://forum.dlang.org/post/xmhkgkqujxmzruque...@forum.dlang.org

None do help. The option "override linker settings from sc.ini"


it may be called dmd.conf (it is on my Mac, but the windows may 
be different)


is nowhere it seems. I have checked both inside the current 
project properties, and VS settings themselves.


I have the following cmd to build the program in the folder :

set PATH=C:\Program Files (x86)\Visual Studio\VC\bin;C:\Program 
Files (x86)\Visual Studio\Common7\IDE;C:\Program Files 
(x86)\Windows Kits\10\bin;C:\D\dmd2\windows\bin;%PATH%

set DMD_LIB=C:\Program Files (x86)\Visual Studio\VC\lib\amd64
set VCINSTALLDIR=C:\Program Files (x86)\Visual Studio\VC\
set VCTOOLSINSTALLDIR=C:\Program Files (x86)\Visual 
Studio\VC\Tools\MSVC\14.21.27702\

set VSINSTALLDIR=C:\Program Files (x86)\Visual Studio\
set WindowsSdkDir=C:\Program Files (x86)\Windows Kits\10\
set WindowsSdkVersion=10.0.17763.0
set UniversalCRTSdkDir=C:\Program Files (x86)\Windows Kits\10\
set UCRTVersion=10.0.17763.0
"C:\Program Files (x86)\VisualD\pipedmd.exe" -deps 
x64\Debug\Test2.dep dmd -m64 -g -gf -debug -X 
-Xf"x64\Debug\Test2.json" -c -of"x64\Debug\Test2.obj" Test2.d

if %errorlevel% neq 0 goto reportError

set LIB=C:\D\dmd2\windows\bin\..\lib64
echo. > D:\sources_D\Test2\Test2\x64\Debug\Test2.link.rsp
echo "x64\Debug\Test2.obj" /OUT:"x64\Debug\Test2.exe" 
user32.lib  >> D:\sources_D\Test2\Test2\x64\Debug\Test2.link.rsp
echo kernel32.lib  >> 
D:\sources_D\Test2\Test2\x64\Debug\Test2.link.rsp
echo legacy_stdio_definitions.lib /LIBPATH:"C:\Program Files 
(x86)\Visual Studio\VC\lib\amd64" /DEBUG 
/PDB:"x64\Debug\Test2.pdb" /INCREMENTAL:NO /NOLOGO /noopttls 
/NODEFAULTLIB:libcmt libcmtd.lib /SUBSYSTEM:CONSOLE >> 
D:\sources_D\Test2\Test2\x64\Debug\Test2.link.rsp
"C:\Program Files (x86)\VisualD\mb2utf16.exe" 
D:\sources_D\Test2\Test2\x64\Debug\Test2.link.rsp


"C:\Program Files (x86)\VisualD\pipedmd.exe" -msmode -deps 
x64\Debug\Test2.lnkdep C:\D\dmd2\windows\bin\link.exe 
@D:\sources_D\Test2\Test2\x64\Debug\Test2.link.rsp

if %errorlevel% neq 0 goto reportError
if not exist "x64\Debug\Test2.exe" (echo "x64\Debug\Test2.exe" 
not created! && goto reportError)


goto noError

:reportError
echo Building x64\Debug\Test2.exe failed!

:noError

Typing "link" seems to launch the D Optilink Linker by default 
on my CMD.
If I understand properly, I should be using the VS C++ supplied 
linker ?


Correct. You have VS, so it is of no use to you. Use the VS one 
instead of C:\D\dmd2\windows\bin\link.exe in your build file. You 
can just delete the wrong link.exe any hopefully it will pick up 
the correct one in the $PATH.


Also any reason why you (or is that visualD doing that? )are 
manually invoking the linker? Omit -c and dmd will invoke the 
linker for you (hopefully the correct one).





Re: DIP 1016 and const ref parameters

2019-06-20 Thread Nicholas Wilson via Digitalmars-d-learn
On Wednesday, 19 June 2019 at 19:25:59 UTC, Jonathan M Davis 
wrote:


Aside from looking through the newsgroup/forum for discussions 
on DIPs, that's pretty much all you're going to find on that. 
Andrei's talk is the most up-to-date information that we have 
about this particular DIP.



The preliminary implementation is the most practicable up to date 
info there: https://github.com/dlang/dmd/pull/9817


Re: is there a way to embed python 3.7 code in D program?

2019-05-12 Thread Nicholas Wilson via Digitalmars-d-learn

On Sunday, 12 May 2019 at 20:06:34 UTC, torea wrote:

Hi,

I'd like to use D for the "brain" of a small robot (Anki 
vector) whose API is coded in Python 3.6+.

I had a look at Pyd but it's limited to python 2.7...


It isn't. You may needs to set a dub version, or it may pick up 
the 2.7 as the default but it definitely works (I'm travelling 
ATM, can't check).


Re: Compiler/Phobos/Types problem — panic level due to timing.

2019-05-05 Thread Nicholas Wilson via Digitalmars-d-learn

On Sunday, 5 May 2019 at 19:18:47 UTC, lithium iodate wrote:

On Sunday, 5 May 2019 at 18:53:08 UTC, Russel Winder wrote:

Hi,

I had merrily asumed I could implement nth Fibonacci number 
with:


takeOne(drop(recurrence!((a, n) => a[n-1] + a[n-2])(zero, 
one), n)).front


where zero and one are of type BigInt, and n is of type 
size_t. However both dmd and ldc2 complain saying:

[…]
I am now at the WTF stage – how can I show this example on 
Thursday in my DevoxxUK presentation?


I am close to giving up and imbibing of too much Pernod.


`recurrence` takes the `CommonType` of the initial values and 
declares its internal state as an array of this type, however 
when at least one of the values is const or immutable, the 
`CommonType` is const too, or even immutable in the case when 
all values are immutable.
The state being const/immutable means that the following step, 
initializing it, can't work, since, well, the array cannot be 
modified (hence the errors).

I'd say this can be considered to be a bug with `recurrence`.
You can solve this issue by constructing and passing mutable 
versions of `one` and `zero` to `recurrence`.


Yep https://run.dlang.io/is/XsLrRz works for me, 
https://run.dlang.io/is/KxY0e9 doesn't.


Re: I had a bad time with slice-in-struct array operation forwarding/mimicing. What's the best way to do it?

2019-05-04 Thread Nicholas Wilson via Digitalmars-d-learn

On Saturday, 4 May 2019 at 15:18:58 UTC, Random D user wrote:
I wanted to make a 2D array like structure and support D slice 
like operations,

but I had surprisingly bad experience.

I quickly copy pasted the example from the docs: 
https://dlang.org/spec/operatoroverloading.html#array-ops


It's something like this:
struct Array2D(E)
{
E[] impl;
int stride;
int width, height;

this(int width, int height, E[] initialData = [])
ref E opIndex(int i, int j)
Array2D opIndex(int[2] r1, int[2] r2)
auto opIndex(int[2] r1, int j)
auto opIndex(int i, int[2] r2)
int[2] opSlice(size_t dim)(int start, int end)
@property int opDollar(size_t dim : 0)()
@property int opDollar(size_t dim : 1)()
}

So basic indexing works fine:
Array2D!int foo(4, 4);
foo[0, 1] = foo[2, 3];

But array copy and setting/clearing doesn't:
int[] bar = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 
15 ];

foo[] = bar[];

And I get this very cryptic message:
(6): Error: template `example.Array2D!int.Array2D.opSlice` 
cannot deduce function from argument types `!()()`, candidates 
are:
(51):`example.Array2D!int.Array2D.opSlice(ulong 
dim)(int start, int end) if (dim >= 0 && (dim < 2))`


1. WTF `!()()` and I haven't even called anything with opSlice 
i.e. `a .. b`?


Anyway, it doesn't overload [] with opIndex(), so fine, I add 
that.

T[] opIndex() { return impl; }

Now I get:
foo[] = bar[]; // or foo[] = bar;
Error: `foo[]` is not an lvalue and cannot be modified

Array copying docs say:
When the slice operator appears as the left-hand side of an 
assignment expression, it means that the contents of the array 
are the target of the assignment rather than a reference to the 
array. Array copying happens when the left-hand side is a 
slice, and the right-hand side is an array of or pointer to the 
same type.


2.WTF I do have slice operator left of assignment.
So I guess [] is just wonky named getter (and not an operator) 
for a slice object and that receives the = so it's trying to 
overwrite/set the slice object itself.


Next I added a ref to the E[] opIndex():
ref E[] opIndex() { return impl; }

Now foo[] = bar[] works as expected, but then I tried
foo[] = 0;
and that fails:
Error: cannot implicitly convert expression `0` of type `int` 
to `int[]`


3. WTF. Didn't I just get reference directly to the slice and 
array copy works, why doesn't array setting?


The ugly foo[][] = 0 does work, but it's so ugly/confusing that 
I'd rather just use a normal function.


So I added:
ref E[] opIndexAssign(E value) { impl[] = value; return impl; }

And now foo[] = 0; works, but foo[0, 1] = foo[2, 3] doesn't.

I get:
Error: function `example.Array2D!int.Array2D.opIndexAssign(int 
f)` is not callable using argument types `(int, int, int)`

expected 1 argument(s), not 3

4. WTF. So basically adding opIndexAssign(E value) disabled ref 
E opIndex(int i, int j). Shouldn't it consider both?


I'm surprised how convoluted this is. Is this really the way 
it's supposed to work or is there a bug or something?



So what is the best/clear/concise/D way to do these for a 
custom type?


I was planning for:
foo[] = bar; // Full copy
foo[] = 0; // Full clear
foo[0 .. 5, 1] = bar[ 0 .. 5]; // Row/Col copy
foo[1, 0 .. 5] = 0; // Row/Col clear
foo[0 .. 5, 2 .. 4] = bar[ 1 .. 6, 0 .. 2 ]; // Box copy
foo[0 .. 5, 2 .. 4] = 0; // Box clear

Anyway, this is not a huge deal breaker for me, I was just 
surprised and felt like I'm missing something.
I suppose I can manually define every case one by one and not 
return/use any references etc.
or use alias this to forward to impl[] (which I don't want to 
do since I don't want to change .length for example)

or just use normal functions and be done with it.

And it's not actually just a regular array I'm making, so 
that's why it will be mostly custom code, except the very 
basics.


The de facto multi dimensional array type in D is mir's ndslice

https://github.com/libmir/mir-algorithm/blob/master/source/mir/ndslice/slice.d#L479


Call delegate from C++

2019-04-24 Thread Nicholas Wilson via Digitalmars-d-learn

How do you pass a delegate to a c++ function to be called by it?

The function to pass the delegate to is:

extern (C++) int
fakeEntrypoint(
extern(C++) void function(void* /*delegate's context*/) func,
void* /*delegate's context*/ arg);


What I want is:

int entrypoint(scope void delegate() func)
{
return fakeEntrypoint(
// for some reason func.funcptr is void function()
cast(void function(void*))func.funcptr,
func.ptr);
}

but that fails with

cannot pass argument cast(void function(void*))func.funcptr of 
type
void function(void*) to parameter extern (C++) void 
function(void*) func





Re: Error: template instance `Reflect!(type)` cannot use local `type` as parameter to non-global template `Reflect(Ts...)()`

2019-04-06 Thread Nicholas Wilson via Digitalmars-d-learn

On Sunday, 7 April 2019 at 05:24:38 UTC, Alex wrote:
Error: template instance `Reflect!(type)` cannot use local 
`type` as parameter to non-global template `Reflect(Ts...)()`


mixin(`import `~moduleName!(T)~`;`);
mixin(`alias X = T.`~name~`;`); 
super.Reflect!(X);

I realize X is local but I'm trying to figure out why it can't 
be passed to a "non-global" template.


See 
https://blog.thecybershadow.net/2015/04/28/the-amazing-template-that-does-nothing/


TL;DR

At global scope
alias Identity(alias X) = X;

then where the error is issued from use `Identity!(type)` instead 
of type.


Re: Problems instantiating template class

2019-04-06 Thread Nicholas Wilson via Digitalmars-d-learn

On Saturday, 6 April 2019 at 17:30:45 UTC, Mek101 wrote:
I'm rewriting from C# a small library of mine to practice with 
D.

I have a class:


 class WeightedRandom(T, W = float) if(isNumeric!W)
 {
 // Fields
 private W[T] _pairs;
 // The total sum of all the weights;
 private W _probabilities;

 /// Code...
 }


And when I try to instantiate an object in a unittest


 unittest
 {
 auto wrnd = new WeightedRandom!char();
 wrnd.normalizeAt(120.55);
 }


Compilation fails with the following error:


 source/utils/weightedRandom.d(25,18): Error: cannot pass type 
char as a function argument
 source/utils/weightedRandom.d(90,18): Error: template instance 
`utils.weightedrandom.WeightedRandom!(char, float)` error 
instantiating

 /usr/bin/dmd failed with exit code 1.


Same exact error with:
   WeightedRandom!(char)();
   WeightedRandom!(string, float)();


It seems like dmd thinks I'm calling a function while I'm 
trying to instantiate the object.


Hmm,

import std.traits;
class WeightedRandom(T, W = float) if(isNumeric!W)
 {
 // Fields
 private W[T] _pairs;
 // The total sum of all the weights;
 private W _probabilities;

 /// Code...
 }

void main()
{
auto wrnd = new WeightedRandom!char();
}

works for me: https://run.dlang.io/is/CjSubj


Re: template with enum parameter doesn't compile

2019-04-05 Thread Nicholas Wilson via Digitalmars-d-learn

On Friday, 5 April 2019 at 14:47:42 UTC, Sjoerd Nijboer wrote:
So the following code doesn't compile for some reason, and I 
can't figure out why.


enum MyEnum { A, B, C }

class MyClass(MyEnum myEnum)
{
/*...*/
}

int main()
{
MyClass!MyEnum.A a;
}

The error:  Error: template instance `MyClass!(MyEnum)` does 
not match template declaration `MyClass(MyEnum myEnum)`

pops up, no matter what I do.


You wrote:


MyClass!MyEnum.A a;


Which is equivalent to


MyClass!(MyEnum).A a;


What you want is

MyClass!(MyEnum.A) a;



Re: Request some GtkD Assistance

2019-03-27 Thread Nicholas Wilson via Digitalmars-d-learn

On Wednesday, 27 March 2019 at 06:55:53 UTC, Andrew Edwards wrote:

Good day all,

I've installed Gtk+ and GtkD on my MacBookPro which is running 
macOS Mojave but am having some issues linking to and using it. 
Any assistance to resolve this is appreciated.


Steps taken:

1. Install Gtk+

  brew install gtk+

2. Build and install GtkD-3.8.5

 unzip GtkD-3.8.5.zip
 copy gtkd folder to dmd/osx/src/
 make
 copy libgtkd-3.a to dmd/osx/lib/

3. Update dmd.conf

 add -I%@P%/../../src/gtkd to DFLAGS

Problems encountered:

1. Unable to find the lib

(dmd-2.085.0)BMP:model edwarac$ dmd -de -w -Llibgtkd-3.a nufsaid
ld: file not found: libgtkd-3.a
clang: error: linker command failed with exit code 1 (use -v to 
see invocation)

Error: linker exited with status 1

Not sure why I'm receiving this first error since the file is 
stored alongside the libphobos2.a which the linker doesn't have 
any issues locating. If copy the file to the local directory, 
linking completes without any further errors.


2. Unable to find libgtkd-3.dylib

 (dmd-2.085.0)Andrews-MBP:model edwarac$ ./nufsaid
 object.Exception@generated/gtkd/gtkd/Loader.d(125): 
Library load failed (libgdk-3.0.dylib): 
dlopen(libgdk-3.0.dylib, 258): image not found


Not sure what's going on here at all. This file was not created 
when I built GtkD. Where do I find it, or how do I create it?


--Andrew



dmd -de -w -Llibgtkd-3.a nufsaid


try
dmd -de -w -lgtkd-3 nufsaid
or
dmd -de -w -L/path/to/lib nufsaid


dlopen(libgdk-3.0.dylib, 258): image not found


it that a typo? gdk not gtk?

Regardless gtkD is bindings to gtk which are separate, make sure 
you have gtk installed and in your path.


Re: Why a template with Nullable does not compile?

2019-03-12 Thread Nicholas Wilson via Digitalmars-d-learn

On Tuesday, 12 March 2019 at 05:14:21 UTC, Victor Porton wrote:

Why does this not compile?

import std.typecons;

template FieldInfo(T, Nullable!T default_) {
}

/usr/lib/ldc/x86_64-linux-gnu/include/d/std/typecons.d(2570,17): Error: `alias 
T = T;` cannot alias itself, use a qualified name to create an overload set
/usr/lib/ldc/x86_64-linux-gnu/include/d/std/typecons.d(3291,17): Error: `alias 
T = T;` cannot alias itself, use a qualified name to create an overload set


It seems to be getting confused between the two types of 
Nullable, namely:

Nullable(T), and
Nullable(T, T defaultVal)

template FieldInfo(T) {
template FieldInfo(Nullable!(T) default_)
{
enum FieldInfo = 0;
}
}

seems to work, but I can't seem to instantiate one of it.



Re: Phobos in BetterC

2019-03-09 Thread Nicholas Wilson via Digitalmars-d-learn

On Saturday, 9 March 2019 at 12:42:34 UTC, Sebastiaan Koppe wrote:
There might also be the option to use @nogc exceptions (dip 
1008), but I am not sure.


That won't work as the implementation on DIP1008 cheats the type 
system but doesn't actually work, i.e. the exceptions are still 
CG allocated.




Re: Phobos in BetterC

2019-03-09 Thread Nicholas Wilson via Digitalmars-d-learn

On Friday, 8 March 2019 at 09:24:25 UTC, Vasyl Teliman wrote:
I've tried to use Mallocator in BetterC but it seems it's not 
available there:


https://run.dlang.io/is/pp3HDq

This produces a linker error.

I'm wondering why Mallocator is not available in this mode (it 
would be intuitive to assume that it's working). Also I would 
like to know what parts of Phobos are available there (e.g. 
std.traits, std.typecons...).


Thanks in advance.


This is really a linker problem, because -betterC doesn't link 
druntime, and pbobos links druntime. to get around this pass 
-i=std.experimental.allocator to dmd along with the rest of you 
usual arguments.


Re: dcompute - Error: unrecognized `pragma(LDC_intrinsic)

2019-02-28 Thread Nicholas Wilson via Digitalmars-d-learn
On Thursday, 28 February 2019 at 09:58:35 UTC, Michelle Long 
wrote:
I've included it in Visual D as di and it seems not to add it 
to the include line...


Is it in any way possible that it being an di file would allow 
that? Seems that it is an LDC issue though but LDC has some 
usage of it I believe and it works fine.


Could it be a LDC version? Or do I need to include something to 
make it work? Seems like it would be part of the compiler 
itself.


(I'm on cold and flu meds so apologies if this doesn't make sense)

It should be on the atuoimport path of LDC as that file had 
others 
(https://github.com/ldc-developers/druntime/tree/ldc/src/ldc) are 
part of LDC's druntime which should be imported by ldc's .conf 
file, it won't show up on the command line unless you do 
something (... brain not working properly...).


Irrespective of all that, the error comes from

https://github.com/ldc-developers/ldc/blob/f5a5324773484447953746725ea455d2827e6004/dmd/dsymbolsem.d#L1862

which should never happen because this branch should be taken

https://github.com/ldc-developers/ldc/blob/f5a5324773484447953746725ea455d2827e6004/dmd/dsymbolsem.d#L1807

because that pragma is explicitly checked for here

https://github.com/ldc-developers/ldc/blob/187d8198e63564c633f22f2ef4db2a31a8a600ce/gen/pragma.cpp#L110


Re: how to pass a malloc'd C string over to be managed by the GC

2019-02-27 Thread Nicholas Wilson via Digitalmars-d-learn

On Thursday, 28 February 2019 at 03:33:25 UTC, Sam Johnson wrote:

```
string snappyCompress(const string plaintext) {
	import deimos.snappy.snappy : snappy_compress, 
snappy_max_compressed_length, SNAPPY_OK;

import core.stdc.stdlib : malloc, free;
import std.string : fromStringz, toStringz;
char *input = cast(char *) toStringz(plaintext);
	size_t output_length = 
snappy_max_compressed_length(plaintext.length);

char *output = cast(char *) malloc(output_length);
	if(snappy_compress(input, plaintext.length, output, 
_length) == SNAPPY_OK) {

string ret = (cast(string) fromStringz(output)).clone();
// < do something magical here
return ret;
}
assert(0);
}
```

How can I get the GC to automatically garbage collect the 
`output` malloc call by tracking the returned `ret` reference?


I'm surprised that GC.addRoot(output) actually helped you here, 
GC.addRoot is for when the thing you are adding may hold pointers 
to GC allocated stuff and you don't want non-GC allocated 
references to dangle when the GC does a collection pass.


If you want the GC to handle it just use new:

char[] output = new char[output_length];
...
return assumeUnique(output);

Or is this already managed by the gc because I cast to a 
`string`?


No, string is just an alias for immutable(char)[], which is just
struct
{
size_t length;
immutable(char)* ptr;
}

it can refer to any span of memory, it has no concept of 
ownership.


Re: dcompute - Error: unrecognized `pragma(LDC_intrinsic)

2019-02-27 Thread Nicholas Wilson via Digitalmars-d-learn
On Wednesday, 27 February 2019 at 22:56:14 UTC, Michelle Long 
wrote:
Trying to get dcompute to work... after a bunch of issues 
dealing with all the crap this is what I can't get past:


Error: unrecognized `pragma(LDC_intrinsic)

This is actually from the ldc.intrinsics file, which I had to 
rename from .di to d so it would be included in by VisualD.


I upgraded to latest LDC just before

LDC - the LLVM D compiler (1.14.0git-1bbda74):
  based on DMD v2.084.1 and LLVM 7.0.1


pragma(LDC_intrinsic, "llvm.returnaddress")
void* llvm_returnaddress(uint level);


..\..\..\..\D\LDC\import\ldc\intrinsics.d(85): Error: 
unrecognized `pragma(LDC_intrinsic)`


I've got no idea why that is the case, although I note that you 
shouldn't need to change intrinsics.di to intrinsics.d, as a .di 
it only needs to be on the include path which should already be 
the case for LDC.


Re: Template recursion exceeded

2019-02-26 Thread Nicholas Wilson via Digitalmars-d-learn
On Wednesday, 27 February 2019 at 05:45:19 UTC, Michelle Long 
wrote:

Basically

void foo(int k = 20)()
{
   static if (k <= 0 || k >= 100) return;
   foo!(k-1)();
}

Error   Error: template instance `foo!-280` recursive expansion 


Yep, that return is a dynamic return, not a static one.


   static if (k <= 0 || k >= 100) {} else:
   foo!(k-1)();


will work.


Re: DMD2 vs LDC2 inliner

2019-02-24 Thread Nicholas Wilson via Digitalmars-d-learn
On Monday, 25 February 2019 at 04:08:38 UTC, Jonathan M Davis 
wrote:
One issue that's commonly brought up about dmd's inliner is 
that it's in the front-end, which apparently is a poor way to 
do inlining. One side effect of that though would be that 
unless the ldc folks go to extra effort to disable the 
front-end's inliner


We do.

, ldc has that inliner - and then it's inlining using llvm. So, 
given that, it's practically guaranteed to do a better job.


It does anyway ;)





Re: DMD2 vs LDC2 inliner

2019-02-24 Thread Nicholas Wilson via Digitalmars-d-learn

On Monday, 25 February 2019 at 02:49:36 UTC, James Blachly wrote:
Any ideas why DMD2 cannot inline this, but LDC2 has no problem 
doing so -- or suggestions for what I can do to make DMD2 
inline it?


Alternatively, I could version(DigitalMars) and version(LDC), 
but AFAICT this requires me to duplicate the entire template, 
because I cannot figure out how to make the version() directive 
apply only to the pragma.


Template instantiation is with a simple struct having integer 
members start and end.


Thanks in advance for tips.
---
pragma(inline, true)
bool overlaps(IntervalType1, IntervalType2)(IntervalType1 int1, 
IntervalType2 int2)


Leaving aside the issue of why DMD can't handle this, the entire 
reason
pragma(inline, bool) takes a bool is for it to be (potentially) 
predicated.

In this case you want:

version(DigitalMars)
 private enum inline_overlaps = false;
else // assuming GDC is good
 private enum inline_overlaps = true;

pragma(inline, inline_overlaps)
bool overlaps(IntervalType1, IntervalType2)(IntervalType1 int1, 
IntervalType2 int2)

{
 return ...;
}


Re: Compile Time Fun Time

2019-02-24 Thread Nicholas Wilson via Digitalmars-d-learn

On Monday, 25 February 2019 at 06:51:20 UTC, Yevano wrote:
I am writing a domain specific language of sorts in D for the 
lambda calculus. One of my requirements is that I should be 
able to generate expressions like this:


new Abstraction(v1, M)

like this:

L!(x => M)

It is common to want to write things like

L!(x => L!(y => M))

but it is much nicer to write that like

L!((x, y) => M)

So, I have created a templated function for this.

Abstraction L(alias f)() {
static if(__traits(compiles, f(null))) {
auto v1 = new Variable;
return new Abstraction(v1, f(v1));
} else static if(__traits(compiles, f(null, null))) {
auto v1 = new Variable;
auto v2 = new Variable;
return new Abstraction(v1, new Abstraction(v2, f(v1, 
v2)));

} else static if(__traits(compiles, f(null, null, null))) {
auto v1 = new Variable;
auto v2 = new Variable;
auto v3 = new Variable;
return new Abstraction(v1, new Abstraction(v2, new 
Abstraction(v3, f(v1, v2, v3;

}
}

This only works for at most 3 parameter delegates. If I want to 
add more, I have to linearly add more static ifs in the obvious 
way. However, I believe I can make this function scalable using 
string mixins and other magic. Any insight into this is much 
appreciated.


import std.traits;
Abstraction L(alias f)() {
 alias Args = Parameters!f;
 Args v;
 foreach(i; 0 .. v.length) v[i] =  new Variable;
 auto _f = f(v);
 auto abstraction = new Abstraction(v[$-1],_f);
 foreach_reverse(e; v[ 0 .. $-2])
  abstraction =  new Abstraction( e, abstraction);
 return abstraction;
}


Re: Can LDC compile to supported legacy LLVM versions?

2019-01-28 Thread Nicholas Wilson via Digitalmars-d-learn

On Monday, 28 January 2019 at 11:37:56 UTC, Dukc wrote:
I have recenty updated my LDC to the most recent version 
(1.14). The problem is that it compiles to LLVM code version 
7.0.1, but I need it to compile to LLVM 6.x.x or LLVM 5.x.x. 
The last release note said that LLVM versions from 
3.something.something are supported, but does this mean only 
linking to them, or also compiling to them?


If it can be done, how? Thanks.


Do you mean bitcode, LLVM IR or something different? The LDC 
built against a given version of LLVM can link to bitcode/compile 
LLMV IR, of that version.


Lowest LLVM it can be compiled against is 3.9. LDC's releases are 
compiled against 7.0.1, but that doesn't stop you downloading a 
release of the desired LLVM version and compiling LDC against 
that.


All you need is a semi-recent CMake. Just git clone from our 
github and run cmake, you'll need to provide the location of the 
llvm-config binary as LLVM_CONFIG but thats it.


Re: How to use core.atomic.cas with (function) pointers?

2019-01-22 Thread Nicholas Wilson via Digitalmars-d-learn

On Tuesday, 22 January 2019 at 14:13:23 UTC, Johan Engelen wrote:

The following code compiles:
```
alias T = shared(int)*;

shared T a;
shared T b;
shared T c;

void foo() {
import core.atomic: cas;
cas(, b, c);
}
```

The type of T has to be a pointer to a shared int (you get a 
template match error for `cas` if `T = int*`), which is 
annoying but I kind-of understand.
However, change b to null (`cas(, null, c);`) and things no 
longer work: "Error: template `core.atomic.cas` cannot deduce 
function from argument types"


I have not succeeded to make things work with function pointers 
(neither with nor without `null` as second argument). What am I 
doing wrong if `alias T = void function();` ?


Thanks,
  Johan


You need to cast stuff (as seems to be the case with everything 
to do with shared, at least until/if Manu's proposal goes 
through):


alias T = void function();
alias S = shared(size_t*);
shared T a;
shared T b;
shared T c;

void foo() {
import core.atomic: cas;
cas(cast(S*), cast(S)b, cast(S)c);
}


Re: Deprecation: foreach: loop index implicitly converted from size_t to int

2019-01-18 Thread Nicholas Wilson via Digitalmars-d-learn

On Friday, 18 January 2019 at 12:27:17 UTC, Michael wrote:

Hello all,

I am getting this deprecation warning when compiling using 
DMD64 D Compiler v2.084.0 on Linux. I'm a little unsure what 
the problem is, however, because the code producing these 
warnings tends to be of the form:



foreach (int i, ref prop; props)


This, to be, looks like quite the explicit conversion, no? Does 
it mean I now have to use to!int(i) to convert the type of i in 
a foreach now?


Thanks,
Michael.



foreach (int i, ref prop; props)


All you need to do is


foreach (i, ref prop; props)


The reason for the deprecation is that if your array props is > 
2GB int can't span the range of indices necessary because it will 
overflow.


Re: Understanding SIGSEGV issues

2019-01-09 Thread Nicholas Wilson via Digitalmars-d-learn

On Wednesday, 9 January 2019 at 16:48:47 UTC, Russel Winder wrote:
It really is totally weird. My new Rust binding to libdvbv5 and 
associated version of the same application works fine. So 
libdvbv5 itself is not the cuprit. This has to mean it is 
something about the D compilers that has changed the way the D 
binding to libdvbv5 behaves.


Hmm, if you think the binding could be the problem you could try 
using app as an alternative, see if it makes any difference.




Re: Understanding SIGSEGV issues

2019-01-08 Thread Nicholas Wilson via Digitalmars-d-learn

On Tuesday, 8 January 2019 at 10:23:30 UTC, Russel Winder wrote:
Actually that is not a worry since the TransmitterData instance 
is only needed to call the scan function which creates a 
ChannelsData instance that holds no references to the 
TransmitterData instance.


It turns out that whilst the code used to run, and now doesn't, 
all the things
we have been talking of are nothing to do with the core 
problem. It turns out
that the function call to initialise the File_Ptr object is 
returning a valid
object with invalid data. Thus the unknown change is likely in 
the libdvbv5
library either due to the C API doing different things or the 
adapter created

using DStep doing the wrong thing.


Ahh. Good that you've found that, I can't help you much more with 
that then.


The compiler generated default opEquals will do basically the 
same thing. Ditto for the other types. You usually want to 
take a const ref for opEquals since there is no point copying 
it.


I deleted them, added a test or three (should have done this 
ages ago) and the tests pass. So teh generated methods do the 
needful. Thanks for that "heads up".


No problems, less code is good code.

Very true. For now I have forbidden copying, which is wrong for 
this sort of thing. If D had the equivalent of C++ 
std::shared_ptr or Rust std::rc::Rc or std::rc::Arc, that would 
be the way forward But I guess having explicit reference 
counting is not too hard.


I believe Andrei and Razvan are working on that, part of that 
being the Copy Constructor DIP. Hopefully it will arrive soon.


You seem to like const, good! You don't need to take `const 
int`s as parameters, you're getting a copy anyway. You have a 
bunch of redundant casts as well.


I am a person who always makes Java variables final, and loves 
that Rust variables are immutable by default!


Indeed, less to think about is always nice.

Good luck figuring out why your data is dud.
Nic


Re: Co-developing application and library

2019-01-05 Thread Nicholas Wilson via Digitalmars-d-learn

On Saturday, 5 January 2019 at 13:01:24 UTC, Russel Winder wrote:
Dub seems to have the inbuilt assumption that libraries are 
dependencies that do not change except via a formal release 
when you developing an application. Clearly there is the 
workflow where you want to amend the library but not release as 
a part of developing an application. Does Dub have a way of 
doing this, I haven't been able to infer one to date. But I am 
a beginner at Dub.


you can depend on ~master as a version, I'm not sure if you have 
to tell it to refresh what is has.


Re: Understanding SIGSEGV issues

2019-01-05 Thread Nicholas Wilson via Digitalmars-d-learn

On Saturday, 5 January 2019 at 12:14:15 UTC, Russel Winder wrote:
Indeed. I should do that to see if I can reproduce the problem 
to submit a proper bug report.


File_Ptr is wrapping a dvb_file * from libdvbv5 to try and make 
things a bit for D and to ensure RAII. libdvbv5 is a C API with 
classic C approach to handling objects and data structures.


My DStep/with manual binding is at 
https://github.com/russel/libdvbv5_d and the application using 
it (which is causing the problems) is at 
https://github.com/russel/DVBTune


Your problem possibly (probably?) stems from

auto channelsData = TransmitterData(args[1]).scan(frontendId);

The temporary TransmitterData(args[1]) is, well, temporary and 
its destructor runs after that expression is done. As the 
returned object from scan references data from the temporary, you 
have a stale pointer.


I have a feeling that I am really not doing things in a D 
idiomatic way.


Some driveby style comments then:


bool opEquals()(const FrontendId other) const {
if (this is other) return true;
if (other is null) return false;
		return this.adapter_number == other.adapter_number && 
this.frontend_number == other.frontend_number;

}


The compiler generated default opEquals will do basically the 
same thing. Ditto for the other types. You usually want to take a 
const ref for opEquals since there is no point copying it.



if (other is null)


I'm surprised the compiler doesn't warn or error on that as the 
only way that could make sense would be if it had an alias this 
to a pointer type.


You should consider reference counting your pointer wrapper 
types, FrontendParameters_Ptr/File_Ptr/ScanHandler_Ptr


You seem to like const, good! You don't need to take `const int`s 
as parameters, you're getting a copy anyway. You have a bunch of 
redundant casts as well.


I'll have another looks tomorrow when I'm a bit more awake.


Re: Understanding SIGSEGV issues

2019-01-05 Thread Nicholas Wilson via Digitalmars-d-learn

On Saturday, 5 January 2019 at 10:52:48 UTC, Russel Winder wrote:
I found the problem and then two minutes later read your email 
and bingo we have found the problem.


Well done.

Previously I had used File_Ptr* and on this occasion I was 
using File_Ptr and there was no copy constructor because I have 
@disable this(this). Except that clearly copying a value is not 
copying a value in this case. Clearly this situation is what is 
causing the destructor to be called on an unconstructed value. 
But I have no idea why.


Could you post a minimised example? Its a bit hard to guess 
without one.


The question now, of course, is should I have been using 
File_Ptr instead of File_Ptr* in the first place. I am 
beginning to think I should have been. More thinking needed.


From the name, File_Ptr sounds like it is wrapping a reference to 
a resource. So compare with C's FILE/ D's File which is a 
reference counted wrapper of a FILE*. Would you ever use a File* 
(or a FILE**)? Probably not, I never have.




Re: Understanding SIGSEGV issues

2019-01-05 Thread Nicholas Wilson via Digitalmars-d-learn

On Saturday, 5 January 2019 at 07:34:17 UTC, Russel Winder wrote:
TransmitterData has a destructor defined but with no code in 
it. This used to work fine – but I cannot be certain which 
version of LDC that was.


The problem does seem to be in the construction of the 
TransmitterData object because a destructor is being called on 
the File_Ptr field as part of the transmitterData constructor.


As you can see from the stack trace #3, the File_Ptr is null. 
The solution to this is to either ensure it is initialised in 
the constructor of TransmitterData, or account for it possibly 
being null by defining a destructor for TransmitterData.


For some reason it seems File_Ptr.~this() is being called before
File_Ptr.this() in the TransmitterData.this(). This is totally 
weird.


Having added some writeln statements:

(gdb) bt
#0  0x555932e0 in dvb_file_free (dvb_file=0x0) at 
dvb_file.d:276
#1  0x55592fbc in types.File_Ptr.~this() (this=...) at 
types.d:83
#2  0x5558cdf6 in 
_D3std6format__T14formattedWriteTSQBg5stdio4File17LockingTextWriterTaTS5types8File_PtrZQCtFKQChxAaQBcZk (w=..., fmt=..., _param_2=...) at /usr/lib/ldc/x86_64-linux-gnu/include/d/std/format.d:472


Maybe it is a problem with copying a File_Ptr (e.g. missing a 
increase of the reference count)? Like, `auto a = File_Ptr(); { 
auto b = a; }` and b calls the destructor on scope exit.
That would be consistent with having problems copying to object 
to pass to writeln.


Re: Understanding SIGSEGV issues

2019-01-03 Thread Nicholas Wilson via Digitalmars-d-learn

On Thursday, 3 January 2019 at 08:35:17 UTC, Russel Winder wrote:
Sorry about that, fairly obvious that the backtrace is needed 
in hindsight. :- )


#0  __GI___libc_free (mem=0xa) at malloc.c:3093
#1  0x5558f174 in dvb_file_free 
(dvb_file=0x555a1320) at dvb_file.d:282
#2  0x5558edcc in types.File_Ptr.~this() (this=...) at 
types.d:83
#3  0x55574809 in 
channels.TransmitterData.__fieldDtor() (this=variable: Cannot access memory at address 0xa>) at 
channels.d:144
#4  0x5556aeda in channels.TransmitterData.__aggrDtor() 
(this=...) at channels.d:144

#5  0x5556ab53 in D main (args=...) at main.d:33

Which indicates that the destructor is being called before the 
instance has been constructed. Which is a real WTF.


Not quite, this occurs as a TransmitterData object goes out of 
scope at the end of main(stick a fflush'ed printf there to see):


TransmitterData is a struct that has no destructor defined but 
has a field of type File_Ptr that does. The compiler generates a 
destructor, __aggrDtor, which calls the fields that have 
destructors, __fieldDtor (e.g. the File_Ptr) which in turn calls 
its destructor, File_Ptr.~this().


As you can see from the stack trace #3, the File_Ptr is null. The 
solution to this is to either ensure it is initialised in the 
constructor of TransmitterData, or account for it possibly being 
null by defining a destructor for TransmitterData.


Re: Understanding SIGSEGV issues

2019-01-02 Thread Nicholas Wilson via Digitalmars-d-learn

On Thursday, 3 January 2019 at 06:25:46 UTC, Russel Winder wrote:
So I have a D program that used to work. I come back to it, 
recompile it, and:


[...]



__GI___libc_free (mem=0xa) at malloc.c:3093


You've tried to free a pointer that, while not null, was derived 
from a pointer that was, i.e. an offset to a field of a struct.


A backtrace would help a lot, otherwise it really is just 
guessing.


Re: Mixin operator 'if' directly

2018-12-22 Thread Nicholas Wilson via Digitalmars-d-learn

On Saturday, 22 December 2018 at 03:44:09 UTC, Timoses wrote:
On Wednesday, 19 December 2018 at 15:40:50 UTC, Neia Neutuladh 
wrote:

On Wed, 19 Dec 2018 15:12:14 +, bauss wrote:
Or while instantiating it:

mixin template foo()
{
  int _ignoreme()
  {
if (readln.strip == "abort") throw new AbortException;
return 1;
  }
  int _alsoIgnoreMe = _ignoreme();
}
void main()
{
  mixin foo;
}


Awesome hack!
Being a hack, it would be even nicer if it worked ouf of the 
box:


mixin template foo(bool b)
{
int _impl() { writeln(b); return int.init; }
int _ipml2 = _impl();
}

vs

mixin template foo(bool b)
{
writeln(b);
}


https://issues.dlang.org/show_bug.cgi?id=19506


Re: 2D-all?

2018-12-14 Thread Nicholas Wilson via Digitalmars-d-learn

On Friday, 14 December 2018 at 12:43:40 UTC, berni wrote:
I've got a lot of code with two-dimensional arrays, where I use 
stuff like:



assert(matrix.all!(a=>a.all!(b=>b>=0)));


Does anyone know if there is a 2D-version of all so I can write 
something like:



assert(matrix.all2D!(a=>a>=0));


auto all2d(alias f)(ref Matrix m)
{
 return m.all!(a => a.all!(b => f(b)));
}


Re: File .. byLine

2018-12-02 Thread Nicholas Wilson via Digitalmars-d-learn

On Monday, 3 December 2018 at 06:09:21 UTC, Joel wrote:

I can't seem to get this to work!

```
foreach(line; File("help.txt").byLine) {
writeln(line.stripLeft);
```

With the code above, I get this compile error:
source/app.d(360,36): Error: template 
std.algorithm.mutation.stripLeft cannot deduce function from 
argument types !()(char[]), candidates are:

/usr/local/opt/dmd/include/dlang/dmd/std/algorithm/mutation.d(2602,7):
std.algorithm.mutation.stripLeft(Range, E)(Range range, E element) if 
(isInputRange!Range && is(typeof(range.front == element) : bool))
/usr/local/opt/dmd/include/dlang/dmd/std/algorithm/mutation.d(2610,7):
std.algorithm.mutation.stripLeft(alias pred, Range)(Range range) if (isInputRange!Range 
&& is(typeof(pred(range.front)) : bool))

I just want to use each 'line' variable as a string?! I've 
tried 'byLineCopy', and 'line.to!string'. I've looked at 
documentation.


https://run.dlang.io/is/h0ArAB

works for me. If you want it as a string not  char[] then 
byLineCopy should work, if not just `.idup` `line`.


Re: D & C++ class question

2018-11-28 Thread Nicholas Wilson via Digitalmars-d-learn

On Wednesday, 28 November 2018 at 13:13:40 UTC, bauss wrote:
Well unfortunately I cannot control the C++ side of things, but 
I assume that it'll work properly with extern(C++) so I guess I 
will just go ahead and try and see if everything works out. I 
have access to the C++ source so at the very least I can see 
how it's used there and if it's possible in the way I want it 
to. I don't hope I have to have a separate C++ "bridge" to make 
it work.


Its mostly a magling problem, if the C++ API uses class& that you 
have to interface with then you have a problem that would require 
a shim.


Re: D & C++ class question

2018-11-28 Thread Nicholas Wilson via Digitalmars-d-learn

On Wednesday, 28 November 2018 at 07:22:46 UTC, bauss wrote:

If I have a class from D.

How would you use that class in C++?

Like what's the correct approach to this.

Would it work just by doing "extern(C++)" or will that only 
work for D to use C++ classes?


If you have

foo.d

class Foo
{
int aMember;
void aMethod() { ... };
final aFinalMethod() { ... };
}

to expose that to C++ you need to add extern(C++) too Foo and use 
it in C++ as a Foo*

foo.h

class Foo
{
int aMember;
virtual void aMethod();
void aFinalMethod();
};

If you can't/don't want to do that you can always pass it around 
in C++ as an opaque pointer with functions that call the member 
functions and get/set the variables (i.e. the pimpl strategy).


Re: memoize & __traits(compiles...)

2018-11-23 Thread Nicholas Wilson via Digitalmars-d-learn

On Friday, 23 November 2018 at 10:34:11 UTC, John Chapman wrote:
I'm doing a fair amount of repeatedly checking if a function 
compiles with __traits(compiles...), executing the function if 
so, erroring out if not, like this:


  static if (__traits(compiles, generateFunc1())) {
return generateFunc1();
  } static if (__traits(compiles, generateFunc2())) {
return generateFunc2();
  } else static assert(false);

But it seems inefficient to have to evaluate those functions 
twice, so I'd like to optimise this so if __traits(compiles...) 
succeeds, the result is cached and then used when the function 
is actually called. I wondered if using std.functional.memoize 
would help?


No, std.functional.memoize uses a hashtable to cache the runtime 
results of calls to expensive functions.


assuming that the example is not oversimplified and generateFunc1 
and generateFunc2 are functions, the compiler doesn't do extra 
semantic analysis so the validity of the functions is effectively 
cached.


If they are templates (with parameters) then the compiler will 
automatically memoize them (it too keeps a hashtable of template 
instances).


When in doubt, profile! 
https://blog.thecybershadow.net/2018/02/07/dmdprof/


Re: D is supposed to compile fast.

2018-11-23 Thread Nicholas Wilson via Digitalmars-d-learn

On Friday, 23 November 2018 at 08:57:57 UTC, Chris Katko wrote:
Any time I see people mention the benefits of D, I see "compile 
times" "compile times" "compile times" over and over.


I'm using very modest amounts of templates, for a fairly small 
sized program (very early work toward a game), and I'm hitting 
~15 seconds compile time in LDC and ~7 seconds in DMD. And I'm 
not even compiling with optimizations!


Templates are slow, slower than CTFE.

ldc2 -w -ofextra  extra.d molto.d helper.d editor.d common.d 
map.d object_t.d animation.d ini.d  -L-L. $@-gc -d-debug=3  
-de -fdmd-trace-functions


dmd -w -ofextra extra.d molto.d helper.d editor.d common.d 
map.d object_t.d animation.d ini.d -profile=gc  -profile  -g 
-debug -color -L-L.


I keep putting stuff into new files, but it feels like it's 
compiling everything from scratch / not getting faster the way 
C++ does.


If you pass all the files on the command line then they all get 
(re)compiled.
Have separate rules for each file, although if you are using 
template from each file in every file that may not help a whole 
lot.


And I'm not even bringing up the 800MB of RAM required because 
I dared to import std.regex. (On a laptop with 2 GB of RAM. 
RIP. If I dare to have tabs open, the compile time goes into 
the minutes thanks to swapping.)


Yep, on the upside the regexen are very fast at runtime. 
std.regex depending on how much of it you are using could also be 
a cause of your problem.you might want to take a look at 
https://blog.thecybershadow.net/2018/02/07/dmdprof/

https://github.com/CyberShadow/dmdprof to see whats taking so long

Is this code online? Its a bit difficult to give specific advice 
without it.


Re: Making external types available to mixins

2018-11-22 Thread Nicholas Wilson via Digitalmars-d-learn

On Saturday, 17 November 2018 at 17:58:54 UTC, John Chapman wrote:
The following code doesn't compile because the generated type 
name needs to be available inside the mixin's scope, whereas 
it's actually in another module.


auto makeWith(string className, Args…)(auto ref Args args) {
  mixin("return makeWith!(I", className, "Factory)(args);"); // 
Fowarded to implementation of makeWith below

}

auto makeWith(T, Args…)(auto ref Args args) … // This is the 
implementation


The idea is that users could type (for example) 
makeWith!`Calendar`(…) instead of the longer 
makeWith!ICalendarFactory(…).


I tried mixing in an import statement with the help of 
std.traits.moduleName so that the I...Factory type would be 
available but again the compiler complains that it's undefined.


Has anyone had a similar need and come up with a solution?


you need to qualify the names: I use 
https://github.com/libmir/dcompute/blob/master/source/dcompute/driver/ocl/util.d#L77-L97
for this in dcompute (needs to be updated for the new style of 
mixin but you get the idea).


Re: How do you debug @safe @nogc code? Can't figure out how to print.

2018-11-17 Thread Nicholas Wilson via Digitalmars-d-learn

On Saturday, 17 November 2018 at 13:13:36 UTC, aliak wrote:
On Friday, 16 November 2018 at 13:21:39 UTC, Stanislav Blinov 
wrote:

auto assumeNoGC(T)(return scope T t) @trusted { /* ... */ }


Sawweet! Thanks, that made the printing possible!

"scope" is const from what I understand right? It works without 
scope as well. So just "return T".


No, `in` used to mean const scope.

scope means roughly "this thing does not escape this function" 
e.g. assigning to global variables.


Re: dip1000: why can't the addressee come into existence later?

2018-11-10 Thread Nicholas Wilson via Digitalmars-d-learn
On Saturday, 10 November 2018 at 06:56:29 UTC, Neia Neutuladh 
wrote:

Is this right?


Are you sure you added @safe to the second example?
https://run.dlang.io/is/2RbOwK fails to compile.


Re: Dealing with raw types as attributes

2018-11-01 Thread Nicholas Wilson via Digitalmars-d-learn

On Friday, 2 November 2018 at 04:18:47 UTC, Neia Neutuladh wrote:

On Fri, 02 Nov 2018 04:01:00 +, Nicholas Wilson wrote:
By noting that all (interesting for the purpose of UDA's i.e. 
not void)

types have a .init

or you could do

static if (is(typeof(uda) == Foo) || is(uda == Foo))


Which, again, only tests for presence, when I want to check for 
presence *and* get the value, which should be Foo.init if the 
person supplied the raw type.


template GetMeTheValue(value...) if(value.length == 1)
{
static if (is(typeof(value[0].init == value[0]) // A type
enum GetMeTheValue = value[0].init;
else
enum GetMeTheValue = value[0];
}
...

static if (is(typeof(GetMeTheValue!uda) == Foo)


Re: Dealing with raw types as attributes

2018-11-01 Thread Nicholas Wilson via Digitalmars-d-learn

On Friday, 2 November 2018 at 03:13:19 UTC, Neia Neutuladh wrote:

On Fri, 02 Nov 2018 00:36:18 +, Nicholas Wilson wrote:

What do you do to handle this?


@Foo() int bar;

instead of

@Foo int bar;


Right. And if you're offering a library with UDAs for other 
people to use?


I mean I suppose if you really wanted to avoid the parentheses, 
you could do


  static foreach (uda; __traits(getAttributes, bar))
  {
static if (is(typeof(uda.init) == Foo)
{
  pragma(msg, "bar is @Foo");
}
  }

By noting that all (interesting for the purpose of UDA's i.e. not 
void) types have a .init


or you could do

static if (is(typeof(uda) == Foo) || is(uda == Foo))


Re: Dealing with raw types as attributes

2018-11-01 Thread Nicholas Wilson via Digitalmars-d-learn
On Thursday, 1 November 2018 at 16:14:45 UTC, Neia Neutuladh 
wrote:
The spec says that a user-defined attribute must be an 
expression, but DMD accepts a wide range of things as UDAs:




Indeed UDA are odd beasts: 
https://issues.dlang.org/show_bug.cgi?id=19127



What do you do to handle this?


@Foo() int bar;

instead of

@Foo int bar;

https://run.dlang.io/is/3USj6h


Re: Removing the precision from double

2018-11-01 Thread Nicholas Wilson via Digitalmars-d-learn

On Thursday, 1 November 2018 at 23:59:26 UTC, kerdemdemir wrote:

I have two numbers

First The price  = 0.0016123
Second Maximum allowed precision = 0.0001(it can be only 
0.001, 0.0001, 0.1, ..., 0.01 bunch of zeros and 
than a one that is it)


Anything more precise than the allow precision should truncated.
So in this case 0.0016123 should turn into 0.0016.

I coded this which in my tests have no problem :

double NormalizeThePrice( double price, double tickSize)
{
import std.math : floor;
double inverseTickSize = 1.0/tickSize;
return floor(price * inverseTickSize) *  tickSize;
}

writeln(NormalizeThePrice(0.0016123, 0.0001));
Returns 1.6e-07 as excepted.

I am doing trading and super scared of suprices like 
mathematical errors during the multiplications(or division 
1/tickSize) since market will reject my orders even if there is 
a small mistake.


Is this safe? Or is there a better way of doing that ?

Erdemdem


the function you does what you describe is called quantize[1].

However be warned that dealing with money as a floating point 
type is generally not a great idea. Precision losses (especially 
when working with ranges like 10^-7) and NaNs (Sociomantic's $9T 
bug, yes 9T thats what lround(NaN) gives) [2] are thing you 
_must_ account for.


I _think_ the accepted way of dealing with it is to use an (non 
overflowing[3]!) integer representing the lowest amount (e.g. 1 
cent), and deal in integer multiples of that.


[1]: https://dlang.org/phobos/std_math.html#.quantize
[2]: https://dconf.org/2016/talks/clugston.html
[3]: https://dlang.org/phobos/core_checkedint.html


Re: link errors when using extern (C) structs

2018-10-28 Thread Nicholas Wilson via Digitalmars-d-learn

On Sunday, 28 October 2018 at 06:59:31 UTC, DanielG wrote:
For the benefit of anybody who encounters a problem like this 
in the future ... originally I had my C library "header" files 
(renamed from .di to .d after the feedback from Nicholas) in a 
special 'headers/' subdir, used as an import path in dub.json. 
I simply moved those files to the source folder and everything 
started magically working.


And thanks again, Nicholas!


Oh yeah, I didn't think to mention that you need to compile them 
for them to fix your missing symbols problem.


No problems.


Re: link errors when using extern (C) structs

2018-10-27 Thread Nicholas Wilson via Digitalmars-d-learn

On Sunday, 28 October 2018 at 04:23:27 UTC, DanielG wrote:
On Sunday, 28 October 2018 at 03:39:41 UTC, Nicholas Wilson 
wrote:

write struct Foo {
double bar = 0.0; // The bitpattern of 0.0 is 0
}


Thank you for your response.

Can you elaborate on 'write struct...'? Is that special syntax?


Nope thats me not proofreading my posts properly, sorry.

 I also checked to see if you meant "(manually re-write it 
as...)", but updating the struct definition in the generated .d 
header with field values doesn't seem to solve the __initZ 
issue, either.


Hmm thats, odd unless there are other fields with initialisers 
that are forcing its emission.



And redefining it in the client .d module just shadows the
header definition, so ...


Try not using the .di files at all. I've never had any use for 
them personally. Wrapping a C library, all thats required is 
definitions of the functions and types declared by the headers. 
this can be done with a .d file.





Re: Dub Renaming source/app.d makes project a library

2018-10-27 Thread Nicholas Wilson via Digitalmars-d-learn

On Sunday, 28 October 2018 at 03:34:57 UTC, Neia Neutuladh wrote:

targetType "executable" does it for me (dub 1.11.0).

Can you post your full dub.sdl?


I'm an idiot, I was in the wrong directory that does seem to work.


Re: link errors when using extern (C) structs

2018-10-27 Thread Nicholas Wilson via Digitalmars-d-learn

On Sunday, 28 October 2018 at 03:28:20 UTC, DanielG wrote:
I'm wrapping a C library which has a lot of structs defined, 
and I keep running into issues where dmd complains that .init 
isn't defined ("Symbol Undefined __xxx__initZ" etc).


I'm struggling to narrow it down to a simple example that 
demonstrates it - I actually made something that's kind of 
minimal, but it goes from working to breaking depending on 
whether the file extension is .di or .d, for the file 
containing the extern (C)'ed struct definitions. Also it seems 
to depend (in the .di case) on whether the C structs use double 
vs. int values for their fields. (int fields work with either 
file extension)


That is because the default initialiser for double is double.nan 
which is non-zero and therefore the default initialiser of a 
struct containing a double will have a non-zero default 
initialiser. This lives as a  __xxx__initZ symbol somewhere 
in your program.


The .di or .d is because in the case of .di the compiler assumes 
the symbols exist somewhere already and it doesn't need to (and 
can't because it would create duplicates) emit them to the object 
files.


But simply changing the file extension in my real project, of 
the header files translated by dstep, seems to have no effect.


In short, it seems that for certain C structs I cannot use them 
as a field in a D struct even with a manually-specified default 
value - I get link errors no matter what 
(init/toHash/opEquals). How can I get around that?


Am I supposed to be doing something with C structs to avoid 
these kinds of errors in my D code? I've searched the forum but 
nothing really jumps out at me as relevant.


For the __initZ symbols

struct Foo {
double bar;
}

write struct Foo {
double bar = 0.0; // The bitpattern of 0.0 is 0
}

and have only zero initialiser for you structs, which means they 
don't need to be stored.


the opEquals stems from the fact that for structs containing 
floats equality comparison cannot be implemented with bitwise 
compare.


The easiest solution is to just use .d for the extension, very 
rarely are .di files useful.


Dub Renaming source/app.d makes project a library

2018-10-27 Thread Nicholas Wilson via Digitalmars-d-learn

So I have a project that is a simple dub app with
source/
app.d

$dub
Performing "debug" build using /Library/D/dmd/bin/dmd for x86_64.
foo ~master: building configuration "application"...
Linking...
Running ./foo
Edit source/app.d to start your project.
$mv source/app.d source/foo.d
$dub
Performing "debug" build using /Library/D/dmd/bin/dmd for x86_64.
foo ~master: building configuration "library"...
Target is a library. Skipping execution.

How do I get it to continue to build in the application 
configuration by default with the renamed file?


I've tried

mainSourceFile "source/foo.d"
targetType "application"
targetType "executable"

to no avail.

Thanks
Nic


Re: Help needed to extend the core.thread

2018-10-26 Thread Nicholas Wilson via Digitalmars-d-learn

On Friday, 26 October 2018 at 01:58:47 UTC, Heromyth wrote:

Maybe it's better to extend core.thread.Thread by inheriting it.
Am I right? Thanks!


Yes, see the example at 
https://dlang.org/phobos/core_thread.html#.Thread




Re: Reading binary streams with decoding to Unicode

2018-10-15 Thread Nicholas Wilson via Digitalmars-d-learn

On Monday, 15 October 2018 at 21:48:05 UTC, Vinay Sajip wrote:
On Monday, 15 October 2018 at 19:56:22 UTC, Nicholas Wilson 
wrote:


import std.file : readText;
import std.uni : byCodePoint, byGrapheme;
// or import std.utf : byCodeUnit, byChar /*utf8*/, byWchar 
/*utf16*/, byDchar /*utf32*/, byUTF  /*utf8(?)*/;

string a = readText("foo");

foreach(cp; a.byCodePoint)
{
// do stuff with code point 'cp'
}


Your example shows reading an entire file into memory (string a 
= readText("foo")), then iterating over that. I know you can 
iterate over a string; I'm interested in iterating over a 
stream, which is perhaps read over a network or from another 
I/O source, where you can't assume you have access to all of it 
at once - just one Unicode character at a time.


Oh, sorry I missed that. Take a look at 
https://github.com/schveiguy/iopipe


Re: Reading binary streams with decoding to Unicode

2018-10-15 Thread Nicholas Wilson via Digitalmars-d-learn

On Monday, 15 October 2018 at 18:57:19 UTC, Vinay Sajip wrote:

On Monday, 15 October 2018 at 17:55:34 UTC, Dukc wrote:
This is done automatically for character arrays, which 
includes strings. wchar arrays wil iterate by UTF-16, and 
dchar arrays by UTF-32. If you have a byte/ubyte array you 
know to be unicode-encoded, convert it to char[] to iterate by 
code points.


Thanks for the response. I was looking for something where I 
don't have to manage buffers myself (e.g. when handling 
buffered file or socket I/O). It's really easy to find this 
functionality in e.g. Python, C#, Go, Kotlin, Java etc. but I'm 
surprised there doesn't seem to be a ready-to-go equivalent in 
D. For example, I can find D examples of opening files and 
reading a line at a time, but no examples of opening a file and 
reading Unicode chars one at a time. Perhaps I've just missed 
them?


import std.file : readText;
import std.uni : byCodePoint, byGrapheme;
// or import std.utf : byCodeUnit, byChar /*utf8*/, byWchar 
/*utf16*/, byDchar /*utf32*/, byUTF  /*utf8(?)*/;

string a = readText("foo");

foreach(cp; a.byCodePoint)
{
// do stuff with code point 'cp'
}

foreach(g; a.byGrapheme)
{
// do stuff with grapheme 'g'
}



Re: Trying to make FreeList Allocator example compile

2018-10-08 Thread Nicholas Wilson via Digitalmars-d-learn

On Monday, 8 October 2018 at 21:50:33 UTC, Per Nordlöw wrote:

I'm trying to compile the example

import std.experimental.allocator.building_blocks.free_list 
: FreeList;

theAllocator = allocatorObject(FreeList!8());

at https://dlang.org/phobos/std_experimental_allocator.html but 
fails first because of missing import


import std.experimental.allocator : allocatorObject, 
theAllocator;


and then, when adding this import, it fails again with the error

/home/per/Work/knet/phobos-next/snippets/gctester.d(127,40): 
Error: template instance `FreeList!8` does not match template 
declaration `FreeList(ParentAllocator, ulong minSize, ulong 
maxSize = minSize, Flag adaptive = No.adaptive)`


Why is this example missing the `ParentAllocator` template 
parameter and what is the preferred type for `ParentAllocator`?


ParentAllocator can be anything preferred types don't really make 
sense in a composable design, but it's probably best to go with 
something like GCAllocator, Mallocator, (Mmap, Sbrk etc.) 
something that asks the system for more memory for the last 
fallback so you don't run out of memory.




Re: Details on how aggregates are constructed with `new` and later destroyed by the GC

2018-10-08 Thread Nicholas Wilson via Digitalmars-d-learn

On Monday, 8 October 2018 at 11:19:40 UTC, Per Nordlöw wrote:

I want to understand how calls to `new` for classes


see _d_newclass

and structs are lowered by the compiler and druntime to a 
GC-allocation (specifically how the `ba`-argument bits are 
determined) followed by an initialization using default 
constructor or via a user-defined constructor called using 
arguments to `new`. And how this is related to the trait 
`hasElaborateConstructor` for both `classes` and `structs`.


Memory is allocated, .init (for classes this comes from 
typeid(T).initializer)

 is copied over the memory and then the constructor is run.

I also want to understand how manually defined constructors and 
destructors affect the setting of the GC finalizer for a given 
aggregate type. And how this is related to the trait 
`hasElaborateDestructor` for both `classes` and `structs`


For classes the typeid(T).destructor is called on the class, for 
structs I'm not sure.



Where's the dmd and druntime code that handles these steps?


should be src/rt/lifetime.d IIRC



Re: Is there an efficient byte buffer queue?

2018-10-08 Thread Nicholas Wilson via Digitalmars-d-learn

On Monday, 8 October 2018 at 09:39:55 UTC, John Burton wrote:

My use case is sending data to a socket.

One part of my program generates blocks of bytes, and the 
socket part tries to send them to the socket and then removes 
from the queue the number that got sent.


[...]


Try searching for "circular buffer". I'm sure 
http://code.dlang.org/packages/iopipe has them in some form but I 
can't find them with a cursory search.


Re: Is there a function for this?

2018-10-06 Thread Nicholas Wilson via Digitalmars-d-learn

On Saturday, 6 October 2018 at 13:17:22 UTC, bauss wrote:
Let's say you have a range with struct, but some of the struct 
are duplicates of each other.


Is there a standard function in Phobos to remove duplicates?

My first thought was "uniq", but it can't really do it like 
that, but it doesn't work.


See: https://run.dlang.io/is/IcFEtw

Is there another function in Phobos that perhaps would work?

I can of course write my own function, but if there is a 
standard function that can do it, then I'd rather use that.


range
.array.sort // make equal elements be adjacent
.chunks!"a==b" // get a range over those equal elements
.map(e => e.front); // get the first one

should work, possibly not the most efficient way to do it though.

I don't know off the top of mu head if there are any to preserve 
the order or the original range.


Re: Error: variable 'xyz' has scoped destruction, cannot build closure

2018-10-05 Thread Nicholas Wilson via Digitalmars-d-learn

On Friday, 5 October 2018 at 19:31:56 UTC, Jon Degenhardt wrote:

On Friday, 5 October 2018 at 16:34:32 UTC, Paul Backus wrote:
You can thread multiple arguments through to `each` using 
`std.range.zip`:


tenRandomNumbers
.zip(repeat(output))
.each!(unpack!((n, output) => 
output.appendln(n.to!string)));


Full code: https://run.dlang.io/is/Qe7uHt


Very interesting, thanks. It's a clever way to avoid the 
delegate capture issue.


(Aside: A nested function that accesses 'output' from lexical 
context has the same issue as delegates wrt to capturing the 
variable.)


Note that this solution may do a lot of output and hence running 
of the destructor.


Use: `.zip(repeat())` to avoid that.




Re: Error: variable 'xyz' has scoped destruction, cannot build closure

2018-10-05 Thread Nicholas Wilson via Digitalmars-d-learn

On Friday, 5 October 2018 at 06:44:08 UTC, Nicholas Wilson wrote:
Alas is does not because each does not accept additional 
argument other than the range. Shouldn't be hard to fix though.


https://issues.dlang.org/show_bug.cgi?id=19287


Re: Error: variable 'xyz' has scoped destruction, cannot build closure

2018-10-05 Thread Nicholas Wilson via Digitalmars-d-learn

On Friday, 5 October 2018 at 06:22:57 UTC, Nicholas Wilson wrote:
tenRandomNumbers.each!((n,o) => 
o.appendln(n.to!string))(output);


or

tenRandomNumbers.each!((n, ref o) => 
o.appendln(n.to!string))(output);


should hopefully do the trick (run.dlang.io seems to be down 
atm).




Alas is does not because each does not accept additional argument 
other than the range. Shouldn't be hard to fix though.


Re: Error: variable 'xyz' has scoped destruction, cannot build closure

2018-10-05 Thread Nicholas Wilson via Digitalmars-d-learn

On Friday, 5 October 2018 at 03:27:17 UTC, Jon Degenhardt wrote:
I got the compilation error in the subject line when trying to 
create a range via std.range.generate. Turns out this was 
caused by trying to create a closure for 'generate' where the 
closure was accessing a struct containing a destructor.


The fix was easy enough: write out the loop by hand rather than 
using 'generate' with a closure. What I'm wondering/asking is 
if there alternate way to do this that would enable the 
'generate' approach. This is more curiosity/learning at this 
point.


Below is a stripped down version of what I was doing. I have a 
struct for output buffering. The destructor writes any data 
left in the buffer to the output stream. This gets passed to 
routines performing output. It was this context that I created 
a generator that wrote to it.


example.d-
struct BufferedStdout
{
import std.array : appender;

private auto _outputBuffer = appender!(char[]);

~this()
{
import std.stdio : write;
write(_outputBuffer.data);
_outputBuffer.clear;
}

void appendln(T)(T stuff)
{
import std.range : put;
put(_outputBuffer, stuff);
put(_outputBuffer, "\n");
}
}

void foo(BufferedStdout output)
{
import std.algorithm : each;
import std.conv : to;
import std.range: generate, takeExactly;
import std.random: Random, uniform, unpredictableSeed;

auto randomGenerator = Random(unpredictableSeed);
auto randomNumbers = generate!(() => uniform(0, 1000, 
randomGenerator));

auto tenRandomNumbers = randomNumbers.takeExactly(10);
tenRandomNumbers.each!(n => output.appendln(n.to!string));
}

void main(string[] args)
{
foo(BufferedStdout());
}
End of  example.d-

Compiling the above results in:

   $ dmd example.d
   example.d(22): Error: variable `example.foo.output` has 
scoped destruction, cannot build closure


As mentioned, using a loop rather than 'generate' works fine, 
but help with alternatives that would use generate would be 
appreciated.


The actual buffered output struct has more behind it than shown 
above, but not too much. For anyone interested it's here:  
https://github.com/eBay/tsv-utils/blob/master/common/src/tsvutil.d#L358


tenRandomNumbers.each!((n,o) => o.appendln(n.to!string))(output);

or

tenRandomNumbers.each!((n, ref o) => 
o.appendln(n.to!string))(output);


should hopefully do the trick (run.dlang.io seems to be down atm).


The problem is that `output` is captured by the delegate and this 
somehow causes problems (idk what or why). If the (perviously 
captured) variables are instead passed as parameters then there 
is no need to create a closure for the variable, so no problem.
This is also the way to ensure that lambdas are @nogc if you ever 
need that.




Re: Wrong module initialization order when building with Dub on Windows?

2018-10-01 Thread Nicholas Wilson via Digitalmars-d-learn
On Tuesday, 2 October 2018 at 01:57:00 UTC, Vladimir Panteleev 
wrote:
Ran into this today, don't have time to dig in now but maybe 
someone ran into this too.


Steps to reproduce:

- git clone https://github.com/CyberShadow/ae
- cd ae/demo/inputtiming
- (download/unpack 
https://www.libsdl.org/release/SDL2-2.0.8-win32-x86.zip or 
https://www.libsdl.org/release/SDL2-2.0.8-win32-x64.zip to 
current directory)

- dub

On Windows, I get a range violation (in ae.sys.log) which 
indicates that Runtime.args has length 0, which should never 
happen.


This doesn't happen if I build as usual with rdmd, or on Linux 
(either rdmd or Dub).


I'd take a look at what arguments are passed to DMD with rdmd vs. 
dub.

Maybe to module order is different?


Re: New With Struct and Getting Class Object Pointers

2018-09-30 Thread Nicholas Wilson via Digitalmars-d-learn

On Sunday, 30 September 2018 at 09:30:38 UTC, Vijay Nayar wrote:
Is there a way to either have a constant reference to a class 
that can be set to a new value, or is there a way to convert 
the class variable to a class pointer?


Alex has mentioned Rebindable, which is the answer to your first 
question.

To answer your second question, no

class A {}

A a:

`a` is always a (possibly null) reference to a class instance. 
You can have pointers to class references (which is what `` 
gives you) but that has two indirections between the variable and 
the data, which if you want high perf is probably not what you 
are looking for.


Re: New With Struct and Getting Class Object Pointers

2018-09-30 Thread Nicholas Wilson via Digitalmars-d-learn

On Sunday, 30 September 2018 at 07:29:00 UTC, Vijay Nayar wrote:

I have two brief questions.

Code that uses "new" to create struct objects appears to 
compile and run. Is this an actual language feature, to get 
structs on the heap?


void main()
{
struct S {int data = 1;}
S* s1 = new S();
S* s2 = s1;
S s3 = *s1;  // Still copies on assignment.
s3.data = 2;
assert(s1.data != s3.data);
}

Second question. const class variables may not be re-assigned, 
so if you need a variable that may be reassigned, but may never 
modify the underlying object, a const pointer can be useful.  
However, it seems that when gets the address of a class 
variable, you do not get the underlying address of the class 
object.


How do you get a pointer to the underlying class object?  
Example of the problem:


void main()
{
import std.stdio;
class A { int data = 3; }
A a = new A();

void f(A a) {
a.data = 4;
writeln(" = ", , ", a.data = ", a.data);
}

f(a);
writeln(" = ", , ", a.data = ", a.data);
}

// Output:
 = 7FFEA6BA3158, a.data = 4  // Addresses are different, from 
different class variables.
 = 7FFEA6BA3180, a.data = 4  // But the same underlying class 
object.


Especially if I'm several levels down the call stack, how do I 
get a pointer to the underlying class object?


the variable `a` is a pointer (well, actually reference) to the 
underlying data.


void main()
{
import core.stdc.stdio;
class A { int data = 3; }
A a = new A();

void f(A a) {
a.data = 4;
printf(" = %p, a = %p, a.data=%d\n", , a,a.data);
}

f(a);
printf(" = %p, a = %p, a.data=%d\n", ,a, a.data);
}

 = 0x7ffd0800acb8, a = 0x7fd6b05b, a.data=4
 = 0x7ffd0800acd0, a = 0x7fd6b05b, a.data=4

 The stack ^ the heap^  data on 
the heap^
The address of the variable a on the stack has different values 
across function calls, its value (the reference to the class 
data) remains the same, as does the data itself.




Re: How to use math functions in dcompute?

2018-09-20 Thread Nicholas Wilson via Digitalmars-d-learn
On Thursday, 20 September 2018 at 12:43:02 UTC, Nicholas Wilson 
wrote:

Hmm, I can reproduce. Will look into it.


pragma(LDC_intrinsic, "llvm.nvvm.cos.approx.f")
float cos(float val);

does work but is an approximation.


Re: How to use math functions in dcompute?

2018-09-20 Thread Nicholas Wilson via Digitalmars-d-learn

On Thursday, 20 September 2018 at 05:16:04 UTC, Sobaya wrote:
On Wednesday, 19 September 2018 at 00:22:44 UTC, Nicholas 
Wilson wrote:
On Wednesday, 19 September 2018 at 00:11:13 UTC, Nicholas 
Wilson wrote:

On Tuesday, 18 September 2018 at 06:25:33 UTC, Sobaya wrote:
On Tuesday, 18 September 2018 at 01:39:51 UTC, Nicholas 
Wilson wrote:

On Tuesday, 18 September 2018 at 00:25:33 UTC, Sobaya wrote:

I'm waiting for the update. How's your progress?


I t appears I have broke SPIR-V completely somewhere along 
the line, I may release a v0.2 with out it, hopefully 
within the week.


I declared like:

pragma(LDC_intrinsic, "llvm.nvvm.cos.f32")
T cos(T)(T val)
if (__traits(isFloating, T));

It also doesn't work.


 pragma(LDC_intrinsic, "llvm.nvvm.cos.f#") // note the # in 
place of 32

T cos(T)(T val)
 if (__traits(isFloating, T));
(Just don't use real with it.)

OR

pragma(LDC_intrinsic, "llvm.nvvm.cos.f32")
 float cos(float val)


And if they don't work, use

 pragma(LDC_intrinsic, "llvm.cos.f#") // note the # in place 
of 32

T cos(T)(T val)
 if (__traits(isFloating, T));
(Just don't use real with it.)


"llvm.nvvm.cos.f#" and "llvm.nvvm.cos.f32" don't work.

And when I use "llvm.cos.f#", Another error occurred in linking.

LLVM ERROR: Cannot select: 0xe0d4798: f32 = fcos 
ConstantFP:f32<0.00e+00>

  0xe0b9db0: f32 = ConstantFP<0.00e+00>


Hmm, I can reproduce. Will look into it.


Re: How to use math functions in dcompute?

2018-09-18 Thread Nicholas Wilson via Digitalmars-d-learn
On Wednesday, 19 September 2018 at 00:11:13 UTC, Nicholas Wilson 
wrote:

On Tuesday, 18 September 2018 at 06:25:33 UTC, Sobaya wrote:
On Tuesday, 18 September 2018 at 01:39:51 UTC, Nicholas Wilson 
wrote:

On Tuesday, 18 September 2018 at 00:25:33 UTC, Sobaya wrote:

I'm waiting for the update. How's your progress?


I t appears I have broke SPIR-V completely somewhere along 
the line, I may release a v0.2 with out it, hopefully within 
the week.


I declared like:

pragma(LDC_intrinsic, "llvm.nvvm.cos.f32")
T cos(T)(T val)
if (__traits(isFloating, T));

It also doesn't work.


 pragma(LDC_intrinsic, "llvm.nvvm.cos.f#") // note the # in 
place of 32

T cos(T)(T val)
 if (__traits(isFloating, T));
(Just don't use real with it.)

OR

pragma(LDC_intrinsic, "llvm.nvvm.cos.f32")
 float cos(float val)


And if they don't work, use

 pragma(LDC_intrinsic, "llvm.cos.f#") // note the # in place of 
32

T cos(T)(T val)
 if (__traits(isFloating, T));
(Just don't use real with it.)



Re: How to use math functions in dcompute?

2018-09-18 Thread Nicholas Wilson via Digitalmars-d-learn

On Tuesday, 18 September 2018 at 06:25:33 UTC, Sobaya wrote:
On Tuesday, 18 September 2018 at 01:39:51 UTC, Nicholas Wilson 
wrote:

On Tuesday, 18 September 2018 at 00:25:33 UTC, Sobaya wrote:

I'm waiting for the update. How's your progress?


I t appears I have broke SPIR-V completely somewhere along the 
line, I may release a v0.2 with out it, hopefully within the 
week.


I declared like:

pragma(LDC_intrinsic, "llvm.nvvm.cos.f32")
T cos(T)(T val)
if (__traits(isFloating, T));

It also doesn't work.


 pragma(LDC_intrinsic, "llvm.nvvm.cos.f#") // note the # in place 
of 32

T cos(T)(T val)
 if (__traits(isFloating, T));
(Just don't use real with it.)

OR

pragma(LDC_intrinsic, "llvm.nvvm.cos.f32")
 float cos(float val)


Re: How to use math functions in dcompute?

2018-09-17 Thread Nicholas Wilson via Digitalmars-d-learn

On Tuesday, 18 September 2018 at 00:25:33 UTC, Sobaya wrote:

I'm waiting for the update. How's your progress?


I t appears I have broke SPIR-V completely somewhere along the 
line, I may release a v0.2 with out it, hopefully within the week.


Re: How to use math functions in dcompute?

2018-09-17 Thread Nicholas Wilson via Digitalmars-d-learn

On Tuesday, 18 September 2018 at 00:25:33 UTC, Sobaya wrote:

On Friday, 7 September 2018 at 10:53:25 UTC, Sobaya wrote:
On Friday, 7 September 2018 at 10:17:47 UTC, Nicholas Wilson 
wrote:

On Friday, 7 September 2018 at 06:45:32 UTC, Sobaya wrote:

[...]


You're missing an "m" in "nvvm", dunno if that will fix it.


[...]


I'll be adding these to DCompute soon (probably Sunday), 
LLVM7.0 has just been released and I've been waiting on that 
to do testing.


I understand about the release.

But missing "m" is just my typo here. I wrote "llvm.nvvm.cos" 
correctly on my code, and error occurred.


I'm waiting for the update. How's your progress?

Still it doesn't work well in my environment.

If you know temporary solution for use "cos" or "sin", I want 
to try it.


Thank you.


Sorry you need to add a size for the argument "llvm.nvvm.cos.f32" 
for float or copy what is done in ldc/intrinsics.di with a 
template for "llvm.nvvm.cos.f#"





Re: dub windows unrecognised file extension a

2018-09-08 Thread Nicholas Wilson via Digitalmars-d-learn
On Sunday, 9 September 2018 at 04:53:05 UTC, Nicholas Wilson 
wrote:
On Sunday, 9 September 2018 at 04:01:30 UTC, Nicholas Wilson 
wrote:
On windows with dub it seems to be creating libfoo.a instead 
of foo.lib, I don't think I changed any settings. Old build 
based on 2.078 DMDFE seem to have built .lib but LDC based on 
2.082 seems to be building .a


This definitely seems to be dubs fault: it passes 
-of/path/to/output/libFoo.a to LDC which compiles. `dub 
describe` also has


{
...
"packages" : [
...
{
...
"targetFileName" : "libFoo.a",


https://github.com/dlang/dub/pull/1559

Ugh time to recompile LLVM & LDC again.


Re: dub windows unrecognised file extension a

2018-09-08 Thread Nicholas Wilson via Digitalmars-d-learn
On Sunday, 9 September 2018 at 04:01:30 UTC, Nicholas Wilson 
wrote:
On windows with dub it seems to be creating libfoo.a instead of 
foo.lib, I don't think I changed any settings. Old build based 
on 2.078 DMDFE seem to have built .lib but LDC based on 2.082 
seems to be building .a


This definitely seems to be dubs fault: it passes 
-of/path/to/output/libFoo.a to LDC which compiles. `dub describe` 
also has


{
...
"packages" : [
...
{
...
"targetFileName" : "libFoo.a",




dub windows unrecognised file extension a

2018-09-08 Thread Nicholas Wilson via Digitalmars-d-learn
On windows with dub it seems to be creating libfoo.a instead of 
foo.lib, I don't think I changed any settings. Old build based on 
2.078 DMDFE seem to have built .lib but LDC based on 2.082 seems 
to be building .a




Re: How to use math functions in dcompute?

2018-09-07 Thread Nicholas Wilson via Digitalmars-d-learn

On Friday, 7 September 2018 at 06:45:32 UTC, Sobaya wrote:

Sorry for being late for reply.

I'm using CUDA for back-end.

So you mean if required function is "cos",

pragma(LDC_intrinsic, "llvm.nvv.cos")
T cos(T a);

Is it right?



You're missing an "m" in "nvvm", dunno if that will fix it.

I tried this declaration, but I got an error diffrent from 
previous one:


dcompute.driver.error.DComputeDriverException@../../.dub/packages/dcompute-master/dcompute/source/dcompute/driver/error.d(172):
 cast(Status)218

??:? [0x48739e]
??:? [0x48f8aa]
??:? [0x47942d]
error.d:172 [0x42fe61]
error.d:167 [0x42fdb4]
error.d:187 [0x42feca]
program.d:30 [0x42fc00]
app.d:13 [0x417bea]
??:? [0x47908f]
??:? [0x478f85]
__entrypoint.d:8 [0x4289f4]
??:? __libc_start_main [0x2b85f455282f]
??:? [0x405c08]
Program exited with code 1

My declaration is wrong?

Or fixed LLVM(LDC?) is already released?

How can I use it ?


I'll be adding these to DCompute soon (probably Sunday), LLVM7.0 
has just been released and I've been waiting on that to do 
testing.


Re: How to use math functions in dcompute?

2018-08-31 Thread Nicholas Wilson via Digitalmars-d-learn

On Thursday, 30 August 2018 at 10:34:33 UTC, Sobaya wrote:
On Monday, 27 August 2018 at 12:47:45 UTC, Nicholas Wilson 
wrote:

On Monday, 27 August 2018 at 09:57:18 UTC, Sobaya wrote:

On Monday, 27 August 2018 at 09:41:34 UTC, 9il wrote:

On Monday, 27 August 2018 at 08:25:14 UTC, Sobaya wrote:

I'm using dcompute(https://github.com/libmir/dcompute).

In the development, I have got to use math functions such 
as sqrt in @compute function.


But LDC says "can only call functions from other @compute 
modules in @compute code", so can't I call any math 
functions with dcompute?


Is there any way to use predefined math functions in 
dcompute?


Thanks.


You may want to try ldc.intrinsics / mir.math.common


Do you mean llvm_sqrt in ldc.intrinsics?

These functions are also not @compute code, so they cause the 
same error.


Thanks for bringing this to my attention, will fix soon. In 
the meantime you may declare your own intrinsics in a @compute 
module and it should work. as in


@compute module mymath;

pragma(LDC_intrinsic, "llvm.sqrt.f#")
T llvm_sqrt(T)(T val)
if (__traits(isFloating, T));


This will work if you are targeting CUDA, SPIRV may not like 
it because the backend is less... mature.


Thank you for replaying.

Surely the definition you told me works for "sqrt".
But "cos" and "sin" does not work.
The error message is

LLVM ERROR: Cannot select: 0xd76ffd8: f32 = fcos 
ConstantFP:f32<0.00e+00>

   0xd76ff70: f32 = ConstantFP<0.00e+00>

What's wrong?


SPIR-V or CUDA?

for SPIR-V try

pragma(mangle, "_Z3sinf")
float sin(float);
pragma(mangle, "_Z3cosf")
float cos(float);

more generally see 
https://github.com/KhronosGroup/SPIR-Tools/wiki/SPIR-2.0-built-in-functions


If this is a problem with CUDA you could try using the NVPTX 
intrinsics


pragma(LDC_intrinsic, "llvm.nvvm.namegoeshere")
T namegoeshere(Args a);

If you need to use both SPIR-V and CUDA then see the hackery e.g. 
https://github.com/libmir/dcompute/blob/master/source/dcompute/std/index.d#L45


LLVM will be released on September 5th I will fix up this shortly 
after.


Sorry for the alpha state of things right now.

Nic


Re: How to use math functions in dcompute?

2018-08-27 Thread Nicholas Wilson via Digitalmars-d-learn

On Monday, 27 August 2018 at 09:57:18 UTC, Sobaya wrote:

On Monday, 27 August 2018 at 09:41:34 UTC, 9il wrote:

On Monday, 27 August 2018 at 08:25:14 UTC, Sobaya wrote:

I'm using dcompute(https://github.com/libmir/dcompute).

In the development, I have got to use math functions such as 
sqrt in @compute function.


But LDC says "can only call functions from other @compute 
modules in @compute code", so can't I call any math functions 
with dcompute?


Is there any way to use predefined math functions in dcompute?

Thanks.


You may want to try ldc.intrinsics / mir.math.common


Do you mean llvm_sqrt in ldc.intrinsics?

These functions are also not @compute code, so they cause the 
same error.


Thanks for bringing this to my attention, will fix soon. In the 
meantime you may declare your own intrinsics in a @compute module 
and it should work. as in


@compute module mymath;

pragma(LDC_intrinsic, "llvm.sqrt.f#")
T llvm_sqrt(T)(T val)
if (__traits(isFloating, T));


This will work if you are targeting CUDA, SPIRV may not like it 
because the backend is less... mature.


  1   2   3   4   5   6   7   >