Previous: Processor/task mapping functions, Up: Built-in functions [Contents][Index]
FILE_DATA
interacts with the surrounding system by
parsing a named file as a table and returning the contents of a
specified row and column.
Read the contents of file filename and parse the data read into rows and columns. Rows are separated by one or more characters appearing in the string row-seps (default: ‘\n’, i.e., a newline character). Columns are separated by one or more characters appearing in the string col-seps (default: ‘ \t’, i.e., a space and a tab). Once the data are parsed in this manner, the cell at column column (default: ‘1’) and row row (default: ‘1’) is converted to a number and returned.
Columns and rows are each numbered starting from 1. Negative numbers represent offsets from the last column or row. Zero values cause the program to abort with an error message.
Consider a data file, example.dat, with the following contents:
Eir 231 58 490 703 19 644 967 Gunnr 901 875 141 372 374 618 77 Herja 17 979 363 930 977 Hrist 100 132 981 246 93 614 Svipul 688 536 965 746 209 |
Then, the following uses of FILE_DATA
return the
results shown:
The use of FILE_DATA
is discouraged
in coNCePTuaL programs because of its reliance on external files,
whose contents are not automatically preserved in any coNCePTuaL
log files (see
Interpreting coNCePTuaL log files) and which may exhibit
system-specific behavior (e.g., if the file is in fact a named pipe
or a file-like interface to a kernel data structure). However,
FILE_DATA
can be useful in certain circumstances for
logging changes in system state of which coNCePTuaL would otherwise
be unaware. For example, one might log values from various
pseudo-files appearing in Linux’s /proc filesystem or
from system log files (e.g., those within Linux’s /var/log
directory).
Because coNCePTuaL cannot determine a priori if
multiple reads of the same row and column from the same file will
produce the same value it pessimistically assumes that each read
produces a different value. (Consider even the simple case of
FILE_DATA
reading the last row of a system log file to
which another process is asynchronously appending.) Consequently,
FILE_DATA
cannot be used in any context that requires
multiple tasks to agree on a value, such as within message
specifications (see Message
specifications) or let bindings (see Binding variables).
For cases where the programmer can assert that reads from a
particular row and column will always return the same value (on
penalty of undefined behavior, including hangs and crashes),
coNCePTuaL provides the following function:
Perform exactly the same operation as
FILE_DATA
but with the programmer’s guarantee that the
file contents will not change from invocation to invocation.
STATIC_FILE_DATA
can therefore be used in places where
FILE_DATA
is disallowed.
Given the example.dat file shown previously, the following let binding is legitimate:
LET msg_size BE STATIC_FILE_DATA("example.dat", 2, iter) AND rank_ofs BE STATIC_FILE_DATA("example.dat", 3, iter) MOD num_tasks WHILE …
However, the following, which uses
FILE_DATA
instead of
STATIC_FILE_DATA
, is not:
LET msg_size BE FILE_DATA("example.dat", 2, iter) AND rank_ofs BE FILE_DATA("example.dat", 3, iter) MOD num_tasks WHILE …
STATIC_FILE_DATA
can be used as above to implement
complex, irregular communication patterns that vary across runs of
the program. That is, each iteration, a different value read from
the file can be used to specify the message size and the distance
between senders and receivers.
The use of
STATIC_FILE_DATA
is even more discouraged than the use
of FILE_DATA
because an
incorrect claim that a file’s contents are unvarying could lead to
abnormal program behavior—and not necessarily easily detectable. It
is best to avoid both FILE_DATA
and
STATIC_FILE_DATA
if possible. If not, use
FILE_DATA
unless (a) the compiler
rejects the program on the grounds that
FILE_DATA
is being used in an invalid location and
(b) the data being read is known to be invariant
throughout the lifetime of the program.
Previous: Processor/task mapping functions, Up: Built-in functions [Contents][Index]