mpi4py Split_type using openmpi's OMPI_COMM_TYPE_SOCKET - mpi

Is it possible to split a communicator using openmpi's OMPI_COMM_TYPE_SOCKET in mpi4py?
I've verified this works:
from mpi4py import MPI
comm = MPI.COMM_WORLD
sharedcomm = comm.Split_type(MPI.COMM_TYPE_SHARED)
but this does not:
socketcomm = comm.Split_type(MPI.OMPI_COMM_TYPE_SOCKET)
nor does this:
socketcomm = comm.Split_type(MPI.COMM_TYPE_SOCKET)
I've looked at the docs but I can't find anything about this.

mpi4py only provides a wrapper around standard MPI features. OMPI_COMM_TYPE_SOCKET is an Open MPI specific split type. You may still use it in mpi4py if you know its numeric value as it is just a member of a C enum:
/*
* Communicator split type constants.
* Do not change the order of these without also modifying mpif.h.in
* (see also mpif-common.h.fin).
*/
enum {
MPI_COMM_TYPE_SHARED,
OMPI_COMM_TYPE_HWTHREAD,
OMPI_COMM_TYPE_CORE,
OMPI_COMM_TYPE_L1CACHE,
OMPI_COMM_TYPE_L2CACHE,
OMPI_COMM_TYPE_L3CACHE,
OMPI_COMM_TYPE_SOCKET, // here
OMPI_COMM_TYPE_NUMA,
OMPI_COMM_TYPE_BOARD,
OMPI_COMM_TYPE_HOST,
OMPI_COMM_TYPE_CU,
OMPI_COMM_TYPE_CLUSTER
};
#define OMPI_COMM_TYPE_NODE MPI_COMM_TYPE_SHARED
Being a member of an enum means that the actual numerical value of OMPI_COMM_TYPE_SOCKET depends on its position in the enum and hence may differ from one release of Open MPI to another. You have several options here.
Hardcode the value
This is the simplest option. Open mpi.h (ompi_info --path incdir gives you its location), count the position of OMPI_COMM_TYPE_SOCKET in the enclosing enum starting with 0 for MPI_COMM_TYPE_SHARED and hardcode the value. The code may break with releases of Open MPI different from yours.
Parse mpi.h
Read mpi.h, search for enum definitions and find the one containing OMPI_COMM_TYPE_SOCKET. Provided that MPI_COMM_TYPE_SHARED is 0, the value of OMPI_COMM_TYPE_SOCKET is its 0-based index in the sequence of enum values. This depends a lot on the code in mpi.h having a specific format and can easily break if that changes.
Parse mpif.h
The Fortran interface is easier to parse as there the value is defined as:
parameter (OMPI_COMM_TYPE_SOCKET=6)
This is easily parsable with a simple regular expression. The problem is that recent versions of Open MPI split mpif.h over a couple of files that are then included from mpif.h and currently the value is in mpif-constants.h. So you may need to parse the include statements and recurse into the files they reference. Note that those are Fortran include statements and not preprocessor #include directives.
Code generation
Write a small C program that outputs the value of OMPI_COMM_TYPE_SOCKET to a Python file and run it as part of your program's setup procedure. Something like:
#include <stdio.h>
#include <mpi.h>
int main (int argc, char **argv)
{
if (argc != 2)
{
printf("Usage: mkompimod /path/to/module.py\n");
return 1;
}
FILE *fh = fopen(argv[1], "w");
if (fh != NULL) {
fprintf(fh, "COMM_TYPE_SOCKET = %d\n", OMPI_COMM_TYPE_SOCKET);
fclose(fh);
}
return 0;
}
Put that in a file named mkompimod.c. Compile with mpicc -o mkompimod mkompimod.c and run with mkompimod /path/to/ompi.py to create a Python file ompi.py with the value of OMPI_COMM_TYPE_SOCKET. Import it and use it in the call to comm.Split_type():
import ompi
socketcomm = comm.Split_type(ompi.COMM_TYPE_SOCKET)
Write a Python module in C
That's a bit involved, but you can write a C module that includes mpi.h and exports the value of OMPI_COMM_TYPE_SOCKET as a Python constant. Consult the Python documentation on how to write extensions in C.
Use the CFFI module
CFFI lets you build Python modules that wrap C libraries and writes all the glue code for you. Put the following in a file named ompi_build.py:
from cffi import FFI
ffi = FFI()
ffi.set_source("ompi", r"#include <mpi.h>")
ffi.cdef(
r"""
const int OMPI_COMM_TYPE_HWTHREAD;
... more constants here ...
const int OMPI_COMM_TYPE_SOCKET;
... even more constants here ...
"""
)
if __name__ == "__main__":
ffi.compile(verbose=True)
Run like this:
$ CC=mpicc python ompi_build.py
This will create the C module ompi.c and compile it into a loadable DSO. You may then import it and access the constant like this:
from ompi.lib import OMPI_COMM_TYPE_SOCKET
socketcomm = comm.Split_type(OMPI_COMM_TYPE_SOCKET)
CFFI provides integration with Python's distutils and you can have it automatically build the C module as part of the setup process.
Use Cython
That's what mpi4py itself is written in. It blends C and Python into a single cryptic syntax. Read the source code. Try to figure out what's going on and how to write something yourself. Can't help you there.
Whichever path you choose, keep in mind that all this pertains to the system on which the program will be running, not only the system on which the program will be developed.

