Calling scipy from C extension - scipy

I would like to load one of the scipy modules (scipy.linalg) inside a function which is exported from a python extension written in C++, so that I can then call a function from it. It would be best if the user to does not have to load the module in their python program beforehand (so PyImport_AddModule is not the solution).
Code using the high level PyImport_Import like this
pckg_name = PyString_FromString("scipy.linalg");
pckg = PyImport_Import(pckg_name);`
works, as recommended here, except in Python 3.6 it produces a warning message before working.
C:\Program Files\Python36\lib\importlib\_bootstrap.py:205:
ImportWarning: can't resolve package from __spec__ or __package__,
falling back on __name__ and __path__
return f(*args, **kwds)
What does the message mean? Its presence suggests I am not doing this the right way. What is the right way to do this?

Related

MPI Autocompletion in Visual Studio Code

I'm trying to use Visual Studio Code to develop Fortran MPI programs. However, while I can successfully build and run them just fine, it would be very helpful for me if I can use intellisense/autocompletion features for MPI (as well as other external modules). I have /usr/lib/openmpi/ (which contains mpi_f08.mod) as part of fortran.includePaths in my settings.json. However, when I use mpi_f08, I get the problem message from VS Code Module "mpi_f08" not found in project. Here is a minimal CMake build example:
! hello.f90
program hello
use mpi_f08
implicit none
integer :: ierror, nproc, my_rank
call MPI_Init()
call MPI_Comm_size(MPI_COMM_WORLD, nproc, ierror)
call MPI_Comm_rank(MPI_COMM_WORLD, my_rank, ierror)
print*, "hello from rank ", my_rank
call MPI_Finalize()
end program hello
# CMakeLists.txt
cmake_minimum_required(VERSION 3.12)
project(hello_mpi)
enable_language(Fortran)
find_package(MPI REQUIRED)
add_executable(hello_mpi hello.f90)
include_directories(${MPI_Fortran_INCLUDE_PATH})
target_link_libraries(hello_mpi PUBLIC ${MPI_Fortran_LIBRARIES})
I would like to be able to (i) get rid of the warning/message and more importantly (ii) enable suggestions from MPI when I press CTRL+space as it would if I was calling from an internal module.
I'll post a partial answer since it's better than nothing, hopefully this helps someone else and/or enables someone else to answer my question fully.
It seems the issue relates to the Fortran language server, which can be configured by adding a .fortls JSON file, as explained on its Github README: https://github.com/hansec/fortran-language-server
I added the following, which allowed it to find not only local modules but also MPI (and the external module json-fortran):
{
"source_dirs": ["src", "."],
"ext_source_dirs": [
"/path/to/json-fortran/src",
"/path/to/openmpi-4.1.2/ompi/mpi/fortran/use-mpi-f08",
]
}
This doesn't capture all functions in json-fortran, which I think is because of its .inc files, as it doesn't give me function pointers like json_file::get at autocomplete.
As for MPI, this kind of works, as it gives me all the functions I can think of needing, but with _f08 appended to the end of it. I don't know the inner workings of OpenMPI but I guess e.g. MPI_Init wraps MPI_Init_f08 for reasons of backward compatibility. For now I can simply autocomplete to the _f08 version and remove that bit manually. (I also tried adding openmpi-4.1.2/ompi/mpi/fortran/use-mpi-tkr and openmpi-4.1.2/ompi/mpi/fortran/mpif.h but no luck).
Would be nice to get this detail sorted though. It is also mildly annoying that I must manually include the source dirs now (removing it makes it not find local modules).

How to tell MakeMaker to add exactly the libraries I want?

I'm using XS to create a Perl Module which uses a C library.
For testing purposes, I've created a test library which has two simple functions:
void kzA() (does a simple printf)
void kzB(int i, char *str) (does a printf of the received parameters)
I've also created some glue in XS, in order, for now, to access the kzA() function:
(I'm only showing the function itself, but the includes are there, too, in the XS)
void
ka()
CODE:
printf("Before kzA()\n");
kzA();
printf("After kzA()\n");
So, I compiled the test library as fc.so, and it is in the same directory as my xs file, and my Makefile.PL (/workspace/LirePivots)
In my Makefile.PL, I set the LIBS key to ['-L/workspace/LirePivots -l:fc.so'], but when executing it with perl (perl Makefile.PL), it says "Warning (mostly harmless): No library found for -l:fc.so"
It then writes a Makefile which does NOT mention said library. And then, after compiling (with "make") and installing (with "sudo make install"), when I run my test script which calls the ka() function from my module, I get the line "before", but the kzA() function isn't called, obviously, because it cannot find the kzA symbol, and the program stops there.
Creating a C test program which I would link with the very same arguments (-l:fc.so -L/workspace/LirePivots) does work, and, as long as I put the path in LD_LIBRARY_PATH, it finds the function and runs it correctly.
I also tried renaming the library libfc.so, and changing the -l part to "-lfc", but it didn't work either. It never manages to find the library.
Does anyone know what I do wrong ?
EDIT:
As requested, I created a minimum example: https://github.com/kzwix/xsTest
To run it, you'll need to have a Linux with Perl 5, along with XS (package perl-devel, on Redhat). And a C compiler, and make, obviously.
Ok, I still don't know the reason why it wouldn't find the library. But I found a workaround:
By adding the test library as "libfc.so" to /usr/lib, then running "sudo ldconfig", the library got added to the cache (when named fc.so, even if in /usr/lib, ldconfig would not add it. Also, it wouldn't work with symbolic links, either, I had to really copy it there).
After the library got added to the cache, "perl Makefile.PL" would still not find the library. I had to use "-L/usr/lib" in addition to "-lfc" for it to at long last find the library, and "agree" to add the parameters to the link step of the library.
After this happened, I could compile with "make", and executing the test program did work as originally intended (I saw both the "before" and "after" printf, and I saw the one from the function in the kzA() function from libfc.so)
Thanks Håkon Hægland for helping.
(I can't provide the Dockerfiles, they link to images internal to my organization, which I'm not allowed to share)

Require module in Atom's init.coffee

I've already Google'd for an answer, since this is a common problem, but all the replies point in using alternatives instead of explaining why this doesn't work, so I'm asking here.
I put this code in my Atom's init.coffee script:
beautify = require('js-beautify').html
But Atom fails with Failed to load init.coffee and Cannot find module 'js-beautify'. Curiously enough, this works on a package and this works if I type the exact same code on Atom's console.
Of course, I could write a package for this, in fact there are a couple available, this is just an example because I want to learn how to require modules from init.coffee for future tweaks.
Thanks a lot!
When you require() from init.coffee, Atom looks for those modules in its own path. An example of where you might want to do that is if you had oni = require('oniguruma') to get access to regular expression functions.
In order to get to js-beautify, you have to specify its complete path. So far, only explicitly declaring the entire absolute path has worked for me:
beaut = require 'C:\\Users\\<username>\\.atom\\packages\\atom-beautify\\node_modules\\js-beautify'
console.log beaut
In practice, the most reliable way to use a module like this is to globally install it so that you can link to your global NPM folder. Linking to a module inside a package will break if the package is ever uninstalled.

How to set Environment Variables with SystemVerilog?

My current project sets an environment variable in a perl module and then later on makes a call from a SystemVerilog file to a function that uses that variable. The requirement is that whatever we added in the perl module is present in the environment variable on time of the call.
The problem however is that something between the perl module and systemverilog call meddles with my variable. I can't figure out what it is and fixing this issue is not pertinent to my project so I just want to set the variable to whatever the perl module sets it to and move on.
There's a handy getenv function in Perl and I am able to use getenv in SV as well. But there doesn't seem to be a setenv. What is the appropriate way to set an environment variable in SV?
Is the perl code invoked from within SystemVerilog using a $system() call? If so, environment changes made by the perl code will definitely NOT propagate back to the SV world, because those changes are made only in the $system() subprocess's environment.
The setenv() system call works for me via SystemVerilog DPI-C in all the tools I use (recent Fedora OS, recent versions of Mentor/Cadence/Synopsys simulators), but there may be some older *nix systems on which it's not available. I used the prototype as given in "man 3 setenv". Looking at discussions on other StackOverflow forums, it seems that using putenv() is not a great idea, especially from the DPI where you have no idea what will happen to the memory used for the DPI string argument. setenv() makes a copy of its argument strings, and should not be at risk from that problem.
It seems to me that if your tool flow isn't correctly propagating environment variables in the way you intend, then you have bigger problems than how to mess with the env from SystemVerilog. I specifically chose NOT to add environment-modifying functions to the svlib utility library, precisely because using the environment is a very bad way to communicate information within a SV simulation. I guess it would make sense if you need to set up an environment for some external program that you would then invoke using a SV $system() call.
Mh... Turns out the answer is trivial but this is the only thread to this question so I'll leave it up in case someone else finds themselve in a similar situation:
SystemVerilog does not have a setenv( ) or getenv( ) function. They're actually implemented from C using the following construct:
module/program foo();
import "DPI-C" function <return type> foonction(<function arguments>);
endmodule/program;
Apparently in my case someone had done this for getenv( ) but never setenv ( ). Reason I didn't catch it was because my code in question was included the following way:
**foo.sv**
if(var.bit) begin
call_function();
use_environment_variable();
end
**bar.sv**
module bar();
<do stuff>
`include foo.sv <-- foo code is copied in after calculations have occured.
endmodule
Trying to import DPI-C in foo.sv will trigger an error because the import will arrive after calculations have taken place. To solve this we need to import in bar.sv like so:
module bar();
import "DPI-C" function int setenv(string name, string value, int override);
<do stuff>
`include foo.sv
endmodule
Setting environment variables from SV is not very useful unless you are running another executable from SV.
If you want to get environment variables, you can use Verilab's svlib functions:
function automatic string sys_getEnv(string envVar);
function automatic bit sys_hasEnv(string envVar);

simscript executable file is missing

I am trying to get my feet wet in SimScript simulation.
I wrote a simple code contains a function that returns the its first parameter.
This is my code:
preamble
define Normal.fn as a double function
end
function Normal.fn (means, f)
define means, f as double variables
return (means)
end
main
let x = Normal.fn(2.1,3.1)
end
However, when I execute the project, I got an error message states:
The executable file MyProject.exe is missing
I build and rebuild the project many times, but I am still having this problem.
I noticed in my executable folder, the MyProject.exe has not been generated.
I don't know what is going on, I am new to this programming language.
Could you help please?
I found the solution myself,
It was a missing library in the simscript version 3, i check the simscript version 2 libraries through file system and I found it, it is the one named "IDebugC.c"