Related

Frama-C aborted Invalid user input

I am very new to Frama-c and I got an issue when I am trying to open a C source file.
The error shows as
"fatal error: event.h: No such file or directory. Compilation terminated".
[kernel] Parsing FRAMAC_SHARE/libc/__fc_builtin_for_normalization.i (no preprocessing)
[kernel] Parsing WorkSpace/bipbuffer.c (with preprocessing)
[kernel] user error: failed to run: gcc -E -C -I. -dD -D__FRAMAC__ -nostdinc -D__FC_MACHDEP_X86_32 -I/usr/share/frama-c/libc -o '/tmp/bipbuffer.ce6d077.i' '/home/xxx/WorkSpace/bipbuffer.c' you may set the CPP environment variable to select the proper preprocessor command or use the option "-cpp-command".
[kernel] user error: stopping on file "/home/xxx/WorkSpace/bipbuffer.c" that has errors. Add'-kernel-msg-key pp' for preprocessing command.
So bascially I am trying to open a C source file but it returns an error like this. I aslo tried other very simple C files like hello world and other slicing functions, it works well.
I thought it was because I didn't have the dependencies of 'event.h' but it still return these errors after I installed the libevent dependencies. I am not sure if I need to manually set some path of the dependencies for frama-c
Here is part of the C file (Source link: https://memcached.org/) that I would like to open:
#include "stdio.h"
#include <stdlib.h>
/* for memcpy */
#include <string.h>
#include "bipbuffer.h"
static size_t bipbuf_sizeof(const unsigned int size)
{
return sizeof(bipbuf_t) + size;
}
int bipbuf_unused(const bipbuf_t* me)
{
if (1 == me->b_inuse)
/* distance between region B and region A */
return me->a_start - me->b_end;
else
return me->size - me->a_end;
}
......
Thanks,
Compilers and other tools working with C source code need to know where to find header files. There are some standard places where they look automatically, but Frama-C has fewer of those than (and different ones from) a normal compiler.
You need to find out where event.h is installed, then pass something like -cpp-extra-args "-I /path/to/directory/" to Frama-C. Pass the directory name only, not including the name event.h itself.
In addition to Isabelle Newbie's answer, I'd like to point out that the Chlorine version of Frama-C, whose beta has been recently announced, features a new option -json-compilation-database that attempts to read the arguments to be passed to the pre-processor from a compilation database.
Such database can be generated directly by cmake, but there are solutions for make-based project such as the one you refer to, in particular bear, which intercepts the commands launched by make to build the database.
Here's a detailed summary of how you could proceed, using the new -json-compilation-database option from Frama-C 17 Chlorine, plus an extra script list_files.py (which is not in the beta, but will be available in the final 17 release, and can be downloaded here):
Get the source files you want to analyze with Frama-C, run ./configure, and if possible try to disable optional dependencies from external libraries; for instance, some code bases include optional dependencies based on availability of libraries/system features, but have fallback options (resorting to standard C library or POSIX functions). The more you give Frama-C, the better the chances of analyzing it well, so if such external libraries are not essential, excluding them might help get a more "POSIXy" code, which should help. This is typically visible in config.h files, in macros commonly named HAVE_*.
Compile and install Build EAR or some equivalent tool to obtain a compile_commands.json file.
Run bear make (or cmake with flag CMAKE_EXPORT_COMPILE_COMMANDS) to get the compile_commands.json file.
Run the aforementioned list_files.py in the directory containing compile_commands.json to obtain the list of C sources used during compilation.
Run Frama-C (17 Chlorine or newer), giving it the list of sources found in the previous step, plus option -json-compilation-database . to parse the compile_commands.json and, hopefully, get the appropriate preprocessing flags.
Ideally, this should suffice, but in practice, this is rarely enough. In particular due to the presence of external libraries and non-C99, non-POSIX functions, the following steps are always needed.
6. Inclusion of external libraries
At this step, Frama-C will complain about the lack of event.h. You'll have to include the headers of this library yourself. Note: copying headers directly from your /usr/include is not likely to work, due to several architecture-specific definitions, especially files such as bits/*.h..
Instead, consider downloading the external libraries and preparing them (e.g. running ./configure at least). Then manually add the extra include directory via -cpp-extra-args="-I <path/to/your/sources/for/libevent.h>/include".
7. Inclusion of missing non-POSIX headers
Some other headers may be missing, in particular GNU- or BSD-specific sources (e.g. sysexits.h). Get these headers and add them when necessary. The error message in this case comes from the preprocessor (gcc) and is similar to this:
memcached.c:51:10: fatal error: sysexits.h: No such file or directory
#include <sysexits.h>
^~~~~~~~~~~~
compilation terminated.
8. Definition of missing non-POSIX types and constants
At this point, all necessary headers should be available, but parsing with Frama-C may still fail. This is due to usage of non-POSIX type definitions (e.g. caddr_t, struct ling), non-POSIX constants (e.g. MAXPATHLEN, SOCK_NONBLOCK, NI_MAXSERV). Error messages typically resemble the following:
[kernel] memcached.c:3261: Failure: Cannot resolve variable MAXPATHLEN
Constants are often easy to provide manually, by grepping what's available in your /usr/include.
Type definitions, on the other hand, may require some copy-pasting at the right places, especially if they depend on other types which are also missing. This step is hardly automatizable, but relatively straightforward once you get used to some specific error messages.
For instance, the following error message is related to a missing type definition (caddr_t):
[kernel] Parsing memcached.c (with preprocessing)
[kernel] memcached.c:1074:
syntax error:
Location: line 1074, between columns 38 and 47, before or at token: c
1072 *hdr++ = 0;
1073 *hdr++ = 0;
1074 assert((void *) hdr == (caddr_t)c->msglist[i].msg_iov[0].iov_base + UDP_HEADER_SIZE);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1075 }
1076
Note that the token just before c is (caddr_t), which has never been defined (it is often defined as either void * or char *).
The following error message is related to an incomplete type, i.e., a struct used somewhere but never defined:
[kernel] memcached.c:5811: User Error:
variable `ling' has initializer but incomplete type
It means that variable ling's type, which is struct linger (non-POSIX), has never been defined. In this case, we can copy it from our /usr/include/bits/socket.h:
struct linger
{
int l_onoff; /* Nonzero to linger on close. */
int l_linger; /* Time to linger. */
};
Note: if there are POSIX constants/definitions missing from Frama-C's libc, consider notifying its developers, or proposing pull requests in Frama-C's Github.
9. Fixing incompatible and missing function prototypes
Parsing is likely to succeed after the previous step, but it may still fail due to incompatible function prototypes. For instance, you may get:
[kernel] User Error: Incompatible declaration for usleep:
different integer types int and unsigned int
First declaration was at assoc.c:238
Current declaration is at items.c:1573
This is the consequence of a warning emitted earlier:
[kernel:typing:implicit-function-declaration] slabs.c:1150: Warning:
Calling undeclared function usleep. Old style K&R code?
It means that function usleep is called, but it does not have a prototype, therefore Frama-C uses the pre-C99 convention of "implicit int": it generates such a prototype, but later in the code, an actual declaration of usleep is found, and its type is not int. Hence the error.
To prevent this, you need to ensure usleep's prototype is properly included. Since it is not POSIX.1-2008, you need to either define/undefine the appropriate macros (see unistd.h), or add your own prototype.
At the end, this should allow Frama-C to parse the files and build an AST.
However, there are several missing prototypes yet; we were just lucky that none conflicted with actual declarations. Ideally, you'll consider the parsing stage done when there are no more messages such as implicit-function-declaration and similar warnings.
Some of the missing prototypes in memcached, such as getsubopt, are POSIX and should be integrated into Frama-C's standard library. Others might make part of a small library of non-standard stubs, to be reused for other software.
Contributing with results for future reuse
Successful conclusion of the parsing stage for such open source libraries is enough to consider them for integration into this repository of open source case studies, so that future users can start their analyses without having to redo all of these steps. (The repository is oriented towards Eva, but not exclusively: parsing is useful for all of Frama-C plug-ins.)

How do I determine whether a julia script is included as module or run as script?

I would like to know how in the Julia language, I can determine if a file.jl is run as script, such as in the call:
bash$ julia file.jl
It must only in this case start a function main, for example. Thus I could use include('file.jl'), without actually executing the function.
To be specific, I am looking for something similar answered already in a python question:
def main():
# does something
if __name__ == '__main__':
main()
Edit:
To be more specific, the method Base.isinteractive (see here) is not solving the problem, when using include('file.jl') from within a non-interactive (e.g. script) environment.
The global constant PROGRAM_FILE contains the script name passed to Julia from the command line (it does not change when include is called).
On the other hand #__FILE__ macro gives you a name of the file where it is present.
For instance if you have a files:
a.jl
println(PROGRAM_FILE)
println(#__FILE__)
include("b.jl")
b.jl
println(PROGRAM_FILE)
println(#__FILE__)
You have the following behavior:
$ julia a.jl
a.jl
D:\a.jl
a.jl
D:\b.jl
$ julia b.jl
b.jl
D:\b.jl
In summary:
PROGRAM_FILE tells you what is the file name that Julia was started with;
#__FILE__ tells you in what file actually the macro was called.
tl;dr version:
if !isdefined(:__init__) || Base.function_module(__init__) != MyModule
main()
end
Explanation:
There seems to be some confusion. Python and Julia work very differently in terms of their "modules" (even though the two use the same term, in principle they are different).
In python, a source file is either a module or a script, depending on how you chose to "load" / "run" it: the boilerplate exists to detect the environment in which the source code was run, by querying the __name__ of the embedding module at the time of execution. E.g. if you have a file called mymodule.py, it you import it normally, then within the module definition the variable __name__ automatically gets set to the value mymodule; but if you ran it as a standalone script (effectively "dumping" the code into the "main" module), the __name__ variable is that of the global scope, namely __main__. This difference gives you the ability to detect how a python file was ran, so you could act slightly differently in each case, and this is exactly what the boilerplate does.
In julia, however, a module is defined explicitly as code. Running a file that contains a module declaration will load that module regardless of whether you did using or include; however in the former case, the module will not be reloaded if it's already on the workspace, whereas in the latter case it's as if you "redefined" it.
Modules can have initialisation code via the special __init__() function, whose job is to only run the first time a module is loaded (e.g. when imported via a using statement). So one thing you could do is have a standalone script, which you could either include directly to run as a standalone script, or include it within the scope of a module definition, and have it detect the presence of module-specific variables such that it behaves differently in each case. But it would still have to be a standalone file, separate from the main module definition.
If you want the module to do stuff, that the standalone script shouldn't, this is easy: you just have something like this:
module MyModule
__init__() = # do module specific initialisation stuff here
include("MyModule_Implementation.jl")
end
If you want the reverse situation, you need a way to detect whether you're running inside the module or not. You could do this, e.g. by detecting the presence of a suitable __init__() function, belonging to that particular module. For example:
### in file "MyModule.jl"
module MyModule
export fun1, fun2;
__init__() = print("Initialising module ...");
include("MyModuleImplementation.jl");
end
### in file "MyModuleImplementation.jl"
fun1(a,b) = a + b;
fun2(a,b) = a * b;
main() = print("Demo of fun1 and fun2. \n" *
" fun1(1,2) = $(fun1(1,2)) \n" *
" fun2(1,2) = $(fun2(1,2)) \n");
if !isdefined(:__init__) || Base.function_module(__init__) != MyModule
main()
end
If MyModule is loaded as a module, the main function in MyModuleImplementation.jl will not run.
If you run MyModuleImplementation.jl as a standalone script, the main function will run.
So this is a way to achieve something close to the effect you want; but it's very different to saying running a module-defining file as either a module or a standalone script; I don't think you can simply "strip" the module instruction from the code and run the module's "contents" in such a manner in julia.
The answer is available at the official Julia docs FAQ. I am copy/pasting it here because this question comes up as the first hit on some search engines. It would be nice if people found the answer on the first-hit site.
How do I check if the current file is being run as the main script?
When a file is run as the main script using julia file.jl one might want to activate extra functionality like command line argument handling. A way to determine that a file is run in this fashion is to check if abspath(PROGRAM_FILE) == #__FILE__ is true.

How to change header include guards in Rcpp interfaces?

I am lately trying to learn the (brilliant) Rcpp library. When I want to export some of my C++ code, afaik it is suggested to use sth like:
// [[Rcpp::interfaces(r, cpp)]]
// [[Rcpp::export(name=".mrwr_cpp")]]
Eigen::VectorXd mrwr_(const Eigen::VectorXd& p0,
const Eigen::MatrixXd& W,
const double r)
{
// impl
}
In this example // [[Rcpp::interfaces(r, cpp)]] would create a header file with the name of my R package (lets say the package is called diffusr). The content of the exported header (diffusr.h) would look like this:
// This file was generated by Rcpp::compileAttributes
// Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393
#ifndef __diffusr_h__
#define __diffusr_h__
#include "diffusr_RcppExports.h"
#endif // __diffusr_h__
Is there a way to change the header include guard autamatically? Two leading "_" might lead to undefined behaviour, if I am correct, and is reserved for the standard library (What are the rules about using an underscore in a C++ identifier?)
Best,
Simon
Briefly:
"You don't", as that is done in the code generators within Rcpp, so you would have to change Rcpp
Check the master branch on GitHub corresponding to the next release (in a week or two) as this was recently changed

Call Rmath via Ctypes from Ocaml on OS X

I want to use R's mathematical functions as provided in libRmath from Ocaml. I successfully installed the library via brew tap homebrew science && brew install --with-librmath-only r. I end up with a .dylib in /usr/local/lib and a .h in /usr/local/include. Following the Ocaml ctypes tutorial, i do this in utop
#require "ctypes.foreign";;
open Ctypes;;
open Foreign;;
let test_pow = foreign "pow_di" (float #-> int #-> returning float);;
this complains that it can't find the symbol. What am I doing wrong? Do I need to open the dynamic library first? Set some environment variables? After googling, I also did this:
nm -gU /usr/local/lib/libRmath.dylib
which gives a bunch of symbols all with a leading underscore including 00000000000013ff T _R_pow_di. In the header file, pow_di is defined via some #define directive from _R_pow_di. I did try variations of the name like "R_pow_di" etc.
Edit: I tried compiling a simple C program using Rmath using Xcode. After setting the include path manually to include /usr/local/include, Xcode can find the header file Rmath.h. However, inside the header file, there is an include of R_ext/Boolean.h which does not seem to exist. This error is flagged by Xcode and compilation stops.
Noob alert: this may be totally obvious to a C programmer...
In order to use external library you still need to link. There're at least two different ways, either link using compiler, or link even more dynamically using dlopen.
For the first method use the following command (as an initial approximation):
ocamlbuild -pkg ctypes.foreign -lflags -cclib,-lRmath yourapp.native
under premise that your code is put into yourapp.ml file.
The second method is to use ctypes interface to dlopen to open the library. Using the correct types and name for the C function call, this goes like this:
let library = Dl.dlopen ~filename:"libRmath.dylib" ~flags:[]
let test_pow = foreign ~from:library "R_pow_di" (double #-> int #-> returning double)

Using sqlite from vala without dependence on glib

I need to use the Sqlite vapi without any depedence on GLib. SQlite is non-gobject library, so it should be possible to do that.
However, when I try to compile the following file with the --profile posix
option,
using Sqlite;
void main() {
stdout.printf("Hello, World!");
}
I get am error messages:
sqlite3.vapi:357.56-357.59: error: The symbol `GLib' could not be found
public int bind_blob (int index, void* value, int n,
GLib.DestroyNotify destroy_notify);
^^^^
sqlite3.vapi:362.68-362.71: error: The symbol `GLib' could not be found
public int bind_text (int index, owned string value, int n = -1,
GLib.DestroyNotify destroy_notify = GLib.g_free);
^^^^
sqlite3.vapi:411.42-411.45: error: The symbol `GLib' could not be found
public void result_blob (uint8[] data, GLib.DestroyNotify?
destroy_notify = GLib.g_free);
^^^^
sqlite3.vapi:420.59-420.62: error: The symbol `GLib' could not be found
public void result_text (string value, int length = -1,
GLib.DestroyNotify? destroy_notify = GLib.g_free);
^^^^
Compilation failed: 4 error(s), 0 warning(s)
It seems that several of the functions defined in the sqlite vapi make references to the GLib.g_free and GLib.DestroyNotify symbols. Are there any posix alternatives to those?
That should be fairly simple to solve, and I can imagine several solutions.
It boils down to declaring a different delegate void DestroyNotify (void* data) (either in the posix.vapi or sqlite3.vapi) and bind free() in posix.vapi.
The problem is the namespace, and you might need to file a bug and discuss it with the developers. If you want to avoid this problem and are ready to go with a workaround, just create a mini glib.vapi GLib namespace, where you bind only the DestroyNotify() and g_free() (binding to libc/posix free).
I would think that sqlite3 should not use GLib, but rather libc/posix, so you should be fine by modifying only posix.vapi and sqlite3.vapi and filing a bug with your patch (awesome, a contrib!).
Note that classes are unavailable under the POSIX profile, as Vala requires a support library (i.e. GLib, Dova) to support those features. Jürg Billeter has acknowledged that support for the POSIX profile is experimental and limited:
https://bugzilla.gnome.org/show_bug.cgi?id=618348
The only way you have is re-writing the sqlite VAPI (or just the classes/methods you need) making them posix friendly (but I guess you can't use classes in that way).
if the vapi for sqlite depends on glib you could just write your own or use the sqlite c code with c and just make some extern statements for the functions you need. for example i made a tool wich mixes vala and c for linux pure c for win32 and objective c and c for mac
https://github.com/boscowitch/wadoku-notify
i just added the 2 functions i need at the beginning of my vala app like this:
extern void init_db(char * path,bool mm);
extern void lookup(char * str);
i added the whole sqlite source cause i needed to activate full text indexing and change a bit in the code and in the beginning of vala there was no sqlite vapi

Resources