SDDS ToolKit Programs and Libraries for C and Python
Loading...
Searching...
No Matches
SDDS_MPI_binary.c File Reference

Detailed Description

Implementation of SDDS MPI Functions.

This source file contains the implementation of functions responsible for reading SDDS (Self Describing Data Set) datasets in binary format using MPI (Message Passing Interface). It handles both native and non-native byte orders, ensuring compatibility across different machine architectures. The functions manage buffer operations, memory allocation, and MPI communication to facilitate efficient and accurate data retrieval in parallel processing environments.

License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Authors
H. Shang M. Borland R. Soliday

Definition in file SDDS_MPI_binary.c.

#include "mdb.h"
#include "mdb_thread.h"
#include "SDDS.h"

Go to the source code of this file.

Functions

static int32_t SDDS_GetLockedDefaultStringLength (void)
 
static int32_t SDDS_GetLockedDefaultTitleBufferSize (void)
 
static int32_t SDDS_GetLockedDefaultReadBufferSize (void)
 
static int32_t SDDS_GetLockedDefaultWriteBufferSize (void)
 
static long SDDS_MPI_GetLockedWriteKludgeUsleep (void)
 
static short SDDS_MPI_GetLockedForceFileSync (void)
 
int32_t SDDS_SetDefaultReadBufferSize (int32_t newSize)
 Set the default read buffer size for SDDS.
 
int32_t SDDS_SetDefaultWriteBufferSize (int32_t newSize)
 Set the default write buffer size for SDDS.
 
int32_t SDDS_SetDefaultTitleBufferSize (int32_t newSize)
 Set the default title buffer size for SDDS.
 
int32_t SDDS_CheckStringTruncated (void)
 Check the number of truncated strings.
 
void SDDS_StringTuncated (void)
 Increment the truncated strings counter.
 
int32_t SDDS_SetDefaultStringLength (int32_t newValue)
 Set the default string length for SDDS.
 
int32_t SDDS_MPI_WriteBinaryPage (SDDS_DATASET *SDDS_dataset)
 Write an SDDS binary page using MPI.
 
int32_t SDDS_MPI_WriteBinaryString (SDDS_DATASET *SDDS_dataset, char *string)
 Write a binary string to an SDDS dataset using MPI.
 
int32_t SDDS_MPI_WriteNonNativeBinaryString (SDDS_DATASET *SDDS_dataset, char *string)
 Write a non-native binary string to an SDDS dataset using MPI.
 
int32_t SDDS_MPI_WriteBinaryParameters (SDDS_DATASET *SDDS_dataset)
 Write binary parameters of an SDDS dataset using MPI.
 
int32_t SDDS_MPI_WriteNonNativeBinaryParameters (SDDS_DATASET *SDDS_dataset)
 Write non-native binary parameters of an SDDS dataset using MPI.
 
int32_t SDDS_MPI_WriteBinaryArrays (SDDS_DATASET *SDDS_dataset)
 Write binary arrays of an SDDS dataset using MPI.
 
int32_t SDDS_MPI_WriteNonNativeBinaryArrays (SDDS_DATASET *SDDS_dataset)
 Write non-native binary arrays of an SDDS dataset using MPI.
 
void SDDS_MPI_SetWriteKludgeUsleep (long value)
 Set the write kludge usleep duration.
 
void SDDS_MPI_SetFileSync (short value)
 Set the file synchronization flag.
 
int32_t SDDS_MPI_WriteBinaryRow (SDDS_DATASET *SDDS_dataset, int64_t row)
 Write a binary row to an SDDS dataset using MPI.
 
int32_t SDDS_MPI_WriteNonNativeBinaryRow (SDDS_DATASET *SDDS_dataset, int64_t row)
 Write a non-native binary row to an SDDS dataset using MPI.
 
MPI_Offset SDDS_MPI_Get_Column_Size (SDDS_DATASET *SDDS_dataset)
 Get the total size of all columns in an SDDS dataset.
 
int32_t SDDS_MPI_BufferedWrite (void *target, int64_t targetSize, SDDS_DATASET *SDDS_dataset)
 Buffered write to an SDDS dataset using MPI.
 
int32_t SDDS_MPI_BufferedWriteAll (void *target, int64_t targetSize, SDDS_DATASET *SDDS_dataset)
 Buffered write all to an SDDS dataset using MPI.
 
int32_t SDDS_MPI_FlushBuffer (SDDS_DATASET *SDDS_dataset)
 Flush the buffer by writing any remaining data to the MPI file.
 
int64_t SDDS_MPI_CountRowsOfInterest (SDDS_DATASET *SDDS_dataset, int64_t start_row, int64_t end_row)
 Count the number of rows marked as "of interest" within a specified range.
 
int64_t SDDS_MPI_GetTotalRows (SDDS_DATASET *SDDS_dataset)
 Get the total number of rows across all MPI processes.
 
int32_t SDDS_MPI_WriteNonNativeBinaryPage (SDDS_DATASET *SDDS_dataset)
 Write a non-native binary page of the SDDS dataset using MPI.
 
int32_t SDDS_MPI_WriteContinuousBinaryPage (SDDS_DATASET *SDDS_dataset)
 Write a continuous binary page of the SDDS dataset using MPI.
 
int32_t SDDS_MPI_BufferedRead (void *target, int64_t targetSize, SDDS_DATASET *SDDS_dataset, SDDS_FILEBUFFER *fBuffer)
 Buffered read from an SDDS dataset using MPI.
 
int32_t SDDS_MPI_BufferedReadAll (void *target, int64_t targetSize, SDDS_DATASET *SDDS_dataset, SDDS_FILEBUFFER *fBuffer)
 Buffered read all from an SDDS dataset using MPI.
 
char * SDDS_MPI_ReadBinaryString (SDDS_DATASET *SDDS_dataset, SDDS_FILEBUFFER *fBuffer, int32_t skip)
 Read a binary string from the SDDS dataset using MPI.
 
char * SDDS_MPI_ReadNonNativeBinaryString (SDDS_DATASET *SDDS_dataset, SDDS_FILEBUFFER *fBuffer, int32_t skip)
 Read a non-native binary string from the SDDS dataset using MPI.
 
int32_t SDDS_MPI_ReadBinaryParameters (SDDS_DATASET *SDDS_dataset, SDDS_FILEBUFFER *fBuffer)
 Read binary parameters from the SDDS dataset using MPI.
 
int32_t SDDS_MPI_ReadBinaryRow (SDDS_DATASET *SDDS_dataset, int64_t row, int32_t skip)
 Read a binary row from the SDDS dataset using MPI.
 
int32_t SDDS_MPI_ReadBinaryArrays (SDDS_DATASET *SDDS_dataset, SDDS_FILEBUFFER *fBuffer)
 Read binary arrays from the SDDS dataset using MPI.
 
int32_t SDDS_MPI_ReadNonNativeBinaryParameters (SDDS_DATASET *SDDS_dataset, SDDS_FILEBUFFER *fBuffer)
 Read non-native binary parameters from the SDDS dataset using MPI.
 
int32_t SDDS_MPI_ReadNonNativeBinaryArrays (SDDS_DATASET *SDDS_dataset, SDDS_FILEBUFFER *fBuffer)
 Reads non-native binary arrays from a binary file buffer into the SDDS dataset using MPI.
 
int32_t SDDS_MPI_ReadNonNativeBinaryRow (SDDS_DATASET *SDDS_dataset, int64_t row, int32_t skip)
 Reads a single non-native binary row from a binary file buffer into the SDDS dataset using MPI.
 
int32_t SDDS_MPI_BroadcastTitleData (SDDS_DATASET *SDDS_dataset)
 Broadcasts the title data (parameters and arrays) of the SDDS dataset to all MPI processes.
 
int32_t SDDS_MPI_ReadBinaryPage (SDDS_DATASET *SDDS_dataset)
 Reads a binary page from an SDDS dataset using MPI parallel I/O.
 
int32_t SDDS_MPI_ReadNonNativePage (SDDS_DATASET *SDDS_dataset)
 Reads a non-native binary page from an SDDS dataset using MPI parallel I/O.
 
int32_t SDDS_MPI_ReadNonNativePageSparse (SDDS_DATASET *SDDS_dataset, uint32_t mode)
 Reads a sparse non-native binary page from an SDDS dataset using MPI parallel I/O.
 
int32_t SDDS_MPI_ReadNonNativeBinaryPage (SDDS_DATASET *SDDS_dataset)
 Reads a non-native binary page from an SDDS dataset using MPI parallel I/O.
 
int32_t SDDS_MPI_BufferedReadNonNativeBinaryTitle (SDDS_DATASET *SDDS_dataset)
 Buffers and reads the non-native binary title data from an SDDS dataset using MPI.
 
MPI_Offset SDDS_MPI_GetTitleOffset (SDDS_DATASET *SDDS_dataset)
 Calculates the byte offset for the title section in a non-native binary SDDS dataset.
 
int32_t SDDS_MPI_BufferedReadBinaryTitle (SDDS_DATASET *SDDS_dataset)
 Buffers and reads the binary title data from an SDDS dataset using MPI.
 
int32_t SDDS_MPI_CollectiveWriteByRow (SDDS_DATASET *SDDS_dataset)
 Writes SDDS dataset rows collectively by row using MPI parallel I/O.
 
int32_t SDDS_MPI_CollectiveWriteNonNativeByRow (SDDS_DATASET *SDDS_dataset)
 Writes non-native binary SDDS dataset rows collectively by row using MPI parallel I/O.
 
int32_t SDDS_MPI_CollectiveReadByRow (SDDS_DATASET *SDDS_dataset)
 Reads SDDS dataset rows collectively by row using MPI parallel I/O.
 

Function Documentation

◆ SDDS_CheckStringTruncated()

int32_t SDDS_CheckStringTruncated ( void )

Check the number of truncated strings.

This function returns the number of strings that have been truncated due to exceeding the default string length.

Returns
The number of truncated strings.

Definition at line 173 of file SDDS_MPI_binary.c.

173 {
174 int32_t count;
175
176 mdb_thread_lock(&number_of_string_truncated_lock);
177 count = number_of_string_truncated;
178 mdb_thread_unlock(&number_of_string_truncated_lock);
179 return count;
180}

◆ SDDS_GetLockedDefaultReadBufferSize()

static int32_t SDDS_GetLockedDefaultReadBufferSize ( void )
static

Definition at line 66 of file SDDS_MPI_binary.c.

66 {
67 int32_t size;
68 mdb_thread_lock(&defaultReadBufferSizeLock);
69 size = defaultReadBufferSize;
70 mdb_thread_unlock(&defaultReadBufferSizeLock);
71 return size;
72}

◆ SDDS_GetLockedDefaultStringLength()

static int32_t SDDS_GetLockedDefaultStringLength ( void )
static

Definition at line 50 of file SDDS_MPI_binary.c.

50 {
51 int32_t length;
52 mdb_thread_lock(&defaultStringLengthLock);
53 length = defaultStringLength;
54 mdb_thread_unlock(&defaultStringLengthLock);
55 return length;
56}

◆ SDDS_GetLockedDefaultTitleBufferSize()

static int32_t SDDS_GetLockedDefaultTitleBufferSize ( void )
static

Definition at line 58 of file SDDS_MPI_binary.c.

58 {
59 int32_t size;
60 mdb_thread_lock(&defaultTitleBufferSizeLock);
61 size = defaultTitleBufferSize;
62 mdb_thread_unlock(&defaultTitleBufferSizeLock);
63 return size;
64}

◆ SDDS_GetLockedDefaultWriteBufferSize()

static int32_t SDDS_GetLockedDefaultWriteBufferSize ( void )
static

Definition at line 74 of file SDDS_MPI_binary.c.

74 {
75 int32_t size;
76 mdb_thread_lock(&defaultWriteBufferSizeLock);
77 size = defaultWriteBufferSize;
78 mdb_thread_unlock(&defaultWriteBufferSizeLock);
79 return size;
80}

◆ SDDS_MPI_BroadcastTitleData()

int32_t SDDS_MPI_BroadcastTitleData ( SDDS_DATASET * SDDS_dataset)

Broadcasts the title data (parameters and arrays) of the SDDS dataset to all MPI processes.

This function gathers the title data from the master process and broadcasts it to all other MPI processes. It handles the total number of rows, parameters, and array definitions, ensuring that each process has consistent dataset metadata.

Parameters
[in,out]SDDS_datasetPointer to the SDDS_DATASET structure containing the title data to broadcast.
Returns
int32_t Returns 1 on successful broadcast, 0 on failure.

Definition at line 1887 of file SDDS_MPI_binary.c.

1887 {
1888 char *par_data = NULL;
1889 int32_t type, size;
1890 int64_t i, count = 0, *data_len = NULL;
1891 MPI_DATASET *MPI_dataset;
1892 SDDS_LAYOUT *layout;
1893 char *string = NULL;
1894
1895 MPI_dataset = SDDS_dataset->MPI_dataset;
1896 layout = &(SDDS_dataset->layout);
1897 if (!layout->n_parameters && !layout->n_arrays) {
1898 /* no parameters and arrays, only broadcast total_rows */
1899 MPI_Bcast(&(MPI_dataset->total_rows), 1, MPI_INT64_T, 0, MPI_dataset->comm);
1900 } else {
1901 /* broadcast the total_rows and parameter data */
1902 data_len = calloc(sizeof(*data_len), 1 + layout->n_parameters);
1903 if (MPI_dataset->myid == 0) {
1904 data_len[0] = sizeof(int64_t);
1905 count = data_len[0];
1906 for (i = 0; i < layout->n_parameters; i++) {
1907 type = layout->parameter_definition[i].type;
1908 if (type == SDDS_STRING)
1909 data_len[i + 1] = strlen(*((char **)SDDS_dataset->parameter[i])) * sizeof(char);
1910 else
1911 data_len[i + 1] = SDDS_type_size[type - 1];
1912 ;
1913 count += data_len[i + 1];
1914 }
1915 par_data = (char *)malloc(sizeof(char) * count);
1916 memcpy((char *)par_data, &(MPI_dataset->total_rows), data_len[0]);
1917 count = data_len[0];
1918 for (i = 0; i < layout->n_parameters; i++) {
1919 if (layout->parameter_definition[i].type == SDDS_STRING)
1920 memcpy((char *)par_data + count, *(char **)SDDS_dataset->parameter[i], data_len[i + 1]);
1921 else
1922 memcpy((char *)par_data + count, (char *)SDDS_dataset->parameter[i], data_len[i + 1]);
1923 count += data_len[i + 1];
1924 }
1925 }
1926 MPI_Bcast(data_len, 1 + layout->n_parameters, MPI_INT64_T, 0, MPI_dataset->comm);
1927 if (MPI_dataset->myid) {
1928 count = data_len[0];
1929 for (i = 0; i < layout->n_parameters; i++)
1930 count += data_len[i + 1];
1931 par_data = (char *)malloc(sizeof(char) * count);
1932 }
1933
1934 MPI_Bcast(par_data, count, MPI_BYTE, 0, MPI_dataset->comm);
1935 if (!SDDS_StartPage(SDDS_dataset, 0)) {
1936 SDDS_SetError("Unable to read page--couldn't start page (SDDS_MPI_BroadcastTitleData)");
1937 return (0);
1938 }
1939 if (MPI_dataset->myid) {
1940 memcpy(&(MPI_dataset->total_rows), (char *)par_data, data_len[0]);
1941 count = data_len[0];
1942 for (i = 0; i < layout->n_parameters; i++) {
1943 if (layout->parameter_definition[i].type == SDDS_STRING) {
1944 string = malloc(sizeof(char) * (data_len[i + 1] + 1));
1945 memcpy((char *)string, (char *)par_data + count, data_len[i + 1]);
1946 string[data_len[i + 1]] = '\0';
1947 *(char **)SDDS_dataset->parameter[i] = string;
1948 } else
1949 memcpy((char *)(SDDS_dataset->parameter[i]), (char *)par_data + count, data_len[i + 1]);
1950 count += data_len[i + 1];
1951 }
1952 }
1953 }
1954 free(data_len);
1955 free(par_data);
1956 data_len = NULL;
1957 par_data = NULL;
1958 if (layout->n_arrays) {
1959 data_len = malloc(sizeof(*data_len) * layout->n_arrays);
1960 if (MPI_dataset->myid == 0) {
1961 for (i = 0; i < layout->n_arrays; i++)
1962 data_len[i] = layout->array_definition[i].dimensions;
1963 }
1964 MPI_Bcast(data_len, layout->n_arrays, MPI_INT64_T, 0, MPI_dataset->comm);
1965 for (i = 0; i < layout->n_arrays; i++) {
1966 type = layout->array_definition[i].type;
1967 size = SDDS_type_size[type - 1];
1968 if (data_len[i]) {
1969 if (type == SDDS_STRING) {
1970 if (MPI_dataset->myid == 0) {
1971 /* it is not easy to broad cast string array, will implement it in the future */
1972 }
1973 } else
1974 MPI_Bcast((char *)SDDS_dataset->array[i].data, data_len[i] * size, MPI_BYTE, 0, MPI_dataset->comm);
1975 }
1976 }
1977 }
1978 /*MPI_dataset->file_offset += SDDS_MPI_GetTitleOffset(MPI_dataset); */
1979 return 1;
1980}
int32_t SDDS_type_size[SDDS_NUM_TYPES]
Array of sizes for each supported data type.
Definition SDDS_data.c:62
int32_t SDDS_StartPage(SDDS_DATASET *SDDS_dataset, int64_t expected_n_rows)
void SDDS_SetError(char *error_text)
Records an error message in the SDDS error stack.
Definition SDDS_utils.c:421
#define SDDS_STRING
Identifier for the string data type.
Definition SDDStypes.h:85

◆ SDDS_MPI_BufferedRead()

int32_t SDDS_MPI_BufferedRead ( void * target,
int64_t targetSize,
SDDS_DATASET * SDDS_dataset,
SDDS_FILEBUFFER * fBuffer )

Buffered read from an SDDS dataset using MPI.

This function reads data from the SDDS dataset using a buffer. It handles cases where sufficient data is already in the buffer and cases where additional data needs to be read from the MPI file. It also manages end-of-file conditions.

Parameters
targetPointer to the buffer where the read data will be stored.
targetSizeThe size of the data to read, in bytes.
SDDS_datasetPointer to the SDDS_DATASET structure.
fBufferPointer to the SDDS_FILEBUFFER structure managing the buffer.
Returns
  • 1 on successful read.
  • 0 on partial read or failure.
  • -1 if end-of-file is reached.

Definition at line 1263 of file SDDS_MPI_binary.c.

1263 {
1264 int32_t mpi_code;
1265 int32_t bytesRead, count;
1266 MPI_Status status;
1267 MPI_DATASET *MPI_dataset = SDDS_dataset->MPI_dataset;
1268
1269 if (!fBuffer || !fBuffer->bufferSize) {
1270 /* just read into users buffer or seek if no buffer given */
1271 if (!target)
1272 mpi_code = MPI_File_seek(MPI_dataset->MPI_file, targetSize, MPI_SEEK_CUR);
1273 else {
1274 mpi_code = MPI_File_read(MPI_dataset->MPI_file, target, targetSize, MPI_BYTE, &status);
1275 MPI_Get_count(&status, MPI_BYTE, &bytesRead);
1276 if (!bytesRead) {
1277 MPI_dataset->end_of_file = 1;
1278 return -1;
1279 }
1280 if (bytesRead < targetSize)
1281 return 0;
1282 }
1283 if (mpi_code != MPI_SUCCESS) {
1284 SDDS_MPI_GOTO_ERROR(stderr, "SDDS_MPI_BufferedRead(MPI_File_read failed)", mpi_code, 0);
1285 return 0;
1286 }
1287 return 1;
1288 }
1289 if ((fBuffer->bytesLeft -= targetSize) >= 0) {
1290 /* sufficient data is already in the buffer */
1291 if (target && targetSize > 0) {
1292 memcpy((char *)target, (char *)fBuffer->data, (size_t)targetSize);
1293 }
1294 fBuffer->data += targetSize;
1295 return 1;
1296 } else {
1297 /* need to read additional data into buffer */
1298 int64_t bytesNeeded, offset;
1299 fBuffer->bytesLeft += targetSize; /* adds back amount subtracted above */
1300 /* first, use the data that is already available. this cleans out the buffer */
1301 if ((offset = fBuffer->bytesLeft)) {
1302 /* some data is available in the buffer */
1303 if (target && offset > 0) {
1304 memcpy((char *)target, (char *)fBuffer->data, (size_t)offset);
1305 }
1306 bytesNeeded = targetSize - offset;
1307 fBuffer->bytesLeft = 0;
1308 } else {
1309 bytesNeeded = targetSize;
1310 }
1311 fBuffer->data = fBuffer->buffer;
1312 if (fBuffer->bufferSize < bytesNeeded) {
1313 /* just read what is needed directly into user's memory or seek */
1314 if (!target)
1315 mpi_code = MPI_File_seek(MPI_dataset->MPI_file, targetSize, MPI_SEEK_CUR);
1316 else {
1317 mpi_code = MPI_File_read(MPI_dataset->MPI_file, (char *)target + offset, bytesNeeded, MPI_BYTE, &status);
1318 MPI_Get_count(&status, MPI_BYTE, &bytesRead);
1319 if (!bytesRead) {
1320 MPI_dataset->end_of_file = 1;
1321 return -1;
1322 }
1323 if (bytesRead < bytesNeeded)
1324 return 0;
1325 }
1326 if (mpi_code != MPI_SUCCESS) {
1327 SDDS_MPI_GOTO_ERROR(stderr, "SDDS_MPI_ReadBufferedRead(MPI_File_read failed)", mpi_code, 0);
1328 return 0;
1329 }
1330 return 1;
1331 }
1332 /* fill the buffer */
1333 mpi_code = MPI_File_read(MPI_dataset->MPI_file, fBuffer->data, (int)(fBuffer->bufferSize), MPI_BYTE, &status);
1334 MPI_Get_count(&status, MPI_BYTE, &count);
1335 fBuffer->bytesLeft = count;
1336 if (!(fBuffer->bytesLeft))
1337 MPI_dataset->end_of_file = 1;
1338 if (fBuffer->bytesLeft < bytesNeeded)
1339 return 0;
1340 if (target && bytesNeeded > 0)
1341 memcpy((char *)target + offset, (char *)fBuffer->data, (size_t)bytesNeeded);
1342 fBuffer->data += bytesNeeded;
1343 fBuffer->bytesLeft -= bytesNeeded;
1344 return 1;
1345 }
1346}
void SDDS_MPI_GOTO_ERROR(FILE *fp, char *str, int32_t mpierr, int32_t exit_code)
Handles MPI errors by printing an error message and optionally exiting.

◆ SDDS_MPI_BufferedReadAll()

int32_t SDDS_MPI_BufferedReadAll ( void * target,
int64_t targetSize,
SDDS_DATASET * SDDS_dataset,
SDDS_FILEBUFFER * fBuffer )

Buffered read all from an SDDS dataset using MPI.

This function reads all requested data from the SDDS dataset using a buffer, ensuring that the entire requested data is read unless end-of-file is reached. It handles buffer management and MPI collective I/O operations.

Parameters
targetPointer to the buffer where the read data will be stored.
targetSizeThe size of the data to read, in bytes.
SDDS_datasetPointer to the SDDS_DATASET structure.
fBufferPointer to the SDDS_FILEBUFFER structure managing the buffer.
Returns
  • 1 on successful read of all requested data.
  • 0 on partial read or failure.
  • -1 if end-of-file is reached.

Definition at line 1364 of file SDDS_MPI_binary.c.

1364 {
1365 int32_t mpi_code, bytesRead, count;
1366 MPI_Status status;
1367 MPI_DATASET *MPI_dataset = SDDS_dataset->MPI_dataset;
1368
1369 if (!fBuffer || !fBuffer->bufferSize) {
1370 /* just read into users buffer or seek if no buffer given */
1371 if (!target)
1372 mpi_code = MPI_File_seek(MPI_dataset->MPI_file, targetSize, MPI_SEEK_CUR);
1373 else {
1374 mpi_code = MPI_File_read_all(MPI_dataset->MPI_file, target, targetSize, MPI_BYTE, &status);
1375 MPI_Get_count(&status, MPI_BYTE, &bytesRead);
1376 if (!bytesRead) {
1377 MPI_dataset->end_of_file = 1;
1378 return -1;
1379 }
1380 if (bytesRead < targetSize)
1381 return 0;
1382 }
1383 if (mpi_code != MPI_SUCCESS) {
1384 SDDS_MPI_GOTO_ERROR(stderr, "SDDS_MPI_BufferedRead(MPI_File_read failed)", mpi_code, 0);
1385 return 0;
1386 }
1387 return 1;
1388 }
1389 if ((fBuffer->bytesLeft -= targetSize) >= 0) {
1390 /* sufficient data is already in the buffer */
1391 if (target && targetSize > 0) {
1392 memcpy((char *)target, (char *)fBuffer->data, (size_t)targetSize);
1393 }
1394 fBuffer->data += targetSize;
1395 return 1;
1396 } else {
1397 /* need to read additional data into buffer */
1398 int64_t bytesNeeded, offset;
1399 fBuffer->bytesLeft += targetSize; /* adds back amount subtracted above */
1400 /* first, use the data that is already available. this cleans out the buffer */
1401 if ((offset = fBuffer->bytesLeft)) {
1402 /* some data is available in the buffer */
1403 if (target && offset > 0) {
1404 memcpy((char *)target, (char *)fBuffer->data, (size_t)offset);
1405 }
1406 bytesNeeded = targetSize - offset;
1407 fBuffer->bytesLeft = 0;
1408 } else {
1409 bytesNeeded = targetSize;
1410 }
1411 fBuffer->data = fBuffer->buffer;
1412 if (fBuffer->bufferSize < bytesNeeded) {
1413 /* just read what is needed directly into user's memory or seek */
1414 if (!target)
1415 mpi_code = MPI_File_seek(MPI_dataset->MPI_file, targetSize, MPI_SEEK_CUR);
1416 else {
1417 mpi_code = MPI_File_read_all(MPI_dataset->MPI_file, (char *)target + offset, bytesNeeded, MPI_BYTE, &status);
1418 MPI_Get_count(&status, MPI_BYTE, &bytesRead);
1419 if (!bytesRead) {
1420 MPI_dataset->end_of_file = 1;
1421 return -1;
1422 }
1423 if (bytesRead < bytesNeeded)
1424 return 0;
1425 }
1426 if (mpi_code != MPI_SUCCESS) {
1427 SDDS_MPI_GOTO_ERROR(stderr, "SDDS_MPI_ReadBufferedRead(MPI_File_read failed)", mpi_code, 0);
1428 return 0;
1429 }
1430 return 1;
1431 }
1432 /* fill the buffer */
1433 mpi_code = MPI_File_read_all(MPI_dataset->MPI_file, fBuffer->data, (int)(fBuffer->bufferSize), MPI_BYTE, &status);
1434 MPI_Get_count(&status, MPI_BYTE, &count);
1435 fBuffer->bytesLeft = count;
1436 if (!(fBuffer->bytesLeft))
1437 MPI_dataset->end_of_file = 1;
1438 if (fBuffer->bytesLeft < bytesNeeded)
1439 return 0;
1440 if (target && bytesNeeded > 0)
1441 memcpy((char *)target + offset, (char *)fBuffer->data, (size_t)bytesNeeded);
1442 fBuffer->data += bytesNeeded;
1443 fBuffer->bytesLeft -= bytesNeeded;
1444 return 1;
1445 }
1446}

◆ SDDS_MPI_BufferedReadBinaryTitle()

int32_t SDDS_MPI_BufferedReadBinaryTitle ( SDDS_DATASET * SDDS_dataset)

Buffers and reads the binary title data from an SDDS dataset using MPI.

This function initializes and manages a buffered read for the title section of a native binary SDDS dataset. It reads the total number of rows, parameters, and arrays from the binary file buffer. The function handles memory allocation for the buffer and initializes the SDDS page structure.

Parameters
[in,out]SDDS_datasetPointer to the SDDS_DATASET structure where the title data will be stored.
Returns
int32_t Returns 1 on successful read, 0 on failure, and -1 if the end of the file is reached.

Definition at line 2502 of file SDDS_MPI_binary.c.

2502 {
2503 SDDS_FILEBUFFER *fBuffer = NULL;
2504 MPI_DATASET *MPI_dataset = NULL;
2505 int32_t ret_val;
2506 int32_t total_rows;
2507
2508 MPI_dataset = SDDS_dataset->MPI_dataset;
2509 fBuffer = &(SDDS_dataset->titleBuffer);
2510 if (!fBuffer->buffer) {
2511 fBuffer->bufferSize = SDDS_GetLockedDefaultTitleBufferSize();
2512 if (!(fBuffer->buffer = fBuffer->data = SDDS_Malloc(sizeof(char) * (fBuffer->bufferSize + 1)))) {
2513 SDDS_SetError("Unable to do buffered read--allocation failure(SDDS_MPI_ReadBinaryTitle)");
2514 return 0;
2515 }
2516 fBuffer->bytesLeft = 0;
2517 }
2518 if (fBuffer->bytesLeft > 0) {
2519 /* discard the extra data for reading next page */
2520 fBuffer->data[0] = 0;
2521 fBuffer->bytesLeft = 0;
2522 }
2523 if ((ret_val = SDDS_MPI_BufferedRead((void *)&(total_rows), sizeof(int32_t), SDDS_dataset, fBuffer)) < 0)
2524 return -1;
2525 if (total_rows == INT32_MIN) {
2526 if ((ret_val = SDDS_MPI_BufferedRead((void *)&(MPI_dataset->total_rows), sizeof(int64_t), SDDS_dataset, fBuffer)) < 0)
2527 return -1;
2528 } else {
2529 MPI_dataset->total_rows = total_rows;
2530 }
2531 if (!ret_val)
2532 return 0;
2533 if (!SDDS_StartPage(SDDS_dataset, 0)) {
2534 SDDS_SetError("Unable to read page--couldn't start page (SDDS_MPI_BufferedReadBinaryTitle)");
2535 return (0);
2536 }
2537 /*read parameters */
2538 if (!SDDS_MPI_ReadBinaryParameters(SDDS_dataset, fBuffer)) {
2539 SDDS_SetError("Unable to read page--parameter reading error (SDDS_MPI_BufferedReadTitle)");
2540 return (0);
2541 }
2542 /*read arrays */
2543 if (!SDDS_MPI_ReadBinaryArrays(SDDS_dataset, fBuffer)) {
2544 SDDS_SetError("Unable to read page--array reading error (SDDS_MPI_BufferedReadTitle)");
2545 return (0);
2546 }
2547
2548 return 1;
2549}
int32_t SDDS_MPI_ReadBinaryParameters(SDDS_DATASET *SDDS_dataset, SDDS_FILEBUFFER *fBuffer)
Read binary parameters from the SDDS dataset using MPI.
int32_t SDDS_MPI_BufferedRead(void *target, int64_t targetSize, SDDS_DATASET *SDDS_dataset, SDDS_FILEBUFFER *fBuffer)
Buffered read from an SDDS dataset using MPI.
int32_t SDDS_MPI_ReadBinaryArrays(SDDS_DATASET *SDDS_dataset, SDDS_FILEBUFFER *fBuffer)
Read binary arrays from the SDDS dataset using MPI.
void * SDDS_Malloc(size_t size)
Allocates memory of a specified size.
Definition SDDS_utils.c:705

◆ SDDS_MPI_BufferedReadNonNativeBinaryTitle()

int32_t SDDS_MPI_BufferedReadNonNativeBinaryTitle ( SDDS_DATASET * SDDS_dataset)

Buffers and reads the non-native binary title data from an SDDS dataset using MPI.

This function initializes and manages a buffered read for the title section of a non-native binary SDDS dataset. It reads the total number of rows, parameters, and arrays from the binary file buffer. The function handles memory allocation for the buffer, byte swapping for endianness, and initializes the SDDS page structure.

Parameters
[in,out]SDDS_datasetPointer to the SDDS_DATASET structure where the title data will be stored.
Returns
int32_t Returns 1 on successful read, 0 on failure, and -1 if the end of the file is reached.

Definition at line 2386 of file SDDS_MPI_binary.c.

2386 {
2387 SDDS_FILEBUFFER *fBuffer = NULL;
2388 MPI_DATASET *MPI_dataset = NULL;
2389 int32_t ret_val;
2390 int32_t total_rows;
2391
2392 MPI_dataset = SDDS_dataset->MPI_dataset;
2393 fBuffer = &(SDDS_dataset->titleBuffer);
2394 if (!fBuffer->buffer) {
2395 fBuffer->bufferSize = SDDS_GetLockedDefaultTitleBufferSize();
2396 if (!(fBuffer->buffer = fBuffer->data = SDDS_Malloc(sizeof(char) * (fBuffer->bufferSize + 1)))) {
2397 SDDS_SetError("Unable to do buffered read--allocation failure(SDDS_MPI_ReadNonNativeBinaryTitle)");
2398 return 0;
2399 }
2400 fBuffer->bytesLeft = 0;
2401 }
2402 if (fBuffer->bytesLeft > 0) {
2403 /* discard the extra data for reading next page */
2404 fBuffer->data[0] = 0;
2405 fBuffer->bytesLeft = 0;
2406 }
2407 if ((ret_val = SDDS_MPI_BufferedRead((void *)&(total_rows), sizeof(int32_t), SDDS_dataset, fBuffer)) < 0)
2408 return -1;
2409 SDDS_SwapLong(&(total_rows));
2410 if (total_rows == INT32_MIN) {
2411 if ((ret_val = SDDS_MPI_BufferedRead((void *)&(MPI_dataset->total_rows), sizeof(int64_t), SDDS_dataset, fBuffer)) < 0)
2412 return -1;
2413 } else {
2414 MPI_dataset->total_rows = total_rows;
2415 }
2416 if (!ret_val)
2417 return 0;
2418 if (!SDDS_StartPage(SDDS_dataset, 0)) {
2419 SDDS_SetError("Unable to read page--couldn't start page (SDDS_MPI_BufferedReadNonNativeBinaryTitle)");
2420 return (0);
2421 }
2422 /*read parameters */
2423 if (!SDDS_MPI_ReadNonNativeBinaryParameters(SDDS_dataset, fBuffer)) {
2424 SDDS_SetError("Unable to read page--parameter reading error (SDDS_MPI_BufferedNonNativeReadTitle)");
2425 return (0);
2426 }
2427 /*read arrays */
2428 if (!SDDS_MPI_ReadNonNativeBinaryArrays(SDDS_dataset, fBuffer)) {
2429 SDDS_SetError("Unable to read page--array reading error (SDDS_MPI_BufferedNonNativeReadTitle)");
2430 return (0);
2431 }
2432
2433 return 1;
2434}
int32_t SDDS_MPI_ReadNonNativeBinaryParameters(SDDS_DATASET *SDDS_dataset, SDDS_FILEBUFFER *fBuffer)
Read non-native binary parameters from the SDDS dataset using MPI.
int32_t SDDS_MPI_ReadNonNativeBinaryArrays(SDDS_DATASET *SDDS_dataset, SDDS_FILEBUFFER *fBuffer)
Reads non-native binary arrays from a binary file buffer into the SDDS dataset using MPI.
void SDDS_SwapLong(int32_t *data)
Swaps the endianness of a 32-bit integer.

◆ SDDS_MPI_BufferedWrite()

int32_t SDDS_MPI_BufferedWrite ( void * target,
int64_t targetSize,
SDDS_DATASET * SDDS_dataset )

Buffered write to an SDDS dataset using MPI.

This function writes data to the SDDS dataset using a buffer. If the buffer has sufficient space, the data is copied into the buffer. Otherwise, the buffer is flushed to the file, and the new data is either written directly or stored in the buffer.

Parameters
targetPointer to the data to write.
targetSizeThe size of the data to write, in bytes.
SDDS_datasetPointer to the SDDS_DATASET structure.
Returns
1 on success, 0 on failure.

Definition at line 714 of file SDDS_MPI_binary.c.

714 {
715 SDDS_FILEBUFFER *fBuffer;
716 MPI_DATASET *MPI_dataset;
717 int32_t mpi_code;
718
719#if MPI_DEBUG
720 logDebug("SDDS_MPI_BufferedWrite", SDDS_dataset);
721#endif
722 MPI_dataset = SDDS_dataset->MPI_dataset;
723 fBuffer = &(SDDS_dataset->fBuffer);
724
725 if (!fBuffer->bufferSize) {
726 if ((mpi_code = MPI_File_write(MPI_dataset->MPI_file, target, targetSize, MPI_BYTE, MPI_STATUS_IGNORE)) != MPI_SUCCESS) {
727 SDDS_MPI_GOTO_ERROR(stderr, "SDDS_MPI_WriteBufferedWrite(MPI_File_write_at failed)", mpi_code, 0);
728 return 0;
729 }
730 return 1;
731 }
732 if ((fBuffer->bytesLeft -= targetSize) >= 0) {
733 memcpy((char *)fBuffer->data, (char *)target, targetSize);
734 fBuffer->data += targetSize;
735#ifdef DEBUG
736 fprintf(stderr, "SDDS_MPI_BufferedWrite of %" PRId64 " bytes done in-memory, %" PRId64 " bytes left\n", targetSize, fBuffer->bytesLeft);
737#endif
738 return 1;
739 } else {
740 int64_t lastLeft;
741 /* add back what was subtracted in test above.
742 * lastLeft is the number of bytes left in the buffer before doing anything
743 * and also the number of bytes from the users data that get copied into the buffer.
744 */
745 lastLeft = (fBuffer->bytesLeft += targetSize);
746 /* copy part of the data into the buffer and write the buffer out */
747 memcpy((char *)fBuffer->data, (char *)target, (size_t)fBuffer->bytesLeft);
748 if ((mpi_code = MPI_File_write(MPI_dataset->MPI_file, fBuffer->buffer, (int)(fBuffer->bufferSize), MPI_BYTE, MPI_STATUS_IGNORE)) != MPI_SUCCESS) {
749 SDDS_MPI_GOTO_ERROR(stderr, "SDDS_MPI_WriteBufferedWrite(MPI_File_write_at failed)", mpi_code, 0);
750 return 0;
751 }
752
753 /* reset the data pointer and the bytesLeft value.
754 * also, determine if the remaining data is too large for the buffer.
755 * if so, just write it out.
756 */
757 fBuffer->data = fBuffer->buffer;
758 if ((targetSize -= lastLeft) > (fBuffer->bytesLeft = fBuffer->bufferSize)) {
759 if ((mpi_code = MPI_File_write_at(MPI_dataset->MPI_file, (MPI_Offset)(MPI_dataset->file_offset), (char *)target + lastLeft, targetSize, MPI_BYTE, MPI_STATUS_IGNORE)) != MPI_SUCCESS) {
760 SDDS_MPI_GOTO_ERROR(stderr, "SDDS_MPI_WriteBufferedWrite(MPI_File_write_at failed)", mpi_code, 0);
761 return 0;
762 }
763 return 1;
764 }
765 /* copy remaining data into the buffer.
766 * could do this with a recursive call, but this is more efficient.
767 */
768 memcpy((char *)fBuffer->data, (char *)target + lastLeft, targetSize);
769 fBuffer->data += targetSize;
770 fBuffer->bytesLeft -= targetSize;
771 return 1;
772 }
773}

◆ SDDS_MPI_BufferedWriteAll()

int32_t SDDS_MPI_BufferedWriteAll ( void * target,
int64_t targetSize,
SDDS_DATASET * SDDS_dataset )

Buffered write all to an SDDS dataset using MPI.

This function writes all data to the SDDS dataset using a buffer, ensuring that all data is written even if the buffer needs to be flushed multiple times.

Parameters
targetPointer to the data to write.
targetSizeThe size of the data to write, in bytes.
SDDS_datasetPointer to the SDDS_DATASET structure.
Returns
1 on success, 0 on failure.

Definition at line 786 of file SDDS_MPI_binary.c.

786 {
787 SDDS_FILEBUFFER *fBuffer;
788 MPI_DATASET *MPI_dataset;
789 int32_t mpi_code;
790
791#if MPI_DEBUG
792 logDebug("SDDS_MPI_BufferedWriteAll", SDDS_dataset);
793#endif
794 MPI_dataset = SDDS_dataset->MPI_dataset;
795 fBuffer = &(SDDS_dataset->fBuffer);
796
797 if (!fBuffer->bufferSize) {
798 if ((mpi_code = MPI_File_write_all(MPI_dataset->MPI_file, target, targetSize, MPI_BYTE, MPI_STATUS_IGNORE)) != MPI_SUCCESS) {
799 SDDS_MPI_GOTO_ERROR(stderr, "SDDS_MPI_WriteBufferedWrite(MPI_File_write_at failed)", mpi_code, 0);
800 return 0;
801 }
802 return 1;
803 }
804 if ((fBuffer->bytesLeft -= targetSize) >= 0) {
805 memcpy((char *)fBuffer->data, (char *)target, targetSize);
806 fBuffer->data += targetSize;
807#ifdef DEBUG
808 fprintf(stderr, "SDDS_MPI_BufferedWrite of %" PRId64 " bytes done in-memory, %" PRId64 " bytes left\n", targetSize, fBuffer->bytesLeft);
809#endif
810 return 1;
811 } else {
812 int64_t lastLeft;
813 /* add back what was subtracted in test above.
814 * lastLeft is the number of bytes left in the buffer before doing anything
815 * and also the number of bytes from the users data that get copied into the buffer.
816 */
817 lastLeft = (fBuffer->bytesLeft += targetSize);
818 /* copy part of the data into the buffer and write the buffer out */
819 memcpy((char *)fBuffer->data, (char *)target, (size_t)fBuffer->bytesLeft);
820 if ((mpi_code = MPI_File_write_all(MPI_dataset->MPI_file, fBuffer->buffer, (int)(fBuffer->bufferSize), MPI_BYTE, MPI_STATUS_IGNORE)) != MPI_SUCCESS) {
821 SDDS_MPI_GOTO_ERROR(stderr, "SDDS_MPI_WriteBufferedWrite(MPI_File_write_at failed)", mpi_code, 0);
822 return 0;
823 }
824
825 /* reset the data pointer and the bytesLeft value.
826 * also, determine if the remaining data is too large for the buffer.
827 * if so, just write it out.
828 */
829 fBuffer->data = fBuffer->buffer;
830 if ((targetSize -= lastLeft) > (fBuffer->bytesLeft = fBuffer->bufferSize)) {
831 if ((mpi_code = MPI_File_write_all(MPI_dataset->MPI_file, (char *)target + lastLeft, targetSize, MPI_BYTE, MPI_STATUS_IGNORE)) != MPI_SUCCESS) {
832 SDDS_MPI_GOTO_ERROR(stderr, "SDDS_MPI_WriteBufferedWrite(MPI_File_write_at failed)", mpi_code, 0);
833 return 0;
834 }
835 return 1;
836 }
837 /* copy remaining data into the buffer.
838 * could do this with a recursive call, but this is more efficient.
839 */
840 memcpy((char *)fBuffer->data, (char *)target + lastLeft, targetSize);
841 fBuffer->data += targetSize;
842 fBuffer->bytesLeft -= targetSize;
843 return 1;
844 }
845}

◆ SDDS_MPI_CollectiveReadByRow()

int32_t SDDS_MPI_CollectiveReadByRow ( SDDS_DATASET * SDDS_dataset)

Reads SDDS dataset rows collectively by row using MPI parallel I/O.

This function performs a collective read operation where each MPI process reads its assigned rows of the SDDS dataset. It handles buffering of row data, ensures synchronization among MPI processes, and manages error handling. The function supports only binary string types for non-string data and flushes the buffer upon completion.

Parameters
[in,out]SDDS_datasetPointer to the SDDS_DATASET structure where the data will be stored.
Returns
int32_t Returns 1 on successful read, 0 on failure.

Definition at line 2684 of file SDDS_MPI_binary.c.

2684 {
2685
2686 SDDS_FILEBUFFER *fBuffer;
2687 MPI_DATASET *MPI_dataset;
2688 int32_t type, size;
2689 int64_t min_rows, i, j;
2690 SDDS_LAYOUT *layout;
2691
2692 MPI_dataset = SDDS_dataset->MPI_dataset;
2693 fBuffer = &(SDDS_dataset->fBuffer);
2694 layout = &(SDDS_dataset->layout);
2695
2696 if (!MPI_dataset->master_read) {
2697 SDDS_SetError("Cannot read row with collective io when master is not reading the data.");
2698 return 0;
2699 }
2700 min_rows = MPI_dataset->total_rows / MPI_dataset->n_processors;
2701 for (i = 0; i < min_rows; i++) {
2702 for (j = 0; j < layout->n_columns; j++) {
2703 type = layout->column_definition[j].type;
2704 size = SDDS_type_size[type - 1];
2705 if (type == SDDS_STRING) {
2706 SDDS_SetError("Can not write binary string in collective io.");
2707 return 0;
2708 }
2709 if (!SDDS_MPI_BufferedReadAll((char *)SDDS_dataset->data[j] + i * size, size, SDDS_dataset, fBuffer))
2710 return 0;
2711 }
2712 }
2713 for (i = min_rows; i < MPI_dataset->n_rows; i++)
2714 if (!SDDS_MPI_ReadBinaryRow(SDDS_dataset, i, 0))
2715 return 0;
2716
2717 return 1;
2718}
int32_t SDDS_MPI_ReadBinaryRow(SDDS_DATASET *SDDS_dataset, int64_t row, int32_t skip)
Read a binary row from the SDDS dataset using MPI.
int32_t SDDS_MPI_BufferedReadAll(void *target, int64_t targetSize, SDDS_DATASET *SDDS_dataset, SDDS_FILEBUFFER *fBuffer)
Buffered read all from an SDDS dataset using MPI.

◆ SDDS_MPI_CollectiveWriteByRow()

int32_t SDDS_MPI_CollectiveWriteByRow ( SDDS_DATASET * SDDS_dataset)

Writes SDDS dataset rows collectively by row using MPI parallel I/O.

This function performs a collective write operation where each MPI process writes its assigned rows of the SDDS dataset. It handles buffering of row data, ensures synchronization among MPI processes, and manages error handling. The function supports only binary string types for non-string data and flushes the buffer upon completion.

Parameters
[in,out]SDDS_datasetPointer to the SDDS_DATASET structure containing the data to be written.
Returns
int32_t Returns 1 on successful write, 0 on failure.

Definition at line 2562 of file SDDS_MPI_binary.c.

2562 {
2563 MPI_DATASET *MPI_dataset;
2564 SDDS_LAYOUT *layout;
2565 int32_t mpi_code, type, size;
2566 int64_t i, j, n_rows, min_rows, writeBytes;
2567 SDDS_FILEBUFFER *fBuffer;
2568
2569#if MPI_DEBUG
2570 logDebug("SDDS_MPI_CollectiveWriteByRow", SDDS_dataset);
2571#endif
2572
2573 MPI_dataset = SDDS_dataset->MPI_dataset;
2574 layout = &(SDDS_dataset->layout);
2575 fBuffer = &(SDDS_dataset->fBuffer);
2576 n_rows = SDDS_dataset->n_rows;
2577 MPI_Allreduce(&n_rows, &min_rows, 1, MPI_INT64_T, MPI_MIN, MPI_dataset->comm);
2578 for (i = 0; i < min_rows; i++) {
2579 for (j = 0; j < layout->n_columns; j++) {
2580 type = layout->column_definition[j].type;
2581 size = SDDS_type_size[type - 1];
2582 if (type == SDDS_STRING) {
2583 SDDS_SetError("Can not write binary string in collective io.");
2584 return 0;
2585 }
2586 if (!SDDS_MPI_BufferedWriteAll((char *)SDDS_dataset->data[j] + i * size, size, SDDS_dataset))
2587 return 0;
2588 }
2589 }
2590
2591 if ((writeBytes = fBuffer->bufferSize - fBuffer->bytesLeft)) {
2592 if (writeBytes < 0) {
2593 SDDS_SetError("Unable to flush buffer: negative byte count (SDDS_FlushBuffer).");
2594 return 0;
2595 }
2596 if ((mpi_code = MPI_File_write_all(MPI_dataset->MPI_file, fBuffer->buffer, writeBytes, MPI_BYTE, MPI_STATUS_IGNORE)) != MPI_SUCCESS) {
2597 SDDS_MPI_GOTO_ERROR(stderr, "SDDS_MPI_FlushBuffer(MPI_File_write_at failed)", mpi_code, 0);
2598 return 0;
2599 }
2600 fBuffer->bytesLeft = fBuffer->bufferSize;
2601 fBuffer->data = fBuffer->buffer;
2602 }
2603
2604 for (i = min_rows; i < n_rows; i++)
2605 if (!SDDS_MPI_WriteBinaryRow(SDDS_dataset, i))
2606 return 0;
2607 if (!SDDS_MPI_FlushBuffer(SDDS_dataset))
2608 return 0;
2609 return 1;
2610}
int32_t SDDS_MPI_WriteBinaryRow(SDDS_DATASET *SDDS_dataset, int64_t row)
Write a binary row to an SDDS dataset using MPI.
int32_t SDDS_MPI_FlushBuffer(SDDS_DATASET *SDDS_dataset)
Flush the buffer by writing any remaining data to the MPI file.
int32_t SDDS_MPI_BufferedWriteAll(void *target, int64_t targetSize, SDDS_DATASET *SDDS_dataset)
Buffered write all to an SDDS dataset using MPI.

◆ SDDS_MPI_CollectiveWriteNonNativeByRow()

int32_t SDDS_MPI_CollectiveWriteNonNativeByRow ( SDDS_DATASET * SDDS_dataset)

Writes non-native binary SDDS dataset rows collectively by row using MPI parallel I/O.

This function performs a collective write operation for non-native binary SDDS datasets, where each MPI process writes its assigned rows. It handles buffering of row data, ensures synchronization among MPI processes, and manages error handling. The function supports only binary string types for non-string data and flushes the buffer upon completion.

Parameters
[in,out]SDDS_datasetPointer to the SDDS_DATASET structure containing the data to be written.
Returns
int32_t Returns 1 on successful write, 0 on failure.

Definition at line 2623 of file SDDS_MPI_binary.c.

2623 {
2624 MPI_DATASET *MPI_dataset;
2625 SDDS_LAYOUT *layout;
2626 int32_t mpi_code, type, size;
2627 int64_t i, j, n_rows, min_rows, writeBytes;
2628 SDDS_FILEBUFFER *fBuffer;
2629
2630#if MPI_DEBUG
2631 logDebug("SDDS_MPI_CollectiveWriteNonNativeByRow", SDDS_dataset);
2632#endif
2633
2634 MPI_dataset = SDDS_dataset->MPI_dataset;
2635 layout = &(SDDS_dataset->layout);
2636 fBuffer = &(SDDS_dataset->fBuffer);
2637 n_rows = SDDS_dataset->n_rows;
2638 MPI_Allreduce(&n_rows, &min_rows, 1, MPI_INT64_T, MPI_MIN, MPI_dataset->comm);
2639 for (i = 0; i < min_rows; i++) {
2640 for (j = 0; j < layout->n_columns; j++) {
2641 type = layout->column_definition[j].type;
2642 size = SDDS_type_size[type - 1];
2643 if (type == SDDS_STRING) {
2644 SDDS_SetError("Can not write binary string in collective io.");
2645 return 0;
2646 }
2647 if (!SDDS_MPI_BufferedWriteAll((char *)SDDS_dataset->data[j] + i * size, size, SDDS_dataset))
2648 return 0;
2649 }
2650 }
2651
2652 if ((writeBytes = fBuffer->bufferSize - fBuffer->bytesLeft)) {
2653 if (writeBytes < 0) {
2654 SDDS_SetError("Unable to flush buffer: negative byte count (SDDS_FlushBuffer).");
2655 return 0;
2656 }
2657 if ((mpi_code = MPI_File_write_all(MPI_dataset->MPI_file, fBuffer->buffer, writeBytes, MPI_BYTE, MPI_STATUS_IGNORE)) != MPI_SUCCESS) {
2658 SDDS_MPI_GOTO_ERROR(stderr, "SDDS_MPI_FlushBuffer(MPI_File_write_at failed)", mpi_code, 0);
2659 return 0;
2660 }
2661 fBuffer->bytesLeft = fBuffer->bufferSize;
2662 fBuffer->data = fBuffer->buffer;
2663 }
2664
2665 for (i = min_rows; i < n_rows; i++)
2666 if (!SDDS_MPI_WriteNonNativeBinaryRow(SDDS_dataset, i))
2667 return 0;
2668 if (!SDDS_MPI_FlushBuffer(SDDS_dataset))
2669 return 0;
2670 return 1;
2671}
int32_t SDDS_MPI_WriteNonNativeBinaryRow(SDDS_DATASET *SDDS_dataset, int64_t row)
Write a non-native binary row to an SDDS dataset using MPI.

◆ SDDS_MPI_CountRowsOfInterest()

int64_t SDDS_MPI_CountRowsOfInterest ( SDDS_DATASET * SDDS_dataset,
int64_t start_row,
int64_t end_row )

Count the number of rows marked as "of interest" within a specified range.

This function iterates through the rows of the SDDS dataset from start_row to end_row and counts how many rows have their row_flag set to indicate they are of interest.

Parameters
SDDS_datasetPointer to the SDDS_DATASET structure.
start_rowThe starting row index (inclusive) to begin counting.
end_rowThe ending row index (exclusive) to stop counting.
Returns
The total number of rows marked as of interest within the specified range.

Definition at line 903 of file SDDS_MPI_binary.c.

903 {
904 int64_t i, rows = 0;
905 for (i = start_row; i < end_row; i++) {
906 if (i > SDDS_dataset->n_rows - 1)
907 break;
908 if (SDDS_dataset->row_flag[i])
909 rows++;
910 }
911 return rows;
912}

◆ SDDS_MPI_FlushBuffer()

int32_t SDDS_MPI_FlushBuffer ( SDDS_DATASET * SDDS_dataset)

Flush the buffer by writing any remaining data to the MPI file.

This function ensures that any data remaining in the buffer is written to the MPI file. It handles error checking and resets the buffer pointers upon successful write.

Parameters
SDDS_datasetPointer to the SDDS_DATASET structure.
Returns
  • 1 on successful flush.
  • 0 on failure.

Definition at line 858 of file SDDS_MPI_binary.c.

858 {
859 SDDS_FILEBUFFER *fBuffer;
860 MPI_DATASET *MPI_dataset;
861 int64_t writeBytes;
862 int32_t mpi_code;
863
864#if MPI_DEBUG
865 logDebug("SDDS_MPI_FlushBuffer", SDDS_dataset);
866#endif
867
868 MPI_dataset = SDDS_dataset->MPI_dataset;
869 fBuffer = &(SDDS_dataset->fBuffer);
870
871 if (!fBuffer->bufferSize)
872 return 1;
873
874 if ((writeBytes = fBuffer->bufferSize - fBuffer->bytesLeft)) {
875 if (writeBytes < 0) {
876 SDDS_SetError("Unable to flush buffer: negative byte count (SDDS_FlushBuffer).");
877 return 0;
878 }
879#ifdef DEBUG
880 fprintf(stderr, "Writing %" PRId64 " bytes to disk\n", writeBytes);
881#endif
882 if ((mpi_code = MPI_File_write(MPI_dataset->MPI_file, fBuffer->buffer, writeBytes, MPI_BYTE, MPI_STATUS_IGNORE)) != MPI_SUCCESS) {
883 SDDS_MPI_GOTO_ERROR(stderr, "SDDS_MPI_FlushBuffer(MPI_File_write_at failed)", mpi_code, 0);
884 return 0;
885 }
886 fBuffer->bytesLeft = fBuffer->bufferSize;
887 fBuffer->data = fBuffer->buffer;
888 }
889 return 1;
890}

◆ SDDS_MPI_Get_Column_Size()

MPI_Offset SDDS_MPI_Get_Column_Size ( SDDS_DATASET * SDDS_dataset)

Get the total size of all columns in an SDDS dataset.

This function calculates the total size in bytes required to store all columns of the SDDS dataset in binary format. For string columns, it includes space for the string length and the fixed maximum string length.

Parameters
SDDS_datasetPointer to the SDDS_DATASET structure.
Returns
The total size of all columns in bytes.

Definition at line 683 of file SDDS_MPI_binary.c.

683 {
684 int64_t i;
685 MPI_Offset column_offset = 0;
686 SDDS_LAYOUT *layout;
687 int32_t currentDefaultStringLength;
688
689 layout = &SDDS_dataset->layout;
690 currentDefaultStringLength = SDDS_GetLockedDefaultStringLength();
691 for (i = 0; i < layout->n_columns; i++) {
692 if (layout->column_definition[i].type == SDDS_STRING)
693 /* for string type column, the fixed column size defined by user use SDDS_SetDefaultStringLength(value),
694 and the length of string is written before the string */
695 column_offset += sizeof(int32_t) + currentDefaultStringLength * sizeof(char);
696 else
697 column_offset += SDDS_type_size[layout->column_definition[i].type - 1];
698 }
699 return column_offset;
700}

◆ SDDS_MPI_GetLockedForceFileSync()

static short SDDS_MPI_GetLockedForceFileSync ( void )
static

Definition at line 90 of file SDDS_MPI_binary.c.

90 {
91 short value;
92 mdb_thread_lock(&SDDS_MPI_force_file_sync_lock);
93 value = SDDS_MPI_force_file_sync;
94 mdb_thread_unlock(&SDDS_MPI_force_file_sync_lock);
95 return value;
96}

◆ SDDS_MPI_GetLockedWriteKludgeUsleep()

static long SDDS_MPI_GetLockedWriteKludgeUsleep ( void )
static

Definition at line 82 of file SDDS_MPI_binary.c.

82 {
83 long value;
84 mdb_thread_lock(&SDDS_MPI_write_kludge_usleep_lock);
85 value = SDDS_MPI_write_kludge_usleep;
86 mdb_thread_unlock(&SDDS_MPI_write_kludge_usleep_lock);
87 return value;
88}

◆ SDDS_MPI_GetTitleOffset()

MPI_Offset SDDS_MPI_GetTitleOffset ( SDDS_DATASET * SDDS_dataset)

Calculates the byte offset for the title section in a non-native binary SDDS dataset.

This function computes the total byte offset required to read the number of rows, parameters, and arrays defined in the SDDS dataset. It accounts for different data types, including strings, and variable-length parameters and arrays. The calculated offset is used to position the MPI file view correctly for reading.

Parameters
[in]SDDS_datasetPointer to the SDDS_DATASET structure containing the dataset layout and data.
Returns
MPI_Offset The total byte offset of the title section in the binary file.

Definition at line 2448 of file SDDS_MPI_binary.c.

2448 {
2449 int64_t i, j;
2450 MPI_Offset offset = 0;
2451 SDDS_LAYOUT *layout;
2452
2453 layout = &(SDDS_dataset->layout);
2454 offset += sizeof(int32_t);
2455 if (SDDS_dataset->n_rows > INT32_MAX) {
2456 offset += sizeof(int64_t);
2457 }
2458 for (i = 0; i < layout->n_parameters; i++) {
2459 if (layout->parameter_definition[i].fixed_value)
2460 continue;
2461 if (layout->parameter_definition[i].type == SDDS_STRING) {
2462 if (*(char **)SDDS_dataset->parameter[i])
2463 offset += sizeof(int32_t) + sizeof(char) * strlen(*(char **)SDDS_dataset->parameter[i]);
2464 else
2465 offset += sizeof(int32_t); /*write length 0 for NULL string */
2466 } else {
2467 offset += SDDS_type_size[layout->parameter_definition[i].type - 1];
2468 }
2469 }
2470 for (i = 0; i < layout->n_arrays; i++) {
2471 if (!(SDDS_dataset->array[i].dimension)) {
2472 offset += layout->array_definition[i].dimensions * sizeof(int32_t);
2473 continue;
2474 }
2475 offset += sizeof(*(SDDS_dataset->array)[i].dimension) * layout->array_definition[i].dimensions;
2476 if (layout->array_definition[i].type == SDDS_STRING) {
2477 for (j = 0; j < SDDS_dataset->array[i].elements; j++) {
2478 if (((char **)SDDS_dataset->array[i].data)[j])
2479 offset += sizeof(int32_t) + sizeof(char) * strlen(((char **)SDDS_dataset->array[i].data)[j]);
2480 else
2481 offset += sizeof(int32_t);
2482 }
2483 } else {
2484 offset += SDDS_type_size[layout->array_definition[i].type - 1] * SDDS_dataset->array[i].elements;
2485 }
2486 }
2487 return offset;
2488}

◆ SDDS_MPI_GetTotalRows()

int64_t SDDS_MPI_GetTotalRows ( SDDS_DATASET * SDDS_dataset)

Get the total number of rows across all MPI processes.

This function uses MPI_Reduce to sum the number of rows (n_rows) from all processes and returns the total number of rows to the root process (process 0).

Parameters
SDDS_datasetPointer to the SDDS_DATASET structure.
Returns
The total number of rows across all MPI processes. Only valid on the root process.

Definition at line 923 of file SDDS_MPI_binary.c.

923 {
924 int64_t total_rows;
925 MPI_Reduce(&(SDDS_dataset->n_rows), &total_rows, 1, MPI_INT64_T, MPI_SUM, 0, SDDS_dataset->MPI_dataset->comm);
926 return total_rows;
927}

◆ SDDS_MPI_ReadBinaryArrays()

int32_t SDDS_MPI_ReadBinaryArrays ( SDDS_DATASET * SDDS_dataset,
SDDS_FILEBUFFER * fBuffer )

Read binary arrays from the SDDS dataset using MPI.

This function reads all arrays defined in the SDDS dataset in binary format using MPI. It handles reading array dimensions, allocating memory for array data, and reading the actual array data. For string arrays, it reads each string individually.

Parameters
SDDS_datasetPointer to the SDDS_DATASET structure.
fBufferPointer to the SDDS_FILEBUFFER structure managing the buffer.
Returns
  • 1 on successful read of all arrays.
  • 0 on failure to read any part of the arrays.

Definition at line 1626 of file SDDS_MPI_binary.c.

1626 {
1627 int32_t i, j;
1628 SDDS_LAYOUT *layout;
1629 /* char *predefined_format; */
1630 /* static char buffer[SDDS_MAXLINE]; */
1631 SDDS_ARRAY *array;
1632
1633 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_MPI_ReadBinaryArrays"))
1634 return (0);
1635 layout = &SDDS_dataset->layout;
1636 if (!layout->n_arrays)
1637 return (1);
1638
1639 if (!SDDS_dataset->array) {
1640 SDDS_SetError("Unable to read array--pointer to structure storage area is NULL (SDDS_MPI_ReadBinaryArrays)");
1641 return (0);
1642 }
1643 for (i = 0; i < layout->n_arrays; i++) {
1644 array = SDDS_dataset->array + i;
1645 if (array->definition && !SDDS_FreeArrayDefinition(array->definition)) {
1646 SDDS_SetError("Unable to get array--array definition corrupted (SDDS_MPI_ReadBinaryArrays)");
1647 return (0);
1648 }
1649 if (!SDDS_CopyArrayDefinition(&array->definition, layout->array_definition + i)) {
1650 SDDS_SetError("Unable to read array--definition copy failed (SDDS_MPI_ReadBinaryArrays)");
1651 return (0);
1652 }
1653 /*if (array->dimension) free(array->dimension); */
1654 if (!(array->dimension = SDDS_Realloc(array->dimension, sizeof(*array->dimension) * array->definition->dimensions))) {
1655 SDDS_SetError("Unable to read array--allocation failure (SDDS_MPI_ReadBinaryArrays)");
1656 return (0);
1657 }
1658 if (!SDDS_MPI_BufferedRead(array->dimension, sizeof(*array->dimension) * array->definition->dimensions, SDDS_dataset, fBuffer)) {
1659 SDDS_SetError("Unable to read arrays--failure reading dimensions (SDDS_MPI_ReadBinaryArrays)");
1660 return (0);
1661 }
1662 array->elements = 1;
1663 for (j = 0; j < array->definition->dimensions; j++)
1664 array->elements *= array->dimension[j];
1665 if (array->data)
1666 free(array->data);
1667 array->data = array->pointer = NULL;
1668 if (array->elements == 0)
1669 continue;
1670 if (array->elements < 0) {
1671 SDDS_SetError("Unable to read array--number of elements is negative (SDDS_MPI_ReadBinaryArrays)");
1672 return (0);
1673 }
1674 if (!(array->data = SDDS_Realloc(array->data, array->elements * SDDS_type_size[array->definition->type - 1]))) {
1675 SDDS_SetError("Unable to read array--allocation failure (SDDS_MPI_ReadBinaryArrays)");
1676 return (0);
1677 }
1678 if (array->definition->type == SDDS_STRING) {
1679 for (j = 0; j < array->elements; j++) {
1680 if (!(((char **)(array->data))[j] = SDDS_MPI_ReadBinaryString(SDDS_dataset, fBuffer, 0))) {
1681 SDDS_SetError("Unable to read arrays--failure reading string (SDDS_MPI_ReadBinaryArrays)");
1682 return (0);
1683 }
1684 }
1685 } else {
1686 if (!SDDS_MPI_BufferedRead(array->data, SDDS_type_size[array->definition->type - 1] * array->elements, SDDS_dataset, fBuffer)) {
1687 SDDS_SetError("Unable to read arrays--failure reading values (SDDS_MPI_ReadBinaryArrays)");
1688 return (0);
1689 }
1690 }
1691 }
1692 return (1);
1693}
char * SDDS_MPI_ReadBinaryString(SDDS_DATASET *SDDS_dataset, SDDS_FILEBUFFER *fBuffer, int32_t skip)
Read a binary string from the SDDS dataset using MPI.
int32_t SDDS_FreeArrayDefinition(ARRAY_DEFINITION *source)
Frees memory allocated for an array definition.
int32_t SDDS_CheckDataset(SDDS_DATASET *SDDS_dataset, const char *caller)
Validates the SDDS dataset pointer.
Definition SDDS_utils.c:618
ARRAY_DEFINITION * SDDS_CopyArrayDefinition(ARRAY_DEFINITION **target, ARRAY_DEFINITION *source)
Creates a copy of an array definition.
void * SDDS_Realloc(void *old_ptr, size_t new_size)
Reallocates memory to a new size.
Definition SDDS_utils.c:743

◆ SDDS_MPI_ReadBinaryPage()

int32_t SDDS_MPI_ReadBinaryPage ( SDDS_DATASET * SDDS_dataset)

Reads a binary page from an SDDS dataset using MPI parallel I/O.

This function reads a page of data from a binary SDDS file in parallel using MPI. It handles reading the page title, distributing the rows among MPI processes, and reading the column or row data depending on the dataset's data mode. It also manages error handling and supports read recovery.

Parameters
[in,out]SDDS_datasetPointer to the SDDS_DATASET structure where the page data will be stored.
Returns
int32_t Returns the page number on success, 0 on failure, or -1 if end-of-file is reached.

Definition at line 1994 of file SDDS_MPI_binary.c.

1994 {
1995 int32_t mpi_code, type = 0, retval, master_read;
1996 int64_t i, j, n_rows, prev_rows;
1997 MPI_DATASET *MPI_dataset;
1998 SDDS_FILEBUFFER *fBuffer;
1999 MPI_Status status;
2000 MPI_Offset offset;
2001 long ID_offset;
2002
2003 MPI_dataset = SDDS_dataset->MPI_dataset;
2004 master_read = MPI_dataset->master_read;
2005
2006 if (SDDS_dataset->autoRecovered)
2007 return -1;
2008 if (SDDS_dataset->swapByteOrder) {
2009 return SDDS_MPI_ReadNonNativeBinaryPage(SDDS_dataset);
2010 }
2011 /* static char s[SDDS_MAXLINE]; */
2012 n_rows = 0;
2013 SDDS_SetReadRecoveryMode(SDDS_dataset, 0);
2014 if (MPI_dataset->file_offset >= MPI_dataset->file_size)
2015 return (SDDS_dataset->page_number = -1);
2016 if ((mpi_code = MPI_File_set_view(MPI_dataset->MPI_file, MPI_dataset->file_offset, MPI_BYTE, MPI_BYTE, "native", MPI_INFO_NULL)) != MPI_SUCCESS) {
2017 SDDS_MPI_GOTO_ERROR(stderr, "Unable to set view for read binary page", mpi_code, 0);
2018 SDDS_SetError("Unable to set view for read binary page(1)");
2019 return 0;
2020 }
2021#if defined(MASTER_READTITLE_ONLY)
2022 if (MPI_dataset->myid == 0)
2023#endif
2024 retval = SDDS_MPI_BufferedReadBinaryTitle(SDDS_dataset);
2025#if defined(MASTER_READTITLE_ONLY)
2026 MPI_Bcast(&retval, 1, MPI_INT, 0, MPI_dataset->comm);
2027#endif
2028 /*end of file reached */
2029 if (retval < 0)
2030 return (SDDS_dataset->page_number = -1);
2031 if (retval == 0) {
2032 SDDS_SetError("Unable to read the SDDS title (row number, parameter and/or array) data");
2033 return 0;
2034 }
2035#if defined(MASTER_READTITLE_ONLY)
2036 SDDS_MPI_BroadcastTitleData(SDDS_dataset);
2037#endif
2038 MPI_dataset->file_offset += SDDS_MPI_GetTitleOffset(SDDS_dataset);
2039 if (MPI_dataset->total_rows < 0) {
2040 SDDS_SetError("Unable to read page--negative number of rows (SDDS_MPI_ReadBinaryPage)");
2041 return (0);
2042 }
2043 if (MPI_dataset->total_rows > SDDS_GetRowLimit()) {
2044 /* the number of rows is "unreasonably" large---treat like end-of-file */
2045 return (SDDS_dataset->page_number = -1);
2046 }
2047 prev_rows = 0;
2048 if (master_read) {
2049 n_rows = MPI_dataset->total_rows / MPI_dataset->n_processors;
2050 prev_rows = MPI_dataset->myid * n_rows;
2051 if (MPI_dataset->myid < (ID_offset = MPI_dataset->total_rows % (MPI_dataset->n_processors))) {
2052 n_rows++;
2053 prev_rows += MPI_dataset->myid;
2054 } else
2055 prev_rows += ID_offset;
2056 } else {
2057 if (MPI_dataset->myid == 0)
2058 n_rows = 0;
2059 else {
2060 n_rows = MPI_dataset->total_rows / (MPI_dataset->n_processors - 1);
2061 prev_rows = (MPI_dataset->myid - 1) * n_rows;
2062 if (MPI_dataset->myid <= (ID_offset = MPI_dataset->total_rows % (MPI_dataset->n_processors - 1))) {
2063 n_rows++;
2064 prev_rows += (MPI_dataset->myid - 1);
2065 } else
2066 prev_rows += ID_offset;
2067 }
2068 }
2069 MPI_dataset->start_row = prev_rows; /* This number will be used as the paritlce ID offset */
2070 if (!SDDS_StartPage(SDDS_dataset, 0) || !SDDS_LengthenTable(SDDS_dataset, n_rows)) {
2071 SDDS_SetError("Unable to read page--couldn't start page (SDDS_MPI_ReadBinaryPage)");
2072 return (0);
2073 }
2074 offset = MPI_dataset->file_offset;
2075 fBuffer = &SDDS_dataset->fBuffer;
2076
2077 if (SDDS_dataset->layout.data_mode.column_major) {
2078 /*read by column buffer is not need */
2079 for (i = 0; i < SDDS_dataset->layout.n_columns; i++) {
2080 type = SDDS_dataset->layout.column_definition[i].type;
2081 if (type == SDDS_STRING) {
2082 SDDS_SetError("Can not read string column from SDDS3 (SDDS_MPI_ReadBinaryPage");
2083 return 0;
2084 }
2085 MPI_dataset->file_offset = offset + (MPI_Offset)prev_rows * SDDS_type_size[type - 1];
2086 if ((mpi_code = MPI_File_set_view(MPI_dataset->MPI_file, MPI_dataset->file_offset, MPI_BYTE, MPI_BYTE, "native", MPI_INFO_NULL)) != MPI_SUCCESS) {
2087 SDDS_SetError("Unable to set view for read binary columns");
2088 return 0;
2089 }
2090 if (!MPI_dataset->collective_io) {
2091 if ((mpi_code = MPI_File_read(MPI_dataset->MPI_file, (char *)SDDS_dataset->data[i], n_rows * SDDS_type_size[type - 1], MPI_BYTE, &status)) != MPI_SUCCESS) {
2092 SDDS_SetError("Unable to set view for read binary columns");
2093 return 0;
2094 }
2095 } else {
2096 if ((mpi_code = MPI_File_read_all(MPI_dataset->MPI_file, (char *)SDDS_dataset->data[i], n_rows * SDDS_type_size[type - 1], MPI_BYTE, &status)) != MPI_SUCCESS) {
2097 SDDS_SetError("Unable to set view for read binary columns");
2098 return 0;
2099 }
2100 }
2101 offset += (MPI_Offset)MPI_dataset->total_rows * SDDS_type_size[type - 1];
2102 }
2103 MPI_dataset->n_rows = SDDS_dataset->n_rows = n_rows;
2104 MPI_dataset->file_offset = offset;
2105 } else {
2106 /* read row by row */
2107 if (!fBuffer->buffer) {
2108 fBuffer->bufferSize = SDDS_GetLockedDefaultReadBufferSize();
2109 if (!(fBuffer->buffer = fBuffer->data = SDDS_Malloc(sizeof(char) * (fBuffer->bufferSize + 1)))) {
2110 SDDS_SetError("Unable to do buffered read--allocation failure");
2111 return 0;
2112 }
2113 fBuffer->bytesLeft = 0;
2114 fBuffer->data[0] = 0;
2115 }
2116 if (fBuffer->bytesLeft > 0) {
2117 /* discard the extra data for reading next page */
2118 fBuffer->data[0] = 0;
2119 fBuffer->bytesLeft = 0;
2120 }
2121 MPI_dataset->file_offset += (MPI_Offset)prev_rows * MPI_dataset->column_offset;
2122 if ((mpi_code = MPI_File_set_view(MPI_dataset->MPI_file, MPI_dataset->file_offset, MPI_BYTE, MPI_BYTE, "native", MPI_INFO_NULL)) != MPI_SUCCESS) {
2123 SDDS_MPI_GOTO_ERROR(stderr, "Unable to set view for read binary rows", mpi_code, 0);
2124 SDDS_SetError("Unable to set view for read binary rows");
2125 return 0;
2126 }
2127 if (!master_read || !MPI_dataset->collective_io) {
2128 for (j = 0; j < n_rows; j++) {
2129 if (!SDDS_MPI_ReadBinaryRow(SDDS_dataset, j, 0)) {
2130 SDDS_dataset->n_rows = j;
2131 if (SDDS_dataset->autoRecover) {
2132#if defined(DEBUG)
2133 fprintf(stderr, "Doing auto-read recovery\n");
2134#endif
2135 SDDS_dataset->autoRecovered = 1;
2137 return (SDDS_dataset->page_number = MPI_dataset->n_page);
2138 }
2139 SDDS_SetError("Unable to read page--error reading data row (SDDS_MPI_ReadBinaryPage)");
2140 SDDS_SetReadRecoveryMode(SDDS_dataset, 1);
2141 return (0);
2142 }
2143 }
2144 MPI_dataset->n_rows = SDDS_dataset->n_rows = j;
2145 } else {
2146 MPI_dataset->n_rows = SDDS_dataset->n_rows = n_rows;
2147 if (!SDDS_MPI_CollectiveReadByRow(SDDS_dataset))
2148 return 0;
2149 }
2150 MPI_dataset->file_offset = offset + MPI_dataset->total_rows * MPI_dataset->column_offset;
2151 }
2152 MPI_dataset->n_page++;
2153 return (SDDS_dataset->page_number = MPI_dataset->n_page);
2154}
int32_t SDDS_MPI_BufferedReadBinaryTitle(SDDS_DATASET *SDDS_dataset)
Buffers and reads the binary title data from an SDDS dataset using MPI.
MPI_Offset SDDS_MPI_GetTitleOffset(SDDS_DATASET *SDDS_dataset)
Calculates the byte offset for the title section in a non-native binary SDDS dataset.
int32_t SDDS_MPI_CollectiveReadByRow(SDDS_DATASET *SDDS_dataset)
Reads SDDS dataset rows collectively by row using MPI parallel I/O.
int32_t SDDS_MPI_BroadcastTitleData(SDDS_DATASET *SDDS_dataset)
Broadcasts the title data (parameters and arrays) of the SDDS dataset to all MPI processes.
int32_t SDDS_MPI_ReadNonNativeBinaryPage(SDDS_DATASET *SDDS_dataset)
Reads a non-native binary page from an SDDS dataset using MPI parallel I/O.
void SDDS_SetReadRecoveryMode(SDDS_DATASET *SDDS_dataset, int32_t mode)
Sets the read recovery mode for an SDDS dataset.
int32_t SDDS_LengthenTable(SDDS_DATASET *SDDS_dataset, int64_t n_additional_rows)
int64_t SDDS_GetRowLimit()
void SDDS_ClearErrors()
Clears all recorded error messages from the SDDS error stack.
Definition SDDS_utils.c:354

◆ SDDS_MPI_ReadBinaryParameters()

int32_t SDDS_MPI_ReadBinaryParameters ( SDDS_DATASET * SDDS_dataset,
SDDS_FILEBUFFER * fBuffer )

Read binary parameters from the SDDS dataset using MPI.

This function reads all non-fixed parameters from the SDDS dataset in binary format using MPI. It iterates through each parameter, handling string parameters by reading them as binary strings, and other types by reading their binary representations directly into the dataset's parameter storage.

Parameters
SDDS_datasetPointer to the SDDS_DATASET structure.
fBufferPointer to the SDDS_FILEBUFFER structure managing the buffer.
Returns
  • 1 on successful read of all parameters.
  • 0 on failure to read any parameter.

Definition at line 1523 of file SDDS_MPI_binary.c.

1523 {
1524 int32_t i;
1525 SDDS_LAYOUT *layout;
1526 /* char *predefined_format; */
1527 char buffer[SDDS_MAXLINE];
1528
1529 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_MPI_ReadBinaryParameters"))
1530 return (0);
1531 layout = &SDDS_dataset->layout;
1532 if (!layout->n_parameters)
1533 return (1);
1534 for (i = 0; i < layout->n_parameters; i++) {
1535 if (layout->parameter_definition[i].definition_mode & SDDS_WRITEONLY_DEFINITION)
1536 continue;
1537 if (layout->parameter_definition[i].fixed_value) {
1538 strcpy(buffer, layout->parameter_definition[i].fixed_value);
1539 if (!SDDS_ScanData(buffer, layout->parameter_definition[i].type, 0, SDDS_dataset->parameter[i], 0, 1)) {
1540 SDDS_SetError("Unable to read page--parameter scanning error (SDDS_MPI_ReadBinaryParameters)");
1541 return (0);
1542 }
1543 } else if (layout->parameter_definition[i].type == SDDS_STRING) {
1544 if (*(char **)SDDS_dataset->parameter[i])
1545 free(*(char **)SDDS_dataset->parameter[i]);
1546 if (!(*((char **)SDDS_dataset->parameter[i]) = SDDS_MPI_ReadBinaryString(SDDS_dataset, fBuffer, 0))) {
1547 SDDS_SetError("Unable to read parameters--failure reading string (SDDS_MPI_ReadBinaryParameters)");
1548 return (0);
1549 }
1550 } else {
1551 if (!SDDS_MPI_BufferedRead(SDDS_dataset->parameter[i], SDDS_type_size[layout->parameter_definition[i].type - 1], SDDS_dataset, fBuffer)) {
1552 SDDS_SetError("Unable to read parameters--failure reading value (SDDS_MPI_ReadBinaryParameters)");
1553 return (0);
1554 }
1555 }
1556 }
1557 return (1);
1558}
int32_t SDDS_ScanData(char *string, int32_t type, int32_t field_length, void *data, int64_t index, int32_t is_parameter)
Scans a string and saves the parsed value into a data pointer according to the specified data type.

◆ SDDS_MPI_ReadBinaryRow()

int32_t SDDS_MPI_ReadBinaryRow ( SDDS_DATASET * SDDS_dataset,
int64_t row,
int32_t skip )

Read a binary row from the SDDS dataset using MPI.

This function reads a specific row of data from the SDDS dataset in binary format using MPI. It handles different column types, including strings and fixed-size data types. If the skip parameter is set, string data is read and discarded.

Parameters
SDDS_datasetPointer to the SDDS_DATASET structure.
rowThe row index to read.
skipIf non-zero, string data in the row is read but not stored.
Returns
  • 1 on successful read of the row.
  • 0 on failure to read any part of the row.

Definition at line 1574 of file SDDS_MPI_binary.c.

1574 {
1575 int64_t i;
1576 int32_t type, size;
1577 SDDS_LAYOUT *layout;
1578 SDDS_FILEBUFFER *fBuffer;
1579
1580 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_MPI_ReadBinaryRow"))
1581 return (0);
1582 layout = &SDDS_dataset->layout;
1583 fBuffer = &SDDS_dataset->fBuffer;
1584
1585 for (i = 0; i < layout->n_columns; i++) {
1586 if (layout->column_definition[i].definition_mode & SDDS_WRITEONLY_DEFINITION)
1587 continue;
1588 if ((type = layout->column_definition[i].type) == SDDS_STRING) {
1589 if (!skip) {
1590 if (((char ***)SDDS_dataset->data)[i][row])
1591 free((((char ***)SDDS_dataset->data)[i][row]));
1592 if (!(((char ***)SDDS_dataset->data)[i][row] = SDDS_MPI_ReadBinaryString(SDDS_dataset, fBuffer, 0))) {
1593 SDDS_SetError("Unable to read rows--failure reading string (SDDS_MPI_ReadBinaryRows)");
1594 return (0);
1595 }
1596 } else {
1597 if (!(((char ***)SDDS_dataset->data)[i][row] = SDDS_MPI_ReadBinaryString(SDDS_dataset, fBuffer, 1))) {
1598 SDDS_SetError("Unable to read rows--failure reading string (SDDS_MPI_ReadBinaryRows)");
1599 return 0;
1600 }
1601 }
1602 } else {
1603 size = SDDS_type_size[type - 1];
1604 if (!SDDS_MPI_BufferedRead(skip ? NULL : (char *)SDDS_dataset->data[i] + row * size, size, SDDS_dataset, fBuffer)) {
1605 SDDS_SetError("Unable to read row--failure reading value (SDDS_MPI_ReadBinaryRow)");
1606 return (0);
1607 }
1608 }
1609 }
1610 return (1);
1611}

◆ SDDS_MPI_ReadBinaryString()

char * SDDS_MPI_ReadBinaryString ( SDDS_DATASET * SDDS_dataset,
SDDS_FILEBUFFER * fBuffer,
int32_t skip )

Read a binary string from the SDDS dataset using MPI.

This function reads a string from the SDDS dataset in binary format using MPI. It first reads the length of the string, allocates memory for the string, and then reads the string data itself. If the skip parameter is set, the string data is read and discarded.

Parameters
SDDS_datasetPointer to the SDDS_DATASET structure.
fBufferPointer to the SDDS_FILEBUFFER structure managing the buffer.
skipIf non-zero, the string data is read and skipped (not stored).
Returns
  • Pointer to the allocated string on success.
  • 0 if reading the length fails or if the length is negative.
  • NULL if memory allocation fails or reading the string data fails.

Definition at line 1464 of file SDDS_MPI_binary.c.

1464 {
1465 int32_t length;
1466 char *string;
1467 if (!SDDS_MPI_BufferedRead(&length, sizeof(length), SDDS_dataset, fBuffer) || length < 0)
1468 return (0);
1469 if (!(string = SDDS_Malloc(sizeof(*string) * (length + 1))))
1470 return (NULL);
1471 if (length && !SDDS_MPI_BufferedRead(skip ? NULL : string, sizeof(*string) * length, SDDS_dataset, fBuffer))
1472 return (NULL);
1473 string[length] = 0;
1474 return (string);
1475}

◆ SDDS_MPI_ReadNonNativeBinaryArrays()

int32_t SDDS_MPI_ReadNonNativeBinaryArrays ( SDDS_DATASET * SDDS_dataset,
SDDS_FILEBUFFER * fBuffer )

Reads non-native binary arrays from a binary file buffer into the SDDS dataset using MPI.

This function validates the provided SDDS dataset and reads array definitions and data from a non-native binary file buffer. It handles byte swapping for endianness, allocates memory for array dimensions and data, and processes string arrays individually.

Parameters
[in,out]SDDS_datasetPointer to the SDDS_DATASET structure where the arrays will be stored.
[in]fBufferPointer to the SDDS_FILEBUFFER structure containing the binary data to be read.
Returns
int32_t Returns 1 on successful read, 0 on failure.

Definition at line 1757 of file SDDS_MPI_binary.c.

1757 {
1758 int32_t i, j;
1759 SDDS_LAYOUT *layout;
1760 SDDS_ARRAY *array;
1761
1762 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_MPI_ReadNonNativeBinaryArrays"))
1763 return (0);
1764 layout = &SDDS_dataset->layout;
1765 if (!layout->n_arrays)
1766 return (1);
1767
1768 if (!SDDS_dataset->array) {
1769 SDDS_SetError("Unable to read array--pointer to structure storage area is NULL (SDDS_MPI_ReadNonNativeBinaryArrays)");
1770 return (0);
1771 }
1772 for (i = 0; i < layout->n_arrays; i++) {
1773 array = SDDS_dataset->array + i;
1774 if (array->definition && !SDDS_FreeArrayDefinition(array->definition)) {
1775 SDDS_SetError("Unable to get array--array definition corrupted (SDDS_MPI_ReadNonNativeBinaryArrays)");
1776 return (0);
1777 }
1778 if (!SDDS_CopyArrayDefinition(&array->definition, layout->array_definition + i)) {
1779 SDDS_SetError("Unable to read array--definition copy failed (SDDS_MPI_ReadNonNativeBinaryArrays)");
1780 return (0);
1781 }
1782 /*if (array->dimension) free(array->dimension); */
1783 if (!(array->dimension = SDDS_Realloc(array->dimension, sizeof(*array->dimension) * array->definition->dimensions))) {
1784 SDDS_SetError("Unable to read array--allocation failure (SDDS_MPI_ReadNonNativeBinaryArrays)");
1785 return (0);
1786 }
1787 if (!SDDS_MPI_BufferedRead(array->dimension, sizeof(*array->dimension) * array->definition->dimensions, SDDS_dataset, fBuffer)) {
1788 SDDS_SetError("Unable to read arrays--failure reading dimensions (SDDS_MPI_ReadNonNativeBinaryArrays)");
1789 return (0);
1790 }
1791 SDDS_SwapLong(array->dimension);
1792 array->elements = 1;
1793 for (j = 0; j < array->definition->dimensions; j++)
1794 array->elements *= array->dimension[j];
1795 if (array->data)
1796 free(array->data);
1797 array->data = array->pointer = NULL;
1798 if (array->elements == 0)
1799 continue;
1800 if (array->elements < 0) {
1801 SDDS_SetError("Unable to read array--number of elements is negative (SDDS_MPI_ReadNonNativeBinaryArrays)");
1802 return (0);
1803 }
1804 if (!(array->data = SDDS_Realloc(array->data, array->elements * SDDS_type_size[array->definition->type - 1]))) {
1805 SDDS_SetError("Unable to read array--allocation failure (SDDS_MPI_ReadNonNativeBinaryArrays)");
1806 return (0);
1807 }
1808 if (array->definition->type == SDDS_STRING) {
1809 for (j = 0; j < array->elements; j++) {
1810 if (!(((char **)(array->data))[j] = SDDS_MPI_ReadNonNativeBinaryString(SDDS_dataset, fBuffer, 0))) {
1811 SDDS_SetError("Unable to read arrays--failure reading string (SDDS_MPI_ReadNonNativeBinaryArrays)");
1812 return (0);
1813 }
1814 }
1815 } else {
1816 if (!SDDS_MPI_BufferedRead(array->data, SDDS_type_size[array->definition->type - 1] * array->elements, SDDS_dataset, fBuffer)) {
1817 SDDS_SetError("Unable to read arrays--failure reading values (SDDS_MPI_ReadNonNativeBinaryArrays)");
1818 return (0);
1819 }
1820 }
1821 }
1822 SDDS_SwapEndsArrayData(SDDS_dataset);
1823 return (1);
1824}
char * SDDS_MPI_ReadNonNativeBinaryString(SDDS_DATASET *SDDS_dataset, SDDS_FILEBUFFER *fBuffer, int32_t skip)
Read a non-native binary string from the SDDS dataset using MPI.
int32_t SDDS_SwapEndsArrayData(SDDS_DATASET *SDDSin)
Swaps the endianness of the array data in an SDDS dataset.

◆ SDDS_MPI_ReadNonNativeBinaryPage()

int32_t SDDS_MPI_ReadNonNativeBinaryPage ( SDDS_DATASET * SDDS_dataset)

Reads a non-native binary page from an SDDS dataset using MPI parallel I/O.

This function reads a page of data from a non-native binary SDDS file in parallel using MPI. It manages reading the title data, distributing the rows among MPI processes, and reading the column or row data depending on the dataset's data mode. It also handles byte swapping for endianness and error management.

Parameters
[in,out]SDDS_datasetPointer to the SDDS_DATASET structure where the page data will be stored.
Returns
int32_t Returns the page number on success, 0 on failure, or -1 if end-of-file is reached.

Definition at line 2218 of file SDDS_MPI_binary.c.

2218 {
2219 int32_t ID_offset, mpi_code, master_read, type, retval;
2220 int64_t i, j, n_rows, total_rows, prev_rows;
2221 SDDS_FILEBUFFER *fBuffer;
2222 MPI_DATASET *MPI_dataset;
2223 MPI_Offset offset;
2224 MPI_Status status;
2225
2226 MPI_dataset = SDDS_dataset->MPI_dataset;
2227 master_read = MPI_dataset->master_read;
2228 /* static char s[SDDS_MAXLINE]; */
2229 n_rows = 0;
2230 SDDS_SetReadRecoveryMode(SDDS_dataset, 0);
2231 if (MPI_dataset->file_offset >= MPI_dataset->file_size)
2232 return (SDDS_dataset->page_number = -1);
2233
2234 if ((mpi_code = MPI_File_set_view(MPI_dataset->MPI_file, MPI_dataset->file_offset, MPI_BYTE, MPI_BYTE, "native", MPI_INFO_NULL)) != MPI_SUCCESS) {
2235 SDDS_MPI_GOTO_ERROR(stderr, "Unable to set view for read binary page", mpi_code, 0);
2236 SDDS_SetError("Unable to set view for read binary page(1)");
2237 return 0;
2238 }
2239 /* read the number of rows in current page */
2240#if defined(MASTER_READTITLE_ONLY)
2241 if (MPI_dataset->myid == 0)
2242#endif
2243 retval = SDDS_MPI_BufferedReadNonNativeBinaryTitle(SDDS_dataset);
2244#if defined(MASTER_READTITLE_ONLY)
2245 MPI_Bcast(&retval, 1, MPI_INT, 0, MPI_dataset->comm);
2246#endif
2247 /*end of file reached */
2248 if (retval < 0)
2249 return (SDDS_dataset->page_number = -1);
2250 if (retval == 0) {
2251 SDDS_SetError("Unable to read the SDDS title (row number, parameter and/or array) data");
2252 return 0;
2253 }
2254#if defined(MASTER_READTITLE_ONLY)
2255 SDDS_MPI_BroadcastTitleData(SDDS_dataset);
2256#endif
2257 MPI_dataset->file_offset += SDDS_MPI_GetTitleOffset(SDDS_dataset);
2258 if (MPI_dataset->total_rows < 0) {
2259 SDDS_SetError("Unable to read page--negative number of rows (SDDS_MPI_ReadBinaryPage)");
2260 return (0);
2261 }
2262 if (MPI_dataset->total_rows > SDDS_GetRowLimit()) {
2263 /* the number of rows is "unreasonably" large---treat like end-of-file */
2264 return (SDDS_dataset->page_number = -1);
2265 }
2266 total_rows = MPI_dataset->total_rows;
2267 prev_rows = 0;
2268 if (master_read) {
2269 n_rows = total_rows / MPI_dataset->n_processors;
2270 prev_rows = MPI_dataset->myid * n_rows;
2271 if (MPI_dataset->myid < (ID_offset = total_rows % (MPI_dataset->n_processors))) {
2272 n_rows++;
2273 prev_rows += MPI_dataset->myid;
2274 } else
2275 prev_rows += ID_offset;
2276 } else {
2277 if (MPI_dataset->myid == 0)
2278 n_rows = 0;
2279 else {
2280 n_rows = total_rows / (MPI_dataset->n_processors - 1);
2281 prev_rows = (MPI_dataset->myid - 1) * n_rows;
2282 if (MPI_dataset->myid <= (ID_offset = total_rows % (MPI_dataset->n_processors - 1))) {
2283 n_rows++;
2284 prev_rows += (MPI_dataset->myid - 1);
2285 } else
2286 prev_rows += ID_offset;
2287 }
2288 }
2289 MPI_dataset->start_row = prev_rows; /* This number will be used as the paritlce ID offset */
2290 if (!SDDS_StartPage(SDDS_dataset, 0) || !SDDS_LengthenTable(SDDS_dataset, n_rows)) {
2291 SDDS_SetError("Unable to read page--couldn't start page (SDDS_MPI_ReadNonNativeBinaryPage)");
2292 return (0);
2293 }
2294
2295 offset = MPI_dataset->file_offset;
2296 fBuffer = &SDDS_dataset->fBuffer;
2297 if (SDDS_dataset->layout.data_mode.column_major) {
2298 /*read by column buffer is not need */
2299 for (i = 0; i < SDDS_dataset->layout.n_columns; i++) {
2300 type = SDDS_dataset->layout.column_definition[i].type;
2301 if (type == SDDS_STRING) {
2302 SDDS_SetError("Can not read string column from SDDS3 (SDDS_MPI_ReadBinaryPage");
2303 return 0;
2304 }
2305 MPI_dataset->file_offset = offset + (MPI_Offset)prev_rows * SDDS_type_size[type - 1];
2306 if ((mpi_code = MPI_File_set_view(MPI_dataset->MPI_file, MPI_dataset->file_offset, MPI_BYTE, MPI_BYTE, "native", MPI_INFO_NULL)) != MPI_SUCCESS) {
2307 SDDS_SetError("Unable to set view for read binary columns");
2308 return 0;
2309 }
2310 if (!MPI_dataset->collective_io) {
2311 if ((mpi_code = MPI_File_read(MPI_dataset->MPI_file, (char *)SDDS_dataset->data[i], n_rows * SDDS_type_size[type - 1], MPI_BYTE, &status)) != MPI_SUCCESS) {
2312 SDDS_SetError("Unable to set view for read binary columns");
2313 return 0;
2314 }
2315 } else {
2316 if ((mpi_code = MPI_File_read_all(MPI_dataset->MPI_file, (char *)SDDS_dataset->data[i], n_rows * SDDS_type_size[type - 1], MPI_BYTE, &status)) != MPI_SUCCESS) {
2317 SDDS_SetError("Unable to set view for read binary columns");
2318 return 0;
2319 }
2320 }
2321 offset += (MPI_Offset)MPI_dataset->total_rows * SDDS_type_size[type - 1];
2322 }
2323 MPI_dataset->n_rows = SDDS_dataset->n_rows = n_rows;
2324 MPI_dataset->file_offset = offset;
2325 } else {
2326 /* read row by row */
2327 if (!fBuffer->buffer) {
2328 fBuffer->bufferSize = SDDS_GetLockedDefaultReadBufferSize();
2329 if (!(fBuffer->buffer = fBuffer->data = SDDS_Malloc(sizeof(char) * (fBuffer->bufferSize + 1)))) {
2330 SDDS_SetError("Unable to do buffered read--allocation failure");
2331 return 0;
2332 }
2333 fBuffer->bytesLeft = 0;
2334 fBuffer->data[0] = 0;
2335 }
2336 if (fBuffer->bytesLeft > 0) {
2337 /* discard the extra data for reading next page */
2338 fBuffer->data[0] = 0;
2339 fBuffer->bytesLeft = 0;
2340 }
2341 MPI_dataset->file_offset += (MPI_Offset)prev_rows * MPI_dataset->column_offset;
2342 if ((mpi_code = MPI_File_set_view(MPI_dataset->MPI_file, MPI_dataset->file_offset, MPI_BYTE, MPI_BYTE, "native", MPI_INFO_NULL)) != MPI_SUCCESS) {
2343 SDDS_MPI_GOTO_ERROR(stderr, "Unable to set view for read binary rows", mpi_code, 0);
2344 SDDS_SetError("Unable to set view for read binary rows");
2345 return 0;
2346 }
2347 if (!MPI_dataset->collective_io || !master_read) {
2348 for (j = 0; j < n_rows; j++) {
2349 if (!SDDS_MPI_ReadBinaryRow(SDDS_dataset, j, 0)) {
2350 SDDS_dataset->n_rows = j - 1;
2351 if (SDDS_dataset->autoRecover) {
2353 SDDS_SwapEndsColumnData(SDDS_dataset);
2354 return (SDDS_dataset->page_number = MPI_dataset->n_page);
2355 }
2356 SDDS_SetError("Unable to read page--error reading data row (SDDS_MPI_ReadNonNativeBinaryPage)");
2357 SDDS_SetReadRecoveryMode(SDDS_dataset, 1);
2358 return (0);
2359 }
2360 }
2361 SDDS_dataset->n_rows = j;
2362 } else {
2363 MPI_dataset->n_rows = SDDS_dataset->n_rows = n_rows;
2364 if (!SDDS_MPI_CollectiveReadByRow(SDDS_dataset))
2365 return 0;
2366 }
2367 MPI_dataset->file_offset = offset + MPI_dataset->total_rows * MPI_dataset->column_offset;
2368 }
2369 SDDS_SwapEndsColumnData(SDDS_dataset);
2370 MPI_dataset->n_page++;
2371 MPI_Barrier(MPI_dataset->comm);
2372 return (SDDS_dataset->page_number = MPI_dataset->n_page);
2373}
int32_t SDDS_MPI_BufferedReadNonNativeBinaryTitle(SDDS_DATASET *SDDS_dataset)
Buffers and reads the non-native binary title data from an SDDS dataset using MPI.
int32_t SDDS_SwapEndsColumnData(SDDS_DATASET *SDDSin)
Swaps the endianness of the column data in an SDDS dataset.

◆ SDDS_MPI_ReadNonNativeBinaryParameters()

int32_t SDDS_MPI_ReadNonNativeBinaryParameters ( SDDS_DATASET * SDDS_dataset,
SDDS_FILEBUFFER * fBuffer )

Read non-native binary parameters from the SDDS dataset using MPI.

This function reads all non-fixed parameters from the SDDS dataset in non-native binary format using MPI. It handles byte swapping for parameter data to match the non-native byte order. String parameters are read as non-native binary strings, and other types are read directly into the dataset's parameter storage.

Parameters
SDDS_datasetPointer to the SDDS_DATASET structure.
fBufferPointer to the SDDS_FILEBUFFER structure managing the buffer.
Returns
  • 1 on successful read of all parameters.
  • 0 on failure to read any parameter.

Definition at line 1709 of file SDDS_MPI_binary.c.

1709 {
1710 int32_t i;
1711 SDDS_LAYOUT *layout;
1712 char buffer[SDDS_MAXLINE];
1713
1714 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_MPI_ReadNonNativeBinaryParameters"))
1715 return (0);
1716 layout = &SDDS_dataset->layout;
1717 if (!layout->n_parameters)
1718 return (1);
1719 for (i = 0; i < layout->n_parameters; i++) {
1720 if (layout->parameter_definition[i].definition_mode & SDDS_WRITEONLY_DEFINITION)
1721 continue;
1722 if (layout->parameter_definition[i].fixed_value) {
1723 strcpy(buffer, layout->parameter_definition[i].fixed_value);
1724 if (!SDDS_ScanData(buffer, layout->parameter_definition[i].type, 0, SDDS_dataset->parameter[i], 0, 1)) {
1725 SDDS_SetError("Unable to read page--parameter scanning error (SDDS_MPI_ReadNonNativeBinaryParameters)");
1726 return (0);
1727 }
1728 } else if (layout->parameter_definition[i].type == SDDS_STRING) {
1729 if (*(char **)SDDS_dataset->parameter[i])
1730 free(*(char **)SDDS_dataset->parameter[i]);
1731 if (!(*((char **)SDDS_dataset->parameter[i]) = SDDS_MPI_ReadNonNativeBinaryString(SDDS_dataset, fBuffer, 0))) {
1732 SDDS_SetError("Unable to read parameters--failure reading string (SDDS_MPI_ReadNonNativeBinaryParameters)");
1733 return (0);
1734 }
1735 } else {
1736 if (!SDDS_MPI_BufferedRead(SDDS_dataset->parameter[i], SDDS_type_size[layout->parameter_definition[i].type - 1], SDDS_dataset, fBuffer)) {
1737 SDDS_SetError("Unable to read parameters--failure reading value (SDDS_MPI_ReadNonNativeBinaryParameters)");
1738 return (0);
1739 }
1740 }
1741 }
1742 SDDS_SwapEndsParameterData(SDDS_dataset);
1743 return (1);
1744}
int32_t SDDS_SwapEndsParameterData(SDDS_DATASET *SDDSin)
Swaps the endianness of the parameter data in an SDDS dataset.

◆ SDDS_MPI_ReadNonNativeBinaryRow()

int32_t SDDS_MPI_ReadNonNativeBinaryRow ( SDDS_DATASET * SDDS_dataset,
int64_t row,
int32_t skip )

Reads a single non-native binary row from a binary file buffer into the SDDS dataset using MPI.

This function reads the data for a specific row from the binary file buffer. It handles different data types, including strings, and can optionally skip reading the row data. If skipping, it advances the file buffer without storing the data.

Parameters
[in,out]SDDS_datasetPointer to the SDDS_DATASET structure where the row data will be stored.
[in]rowThe index of the row to read.
[in]skipIf non-zero, the function will skip reading the row data without storing it.
Returns
int32_t Returns 1 on successful read, 0 on failure.

Definition at line 1838 of file SDDS_MPI_binary.c.

1838 {
1839 int64_t i;
1840 int32_t type, size;
1841 SDDS_LAYOUT *layout;
1842 SDDS_FILEBUFFER *fBuffer;
1843
1844 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_MPI_ReadNonNativeBinaryRow"))
1845 return (0);
1846 layout = &SDDS_dataset->layout;
1847 fBuffer = &SDDS_dataset->fBuffer;
1848
1849 for (i = 0; i < layout->n_columns; i++) {
1850 if (layout->column_definition[i].definition_mode & SDDS_WRITEONLY_DEFINITION)
1851 continue;
1852 if ((type = layout->column_definition[i].type) == SDDS_STRING) {
1853 if (!skip) {
1854 if (((char ***)SDDS_dataset->data)[i][row])
1855 free((((char ***)SDDS_dataset->data)[i][row]));
1856 if (!(((char ***)SDDS_dataset->data)[i][row] = SDDS_MPI_ReadNonNativeBinaryString(SDDS_dataset, fBuffer, 0))) {
1857 SDDS_SetError("Unable to read rows--failure reading string (SDDS_MPI_ReadNonNativeBinaryRow)");
1858 return (0);
1859 }
1860 } else {
1861 if (!SDDS_MPI_ReadNonNativeBinaryString(SDDS_dataset, fBuffer, 1)) {
1862 SDDS_SetError("Unable to read rows--failure reading string (SDDS_MPI_ReadNonNativeBinaryRow)");
1863 return 0;
1864 }
1865 }
1866 } else {
1867 size = SDDS_type_size[type - 1];
1868 if (!SDDS_MPI_BufferedRead(skip ? NULL : (char *)SDDS_dataset->data[i] + row * size, size, SDDS_dataset, fBuffer)) {
1869 SDDS_SetError("Unable to read row--failure reading value (SDDS_MPI_ReadNonNativeBinaryRow)");
1870 return (0);
1871 }
1872 }
1873 }
1874 return (1);
1875}

◆ SDDS_MPI_ReadNonNativeBinaryString()

char * SDDS_MPI_ReadNonNativeBinaryString ( SDDS_DATASET * SDDS_dataset,
SDDS_FILEBUFFER * fBuffer,
int32_t skip )

Read a non-native binary string from the SDDS dataset using MPI.

This function reads a string from the SDDS dataset in non-native binary format using MPI. It handles byte swapping for the string length to match the non-native byte order. After reading the length, it allocates memory for the string and reads the string data. If the skip parameter is set, the string data is read and discarded.

Parameters
SDDS_datasetPointer to the SDDS_DATASET structure.
fBufferPointer to the SDDS_FILEBUFFER structure managing the buffer.
skipIf non-zero, the string data is read and skipped (not stored).
Returns
  • Pointer to the allocated string on success.
  • 0 if reading the length fails or if the length is negative.
  • NULL if memory allocation fails or reading the string data fails.

Definition at line 1493 of file SDDS_MPI_binary.c.

1493 {
1494 int32_t length;
1495 char *string;
1496
1497 if (!SDDS_MPI_BufferedRead(&length, sizeof(length), SDDS_dataset, fBuffer))
1498 return (0);
1499 SDDS_SwapLong(&length);
1500 if (length < 0)
1501 return (0);
1502 if (!(string = SDDS_Malloc(sizeof(*string) * (length + 1))))
1503 return (NULL);
1504 if (length && !SDDS_MPI_BufferedRead(skip ? NULL : string, sizeof(*string) * length, SDDS_dataset, fBuffer))
1505 return (NULL);
1506 string[length] = 0;
1507 return (string);
1508}

◆ SDDS_MPI_ReadNonNativePage()

int32_t SDDS_MPI_ReadNonNativePage ( SDDS_DATASET * SDDS_dataset)

Reads a non-native binary page from an SDDS dataset using MPI parallel I/O.

This function is a wrapper that calls SDDS_MPI_ReadNonNativePageSparse with mode set to 0, facilitating the reading of non-native binary pages.

Parameters
[in,out]SDDS_datasetPointer to the SDDS_DATASET structure where the page data will be stored.
Returns
int32_t Returns the page number on success, 0 on failure, or -1 if end-of-file is reached.

Definition at line 2166 of file SDDS_MPI_binary.c.

2166 {
2167 return SDDS_MPI_ReadNonNativePageSparse(SDDS_dataset, 0);
2168}
int32_t SDDS_MPI_ReadNonNativePageSparse(SDDS_DATASET *SDDS_dataset, uint32_t mode)
Reads a sparse non-native binary page from an SDDS dataset using MPI parallel I/O.

◆ SDDS_MPI_ReadNonNativePageSparse()

int32_t SDDS_MPI_ReadNonNativePageSparse ( SDDS_DATASET * SDDS_dataset,
uint32_t mode )

Reads a sparse non-native binary page from an SDDS dataset using MPI parallel I/O.

This function reads a page of data from a non-native binary SDDS file in parallel using MPI. The mode parameter allows for future expansion. It handles reading the title data, broadcasting it to all MPI processes, and reading the column or row data based on the dataset's data mode.

Parameters
[in,out]SDDS_datasetPointer to the SDDS_DATASET structure where the page data will be stored.
[in]modeMode flag to support future expansion (currently unused).
Returns
int32_t Returns the page number on success, 0 on failure, or -1 if end-of-file is reached.

Definition at line 2181 of file SDDS_MPI_binary.c.

2183{
2184 int32_t retval;
2185
2186 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_MPI_ReadNonNativePageSparse"))
2187 return (0);
2188 if (SDDS_dataset->layout.disconnected) {
2189 SDDS_SetError("Can't read page--file is disconnected (SDDS_MPI_ReadNonNativePageSparse)");
2190 return 0;
2191 }
2192
2193 if (SDDS_dataset->original_layout.data_mode.mode == SDDS_ASCII) {
2194 SDDS_SetError("Can not read assii file with parallel io.");
2195 return 0;
2196 } else if (SDDS_dataset->original_layout.data_mode.mode == SDDS_BINARY) {
2197 if ((retval = SDDS_MPI_ReadNonNativeBinaryPage(SDDS_dataset)) < 1) {
2198 return (retval);
2199 }
2200 } else {
2201 SDDS_SetError("Unable to read page--unrecognized data mode (SDDS_MPI_ReadNonNativePageSparse)");
2202 return (0);
2203 }
2204 return (retval);
2205}

◆ SDDS_MPI_SetFileSync()

void SDDS_MPI_SetFileSync ( short value)

Set the file synchronization flag.

This function enables or disables forced file synchronization after writing binary rows. This can help prevent data corruption by ensuring data is flushed to the file system.

Parameters
valueA short integer where non-zero enables file synchronization, and zero disables it.

Definition at line 514 of file SDDS_MPI_binary.c.

514 {
515 mdb_thread_lock(&SDDS_MPI_force_file_sync_lock);
516 SDDS_MPI_force_file_sync = value;
517 mdb_thread_unlock(&SDDS_MPI_force_file_sync_lock);
518}

◆ SDDS_MPI_SetWriteKludgeUsleep()

void SDDS_MPI_SetWriteKludgeUsleep ( long value)

Set the write kludge usleep duration.

This function sets the duration (in microseconds) for the write kludge sleep operation. This is used to fix write issues in certain test cases by introducing a delay after writing a binary row.

Parameters
valueThe number of microseconds to sleep after writing a row.

Definition at line 498 of file SDDS_MPI_binary.c.

498 {
499 mdb_thread_lock(&SDDS_MPI_write_kludge_usleep_lock);
500 SDDS_MPI_write_kludge_usleep = value;
501 mdb_thread_unlock(&SDDS_MPI_write_kludge_usleep_lock);
502}

◆ SDDS_MPI_WriteBinaryArrays()

int32_t SDDS_MPI_WriteBinaryArrays ( SDDS_DATASET * SDDS_dataset)

Write binary arrays of an SDDS dataset using MPI.

This function writes all arrays of the SDDS dataset in binary format using MPI. It handles different types of arrays, including strings and fixed-size data types.

Only the master processor should call this function to write SDDS headers, parameters, and arrays.

Parameters
SDDS_datasetPointer to the SDDS_DATASET structure.
Returns
1 on success, 0 on failure.

Definition at line 387 of file SDDS_MPI_binary.c.

387 {
388 int32_t i, j, zero = 0, writeSize = 0;
389 SDDS_LAYOUT *layout;
390
391 /*only the master processor write SDDS header, parameters and arrays */
392 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_MPI_WriteBinaryArray"))
393 return (0);
394 layout = &SDDS_dataset->layout;
395 for (i = 0; i < layout->n_arrays; i++) {
396 if (!SDDS_dataset->array[i].dimension) {
397 for (j = 0; j < layout->array_definition[i].dimensions; j++) {
398 if (!SDDS_MPI_BufferedWrite(&zero, sizeof(zero), SDDS_dataset)) {
399 SDDS_SetError("Unable to write null array--failure writing dimensions (SDDS_MPI_WriteBinaryArrays)");
400 return 0;
401 }
402 }
403 continue;
404 }
405 writeSize = sizeof(*(SDDS_dataset->array)[i].dimension) * layout->array_definition[i].dimensions;
406 if (!SDDS_MPI_BufferedWrite(SDDS_dataset->array[i].dimension, writeSize, SDDS_dataset)) {
407 SDDS_SetError("Unable to write arrays--failure writing dimensions (SDDS_MPI_WriteBinaryArrays)");
408 return (0);
409 }
410 if (layout->array_definition[i].type == SDDS_STRING) {
411 for (j = 0; j < SDDS_dataset->array[i].elements; j++) {
412 if (!SDDS_MPI_WriteBinaryString(SDDS_dataset, ((char **)SDDS_dataset->array[i].data)[j])) {
413 SDDS_SetError("Unable to write arrays--failure writing string (SDDS_WriteBinaryArrays)");
414 return (0);
415 }
416 }
417 } else {
418 writeSize = SDDS_type_size[layout->array_definition[i].type - 1] * SDDS_dataset->array[i].elements;
419 if (!SDDS_MPI_BufferedWrite(SDDS_dataset->array[i].data, writeSize, SDDS_dataset)) {
420 SDDS_SetError("Unable to write arrays--failure writing values (SDDS_MPI_WriteBinaryArrays)");
421 return (0);
422 }
423 }
424 }
425 return (1);
426}
int32_t SDDS_MPI_WriteBinaryString(SDDS_DATASET *SDDS_dataset, char *string)
Write a binary string to an SDDS dataset using MPI.
int32_t SDDS_MPI_BufferedWrite(void *target, int64_t targetSize, SDDS_DATASET *SDDS_dataset)
Buffered write to an SDDS dataset using MPI.

◆ SDDS_MPI_WriteBinaryPage()

int32_t SDDS_MPI_WriteBinaryPage ( SDDS_DATASET * SDDS_dataset)

Write an SDDS binary page using MPI.

This function writes an SDDS dataset as a binary page using MPI. If MPI_DEBUG is enabled, it logs debugging information.

Parameters
SDDS_datasetPointer to the SDDS_DATASET structure to write.
Returns
1 on success, 0 on failure.

Definition at line 223 of file SDDS_MPI_binary.c.

223 {
224#if MPI_DEBUG
225 logDebug("SDDS_MPI_WriteBinaryPage", SDDS_dataset);
226#endif
227 /* usleep(1000000); Doesn't solve problem of corrupted data */
228 return SDDS_MPI_WriteContinuousBinaryPage(SDDS_dataset);
229}
int32_t SDDS_MPI_WriteContinuousBinaryPage(SDDS_DATASET *SDDS_dataset)
Write a continuous binary page of the SDDS dataset using MPI.

◆ SDDS_MPI_WriteBinaryParameters()

int32_t SDDS_MPI_WriteBinaryParameters ( SDDS_DATASET * SDDS_dataset)

Write binary parameters of an SDDS dataset using MPI.

This function writes all non-fixed parameters of the SDDS dataset in binary format using MPI. String parameters are written using SDDS_MPI_WriteBinaryString, and other types are written directly to the buffer.

Only the master processor should call this function to write SDDS headers, parameters, and arrays.

Parameters
SDDS_datasetPointer to the SDDS_DATASET structure.
Returns
1 on success, 0 on failure.

Definition at line 303 of file SDDS_MPI_binary.c.

303 {
304 SDDS_LAYOUT *layout;
305 int32_t i;
306
307#if MPI_DEBUG
308 logDebug("SDDS_MPI_WriteBinaryParameters", SDDS_dataset);
309#endif
310
311 /*should only master processors write SDDS hearder,parameters and arrays */
312 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_MPI_WriteBinaryParameters"))
313 return (0);
314 layout = &SDDS_dataset->layout;
315 for (i = 0; i < layout->n_parameters; i++) {
316 if (layout->parameter_definition[i].fixed_value)
317 continue;
318 if (layout->parameter_definition[i].type == SDDS_STRING) {
319 if (!SDDS_MPI_WriteBinaryString(SDDS_dataset, *(char **)SDDS_dataset->parameter[i]))
320 return 0;
321 } else {
322 if (!SDDS_MPI_BufferedWrite(SDDS_dataset->parameter[i], SDDS_type_size[layout->parameter_definition[i].type - 1], SDDS_dataset))
323 return 0;
324 }
325 }
326 return (1);
327}

◆ SDDS_MPI_WriteBinaryRow()

int32_t SDDS_MPI_WriteBinaryRow ( SDDS_DATASET * SDDS_dataset,
int64_t row )

Write a binary row to an SDDS dataset using MPI.

This function writes a specific row of data from the SDDS dataset in binary format using MPI. It handles different column types, including strings with truncation based on the default string length. Optional write kludge delays and file synchronization can be applied based on configuration.

Parameters
SDDS_datasetPointer to the SDDS_DATASET structure.
rowThe row index to write.
Returns
1 on success, 0 on failure.

Definition at line 532 of file SDDS_MPI_binary.c.

532 {
533 int32_t size, type;
534 int64_t i;
535 SDDS_LAYOUT *layout;
536 /*char buff[defaultStringLength+1], format[256]; */
537 char *buff;
538 char format[256];
539 int32_t currentDefaultStringLength;
540 long writeKludgeUsleep;
541
542#if MPI_DEBUG
543 logDebug("SDDS_MPI_WriteBinaryRow", SDDS_dataset);
544#endif
545
546 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_WriteBinaryRow"))
547 return (0);
548
549 layout = &SDDS_dataset->layout;
550 currentDefaultStringLength = SDDS_GetLockedDefaultStringLength();
551
552 if (currentDefaultStringLength < 0 || currentDefaultStringLength >= INT32_MAX) {
553 SDDS_SetError("Default string length is too large in SDDS_MPI_WriteBinaryRow!");
554 return 0;
555 }
556 if (snprintf(format, sizeof(format), "%%-%" PRId32 "s", currentDefaultStringLength) >= (int)sizeof(format)) {
557 SDDS_SetError("Default string length is too large in SDDS_MPI_WriteBinaryRow!");
558 return 0;
559 }
560 if (!(buff = malloc(sizeof(*buff) * ((size_t)currentDefaultStringLength + 1)))) {
561 SDDS_SetError("Can not allocate memory in SDDS_MPI_WriteBinaryRow!");
562 return 0;
563 }
564 buff[currentDefaultStringLength] = 0;
565 for (i = 0; i < layout->n_columns; i++) {
566 type = layout->column_definition[i].type;
567 size = SDDS_type_size[type - 1];
568
569 if (type == SDDS_STRING) {
570 if (strlen(*((char **)SDDS_dataset->data[i] + row)) <= currentDefaultStringLength)
571 sprintf(buff, format, *((char **)SDDS_dataset->data[i] + row));
572 else {
573 strncpy(buff, *((char **)SDDS_dataset->data[i] + row), currentDefaultStringLength);
575 }
576 if (!SDDS_MPI_WriteBinaryString(SDDS_dataset, buff)) {
577 free(buff);
578 return 0;
579 }
580 } else {
581 size = SDDS_type_size[type - 1];
582 if (!SDDS_MPI_BufferedWrite((char *)SDDS_dataset->data[i] + row * size, size, SDDS_dataset)) {
583 free(buff);
584 return 0;
585 }
586 }
587 }
588 free(buff);
589 writeKludgeUsleep = SDDS_MPI_GetLockedWriteKludgeUsleep();
590 if (writeKludgeUsleep)
591 usleepSystemIndependent(writeKludgeUsleep); /* This fixes write issue in test case. No data corruption observed. */
592 if (SDDS_MPI_GetLockedForceFileSync())
593 MPI_File_sync(SDDS_dataset->MPI_dataset->MPI_file); /* This also seems to fix it. */
594 return (1);
595}
void SDDS_StringTuncated(void)
Increment the truncated strings counter.
void usleepSystemIndependent(long usec)
Sleep for a given number of microseconds, system-independently.

◆ SDDS_MPI_WriteBinaryString()

int32_t SDDS_MPI_WriteBinaryString ( SDDS_DATASET * SDDS_dataset,
char * string )

Write a binary string to an SDDS dataset using MPI.

This function writes a string to the SDDS dataset in binary format using MPI. If the provided string is NULL, a dummy empty string is written instead.

Parameters
SDDS_datasetPointer to the SDDS_DATASET structure.
stringThe string to write. If NULL, an empty string is written.
Returns
1 on success, 0 on failure.

Definition at line 241 of file SDDS_MPI_binary.c.

241 {
242 int32_t length;
243
244#if MPI_DEBUG
245 logDebug("SDDS_MPI_WriteBinaryString", SDDS_dataset);
246#endif
247
248 if (!string)
249 string = "";
250
251 length = strlen(string);
252 if (!SDDS_MPI_BufferedWrite(&length, sizeof(length), SDDS_dataset))
253 return 0;
254 if (length && !SDDS_MPI_BufferedWrite(string, sizeof(*string) * length, SDDS_dataset))
255 return 0;
256 return 1;
257}

◆ SDDS_MPI_WriteContinuousBinaryPage()

int32_t SDDS_MPI_WriteContinuousBinaryPage ( SDDS_DATASET * SDDS_dataset)

Write a continuous binary page of the SDDS dataset using MPI.

This function writes an SDDS dataset page in binary format, handling both native and non-native byte orders based on the environment variable SDDS_OUTPUT_ENDIANESS. It manages buffer allocation, byte swapping, and coordinates writing across MPI processes.

Parameters
SDDS_datasetPointer to the SDDS_DATASET structure.
Returns
  • 1 on successful write.
  • 0 on failure.

Definition at line 1100 of file SDDS_MPI_binary.c.

1100 {
1101 int64_t row, prev_rows, i, total_rows, fixed_rows, rows;
1102 int mpi_code, type = 0;
1103 MPI_Offset column_offset, rowcount_offset, offset;
1104 int64_t *n_rows = NULL;
1105 int32_t min32 = INT32_MIN;
1106 MPI_Status status;
1107
1108 MPI_DATASET *MPI_dataset = NULL;
1109 SDDS_FILEBUFFER *fBuffer;
1110 char *outputEndianess = NULL;
1111
1112#if MPI_DEBUG
1113 logDebug("SDDS_MPI_WriteContinuousBinaryPage", SDDS_dataset);
1114#endif
1115
1116 /* usleep(10000); This doesn't really help */
1117
1118 if ((outputEndianess = getenv("SDDS_OUTPUT_ENDIANESS"))) {
1119 if (((strncmp(outputEndianess, "big", 3) == 0) && (SDDS_IsBigEndianMachine() == 0)) || ((strncmp(outputEndianess, "little", 6) == 0) && (SDDS_IsBigEndianMachine() == 1)))
1120 return SDDS_MPI_WriteNonNativeBinaryPage(SDDS_dataset);
1121 }
1122
1123 MPI_dataset = SDDS_dataset->MPI_dataset;
1124
1125 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_MPI_WriteContinuousBinaryPage"))
1126 return (0);
1127
1128 fBuffer = &SDDS_dataset->fBuffer;
1129 if (SDDS_dataset->layout.data_mode.column_major)
1130 /*write by column ignores the row flag and buffer is not needed for writing data by column */
1131 rows = SDDS_dataset->n_rows;
1132 else {
1133 rows = SDDS_CountRowsOfInterest(SDDS_dataset);
1134 if (!fBuffer->buffer) {
1135 fBuffer->bufferSize = SDDS_GetLockedDefaultWriteBufferSize();
1136 if (!(fBuffer->buffer = fBuffer->data = SDDS_Malloc(sizeof(char) * (fBuffer->bufferSize + 1)))) {
1137 SDDS_SetError("Unable to do buffered read--allocation failure (SDDS_WriteContinuousBinaryPage)");
1138 return 0;
1139 }
1140 fBuffer->bytesLeft = fBuffer->bufferSize;
1141 fBuffer->data[0] = 0;
1142 }
1143 }
1144 if (MPI_dataset->n_page >= 1)
1145 MPI_File_set_view(MPI_dataset->MPI_file, MPI_dataset->file_offset, MPI_BYTE, MPI_BYTE, "native", MPI_INFO_NULL);
1146 rowcount_offset = MPI_dataset->file_offset + SDDS_MPI_GetTitleOffset(SDDS_dataset); /* the offset before writing rows */
1147 /*get total number of rows writing */
1148 column_offset = MPI_dataset->column_offset;
1149 if (!(n_rows = calloc(sizeof(*n_rows), MPI_dataset->n_processors))) {
1150 SDDS_SetError("Memory allocation failed!");
1151 return 0;
1152 }
1153 MPI_Allgather(&rows, 1, MPI_INT64_T, n_rows, 1, MPI_INT64_T, MPI_dataset->comm);
1154 prev_rows = 0;
1155 for (i = 0; i < MPI_dataset->myid; i++)
1156 prev_rows += n_rows[i];
1157 total_rows = 0;
1158 for (i = 0; i < MPI_dataset->n_processors; i++)
1159 total_rows += n_rows[i];
1160 if (MPI_dataset->myid == 0) {
1161 fixed_rows = total_rows;
1162 if (!fBuffer->buffer) {
1163 fBuffer->bufferSize = SDDS_GetLockedDefaultWriteBufferSize();
1164 if (!(fBuffer->buffer = fBuffer->data = SDDS_Malloc(sizeof(char) * (fBuffer->bufferSize + 1)))) {
1165 SDDS_SetError("Unable to do buffered read--allocation failure (SDDS_WriteContinuousBinaryPage)");
1166 return 0;
1167 }
1168 fBuffer->bytesLeft = fBuffer->bufferSize;
1169 fBuffer->data[0] = 0;
1170 }
1171 if (fixed_rows > INT32_MAX) {
1172 if (!SDDS_MPI_BufferedWrite(&min32, sizeof(min32), SDDS_dataset))
1173 return 0;
1174 if (!SDDS_MPI_BufferedWrite(&fixed_rows, sizeof(fixed_rows), SDDS_dataset))
1175 return 0;
1176 } else {
1177 int32_t fixed_rows32;
1178 fixed_rows32 = (int32_t)fixed_rows;
1179 if (!SDDS_MPI_BufferedWrite(&fixed_rows32, sizeof(fixed_rows32), SDDS_dataset))
1180 return 0;
1181 }
1182 if (!SDDS_MPI_WriteBinaryParameters(SDDS_dataset) || !SDDS_MPI_WriteBinaryArrays(SDDS_dataset))
1183 return 0;
1184 /* flush buffer, write everything in the buffer to file */
1185 if (!SDDS_MPI_FlushBuffer(SDDS_dataset))
1186 return 0;
1187 }
1188
1189 if (SDDS_dataset->layout.data_mode.column_major) {
1190 /*write data by column */
1191 offset = rowcount_offset;
1192 for (i = 0; i < SDDS_dataset->layout.n_columns; i++) {
1193 type = SDDS_dataset->layout.column_definition[i].type;
1194 MPI_dataset->file_offset = offset + (MPI_Offset)prev_rows * SDDS_type_size[type - 1];
1195 if (type == SDDS_STRING) {
1196 SDDS_SetError("Can not write string column to SDDS3 (SDDS_MPI_WriteContinuousBinaryPage");
1197 return 0;
1198 }
1199 if ((mpi_code = MPI_File_set_view(MPI_dataset->MPI_file, MPI_dataset->file_offset, MPI_BYTE, MPI_BYTE, "native", MPI_INFO_NULL)) != MPI_SUCCESS) {
1200 SDDS_MPI_GOTO_ERROR(stderr, "Unable to set view for read binary rows", mpi_code, 0);
1201 SDDS_SetError("Unable to set view for read binary rows");
1202 return 0;
1203 }
1204 if ((mpi_code = MPI_File_write(MPI_dataset->MPI_file, SDDS_dataset->data[i], rows * SDDS_type_size[type - 1], MPI_BYTE, &status)) != MPI_SUCCESS) {
1205 SDDS_SetError("Unable to write binary columns (SDDS_MPI_WriteContinuousBinaryPage");
1206 return 0;
1207 }
1208
1209 offset += (MPI_Offset)total_rows * SDDS_type_size[type - 1];
1210 }
1211 MPI_dataset->file_offset = offset;
1212 } else {
1213 /* now all processors write column data row by row */
1214 MPI_dataset->file_offset = rowcount_offset + (MPI_Offset)prev_rows * column_offset;
1215 /* set view to the position where the processor starts writing data */
1216 MPI_File_set_view(MPI_dataset->MPI_file, MPI_dataset->file_offset, MPI_BYTE, MPI_BYTE, "native", MPI_INFO_NULL);
1217 if (!MPI_dataset->collective_io) {
1218 row = 0;
1219 for (i = 0; i < SDDS_dataset->n_rows; i++) {
1220 if (SDDS_dataset->row_flag[i] && !SDDS_MPI_WriteBinaryRow(SDDS_dataset, i))
1221 return 0;
1222 row++;
1223 }
1224 /*get current file position until now */
1225 SDDS_dataset->n_rows = row;
1226 if (!SDDS_MPI_FlushBuffer(SDDS_dataset))
1227 return 0;
1228 } else {
1229 if (!SDDS_MPI_CollectiveWriteByRow(SDDS_dataset))
1230 return 0;
1231 row = SDDS_dataset->n_rows;
1232 }
1233 MPI_Allreduce(&row, &total_rows, 1, MPI_INT64_T, MPI_SUM, MPI_dataset->comm);
1234 MPI_dataset->file_offset = rowcount_offset + total_rows * column_offset;
1235 rows = row;
1236 }
1237 free(n_rows);
1238 /*skip checking if all data has been written for now */
1239 SDDS_dataset->last_row_written = SDDS_dataset->n_rows - 1;
1240 SDDS_dataset->n_rows_written = rows;
1241 SDDS_dataset->writing_page = 1;
1242 MPI_dataset->n_page++;
1243
1244 return 1;
1245}
int32_t SDDS_MPI_WriteBinaryParameters(SDDS_DATASET *SDDS_dataset)
Write binary parameters of an SDDS dataset using MPI.
int32_t SDDS_MPI_WriteBinaryArrays(SDDS_DATASET *SDDS_dataset)
Write binary arrays of an SDDS dataset using MPI.
int32_t SDDS_MPI_CollectiveWriteByRow(SDDS_DATASET *SDDS_dataset)
Writes SDDS dataset rows collectively by row using MPI parallel I/O.
int32_t SDDS_MPI_WriteNonNativeBinaryPage(SDDS_DATASET *SDDS_dataset)
Write a non-native binary page of the SDDS dataset using MPI.
int64_t SDDS_CountRowsOfInterest(SDDS_DATASET *SDDS_dataset)
Counts the number of rows marked as "of interest" in the current data table.
int32_t SDDS_IsBigEndianMachine()
Determines whether the current machine uses big-endian byte ordering.

◆ SDDS_MPI_WriteNonNativeBinaryArrays()

int32_t SDDS_MPI_WriteNonNativeBinaryArrays ( SDDS_DATASET * SDDS_dataset)

Write non-native binary arrays of an SDDS dataset using MPI.

This function writes all arrays of the SDDS dataset in non-native binary format using MPI, handling byte swapping as necessary. It handles different types of arrays, including strings and fixed-size data types.

Only the master processor should call this function to write SDDS headers, parameters, and arrays.

Parameters
SDDS_datasetPointer to the SDDS_DATASET structure.
Returns
1 on success, 0 on failure.

Definition at line 441 of file SDDS_MPI_binary.c.

441 {
442 int32_t i, j, zero = 0, writeSize = 0;
443 SDDS_LAYOUT *layout;
444
445 /*only the master processor write SDDS header, parameters and arrays */
446
447 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_MPI_WriteBinaryArray"))
448 return (0);
449 SDDS_SwapEndsArrayData(SDDS_dataset);
450 layout = &SDDS_dataset->layout;
451 for (i = 0; i < layout->n_arrays; i++) {
452 if (!SDDS_dataset->array[i].dimension) {
453 for (j = 0; j < layout->array_definition[i].dimensions; j++) {
454 if (!SDDS_MPI_BufferedWrite(&zero, sizeof(zero), SDDS_dataset)) {
455 SDDS_SetError("Unable to write null array--failure writing dimensions (SDDS_MPI_WriteBinaryArrays)");
456 SDDS_SwapEndsArrayData(SDDS_dataset);
457 return 0;
458 }
459 }
460 continue;
461 }
462 writeSize = sizeof(*(SDDS_dataset->array)[i].dimension) * layout->array_definition[i].dimensions;
463 if (!SDDS_MPI_BufferedWrite(SDDS_dataset->array[i].dimension, writeSize, SDDS_dataset)) {
464 SDDS_SetError("Unable to write arrays--failure writing dimensions (SDDS_MPI_WriteBinaryArrays)");
465 SDDS_SwapEndsArrayData(SDDS_dataset);
466 return (0);
467 }
468 if (layout->array_definition[i].type == SDDS_STRING) {
469 for (j = 0; j < SDDS_dataset->array[i].elements; j++) {
470 if (!SDDS_MPI_WriteNonNativeBinaryString(SDDS_dataset, ((char **)SDDS_dataset->array[i].data)[j])) {
471 SDDS_SetError("Unable to write arrays--failure writing string (SDDS_WriteBinaryArrays)");
472 SDDS_SwapEndsArrayData(SDDS_dataset);
473 return (0);
474 }
475 }
476 } else {
477 writeSize = SDDS_type_size[layout->array_definition[i].type - 1] * SDDS_dataset->array[i].elements;
478 if (!SDDS_MPI_BufferedWrite(SDDS_dataset->array[i].data, writeSize, SDDS_dataset)) {
479 SDDS_SetError("Unable to write arrays--failure writing values (SDDS_MPI_WriteBinaryArrays)");
480 SDDS_SwapEndsArrayData(SDDS_dataset);
481 return (0);
482 }
483 }
484 }
485 SDDS_SwapEndsArrayData(SDDS_dataset);
486 return (1);
487}
int32_t SDDS_MPI_WriteNonNativeBinaryString(SDDS_DATASET *SDDS_dataset, char *string)
Write a non-native binary string to an SDDS dataset using MPI.

◆ SDDS_MPI_WriteNonNativeBinaryPage()

int32_t SDDS_MPI_WriteNonNativeBinaryPage ( SDDS_DATASET * SDDS_dataset)

Write a non-native binary page of the SDDS dataset using MPI.

This function handles the writing of an entire SDDS dataset page in non-native binary format. It manages buffer allocation, handles byte swapping for non-native formats, and ensures that all parameters and arrays are correctly written. It also coordinates writing across multiple MPI processes.

Parameters
SDDS_datasetPointer to the SDDS_DATASET structure.
Returns
  • 1 on successful write.
  • 0 on failure.

Definition at line 942 of file SDDS_MPI_binary.c.

942 {
943 int64_t row, prev_rows, i, total_rows, fixed_rows, rows;
944 int mpi_code, type = 0;
945 MPI_Offset column_offset, rowcount_offset, offset;
946 int64_t *n_rows = NULL;
947 MPI_Status status;
948 int32_t min32 = INT32_MIN;
949
950 MPI_DATASET *MPI_dataset = NULL;
951 SDDS_FILEBUFFER *fBuffer;
952
953#if MPI_DEBUG
954 logDebug("SDDS_MPI_WriteNonNativeBinaryPage", SDDS_dataset);
955#endif
956
957 MPI_dataset = SDDS_dataset->MPI_dataset;
958
959#if MPI_DEBUG
960
961#endif
962
963 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_MPI_WriteNonNativeBinaryPage"))
964 return (0);
965
966 fBuffer = &SDDS_dataset->fBuffer;
967 if (SDDS_dataset->layout.data_mode.column_major)
968 /*write by column ignores the row flag and buffer is not needed for writing data by column */
969 rows = SDDS_dataset->n_rows;
970 else {
971 rows = SDDS_CountRowsOfInterest(SDDS_dataset);
972 if (!fBuffer->buffer) {
973 fBuffer->bufferSize = SDDS_GetLockedDefaultWriteBufferSize();
974 if (!(fBuffer->buffer = fBuffer->data = SDDS_Malloc(sizeof(char) * (fBuffer->bufferSize + 1)))) {
975 SDDS_SetError("Unable to do buffered read--allocation failure (SDDS_WriteNonNativeBinaryPage)");
976 return 0;
977 }
978 fBuffer->bytesLeft = fBuffer->bufferSize;
979 fBuffer->data[0] = 0;
980 }
981 }
982 if (MPI_dataset->n_page >= 1)
983 MPI_File_set_view(MPI_dataset->MPI_file, MPI_dataset->file_offset, MPI_BYTE, MPI_BYTE, "native", MPI_INFO_NULL);
984 rowcount_offset = MPI_dataset->file_offset + SDDS_MPI_GetTitleOffset(SDDS_dataset); /* the offset before writing rows */
985 /*get total number of rows writing */
986 column_offset = MPI_dataset->column_offset;
987 if (!(n_rows = calloc(sizeof(*n_rows), MPI_dataset->n_processors))) {
988 SDDS_SetError("Memory allocation failed!");
989 return 0;
990 }
991 MPI_Allgather(&rows, 1, MPI_INT64_T, n_rows, 1, MPI_INT64_T, MPI_dataset->comm);
992 prev_rows = 0;
993 for (i = 0; i < MPI_dataset->myid; i++)
994 prev_rows += n_rows[i];
995 total_rows = 0;
996 for (i = 0; i < MPI_dataset->n_processors; i++)
997 total_rows += n_rows[i];
998 if (MPI_dataset->myid == 0) {
999 fixed_rows = total_rows;
1000 if (!fBuffer->buffer) {
1001 fBuffer->bufferSize = SDDS_GetLockedDefaultWriteBufferSize();
1002 if (!(fBuffer->buffer = fBuffer->data = SDDS_Malloc(sizeof(char) * (fBuffer->bufferSize + 1)))) {
1003 SDDS_SetError("Unable to do buffered read--allocation failure (SDDS_WriteNonNativeBinaryPage)");
1004 return 0;
1005 }
1006 fBuffer->bytesLeft = fBuffer->bufferSize;
1007 fBuffer->data[0] = 0;
1008 }
1009 if (fixed_rows > INT32_MAX) {
1010 SDDS_SwapLong(&min32);
1011 if (!SDDS_MPI_BufferedWrite(&min32, sizeof(min32), SDDS_dataset))
1012 return 0;
1013 SDDS_SwapLong64(&fixed_rows);
1014 if (!SDDS_MPI_BufferedWrite(&fixed_rows, sizeof(fixed_rows), SDDS_dataset))
1015 return 0;
1016 } else {
1017 int32_t fixed_rows32;
1018 fixed_rows32 = (int32_t)fixed_rows;
1019 SDDS_SwapLong(&fixed_rows32);
1020 if (!SDDS_MPI_BufferedWrite(&fixed_rows32, sizeof(fixed_rows32), SDDS_dataset))
1021 return 0;
1022 }
1024 return 0;
1025 /* flush buffer, write everything in the buffer to file */
1026 if (!SDDS_MPI_FlushBuffer(SDDS_dataset))
1027 return 0;
1028 }
1029 SDDS_SwapEndsColumnData(SDDS_dataset);
1030 if (SDDS_dataset->layout.data_mode.column_major) {
1031 /*write data by column */
1032 offset = rowcount_offset;
1033 for (i = 0; i < SDDS_dataset->layout.n_columns; i++) {
1034 type = SDDS_dataset->layout.column_definition[i].type;
1035 MPI_dataset->file_offset = offset + (MPI_Offset)prev_rows * SDDS_type_size[type - 1];
1036 if (type == SDDS_STRING) {
1037 SDDS_SetError("Can not write string column to SDDS3 (SDDS_MPI_WriteNonNativeBinaryPage");
1038 return 0;
1039 }
1040 if ((mpi_code = MPI_File_set_view(MPI_dataset->MPI_file, MPI_dataset->file_offset, MPI_BYTE, MPI_BYTE, "native", MPI_INFO_NULL)) != MPI_SUCCESS) {
1041 SDDS_MPI_GOTO_ERROR(stderr, "Unable to set view for read binary rows", mpi_code, 0);
1042 SDDS_SetError("Unable to set view for read binary rows");
1043 return 0;
1044 }
1045 if ((mpi_code = MPI_File_write(MPI_dataset->MPI_file, SDDS_dataset->data[i], rows * SDDS_type_size[type - 1], MPI_BYTE, &status)) != MPI_SUCCESS) {
1046 SDDS_SetError("Unable to write binary columns (SDDS_MPI_WriteNonNativeBinaryPage");
1047 return 0;
1048 }
1049
1050 offset += (MPI_Offset)total_rows * SDDS_type_size[type - 1];
1051 }
1052 MPI_dataset->file_offset = offset;
1053 } else {
1054 /* now all processors write column data row by row */
1055 MPI_dataset->file_offset = rowcount_offset + (MPI_Offset)prev_rows * column_offset;
1056 /* set view to the position where the processor starts writing data */
1057 MPI_File_set_view(MPI_dataset->MPI_file, MPI_dataset->file_offset, MPI_BYTE, MPI_BYTE, "native", MPI_INFO_NULL);
1058 if (!MPI_dataset->collective_io) {
1059 row = 0;
1060 for (i = 0; i < SDDS_dataset->n_rows; i++) {
1061 if (SDDS_dataset->row_flag[i] && !SDDS_MPI_WriteNonNativeBinaryRow(SDDS_dataset, i))
1062 return 0;
1063 row++;
1064 }
1065 /*get current file position until now */
1066 SDDS_dataset->n_rows = row;
1067 if (!SDDS_MPI_FlushBuffer(SDDS_dataset))
1068 return 0;
1069 } else {
1070 if (!SDDS_MPI_CollectiveWriteByRow(SDDS_dataset))
1071 return 0;
1072 row = SDDS_dataset->n_rows;
1073 }
1074 MPI_Allreduce(&row, &total_rows, 1, MPI_INT64_T, MPI_SUM, MPI_dataset->comm);
1075 MPI_dataset->file_offset = rowcount_offset + total_rows * column_offset;
1076 rows = row;
1077 }
1078 SDDS_SwapEndsColumnData(SDDS_dataset);
1079 free(n_rows);
1080 /*skip checking if all data has been written for now */
1081 SDDS_dataset->last_row_written = SDDS_dataset->n_rows - 1;
1082 SDDS_dataset->n_rows_written = rows;
1083 SDDS_dataset->writing_page = 1;
1084 MPI_dataset->n_page++;
1085 return 1;
1086}
int32_t SDDS_MPI_WriteNonNativeBinaryArrays(SDDS_DATASET *SDDS_dataset)
Write non-native binary arrays of an SDDS dataset using MPI.
int32_t SDDS_MPI_WriteNonNativeBinaryParameters(SDDS_DATASET *SDDS_dataset)
Write non-native binary parameters of an SDDS dataset using MPI.
void SDDS_SwapLong64(int64_t *data)
Swaps the endianness of a 64-bit integer.

◆ SDDS_MPI_WriteNonNativeBinaryParameters()

int32_t SDDS_MPI_WriteNonNativeBinaryParameters ( SDDS_DATASET * SDDS_dataset)

Write non-native binary parameters of an SDDS dataset using MPI.

This function writes all non-fixed parameters of the SDDS dataset in non-native binary format using MPI, handling byte swapping as necessary. String parameters are written using SDDS_MPI_WriteNonNativeBinaryString, and other types are written directly to the buffer.

Only the master processor should call this function to write SDDS headers, parameters, and arrays.

Parameters
SDDS_datasetPointer to the SDDS_DATASET structure.
Returns
1 on success, 0 on failure.

Definition at line 343 of file SDDS_MPI_binary.c.

343 {
344 SDDS_LAYOUT *layout;
345 int32_t i;
346
347#if MPI_DEBUG
348 logDebug("SDDS_MPI_WriteNonNativeBinaryParameters", SDDS_dataset);
349#endif
350
351 /*should only master processors write SDDS hearder,parameters and arrays */
352 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_MPI_WriteBinaryParameters"))
353 return (0);
354 layout = &SDDS_dataset->layout;
355 SDDS_SwapEndsParameterData(SDDS_dataset);
356 for (i = 0; i < layout->n_parameters; i++) {
357 if (layout->parameter_definition[i].fixed_value)
358 continue;
359 if (layout->parameter_definition[i].type == SDDS_STRING) {
360 if (!SDDS_MPI_WriteNonNativeBinaryString(SDDS_dataset, *(char **)SDDS_dataset->parameter[i])) {
361 SDDS_SwapEndsParameterData(SDDS_dataset);
362 return 0;
363 }
364 } else {
365 if (!SDDS_MPI_BufferedWrite(SDDS_dataset->parameter[i], SDDS_type_size[layout->parameter_definition[i].type - 1], SDDS_dataset)) {
366 SDDS_SwapEndsParameterData(SDDS_dataset);
367 return 0;
368 }
369 }
370 }
371 SDDS_SwapEndsParameterData(SDDS_dataset);
372 return (1);
373}

◆ SDDS_MPI_WriteNonNativeBinaryRow()

int32_t SDDS_MPI_WriteNonNativeBinaryRow ( SDDS_DATASET * SDDS_dataset,
int64_t row )

Write a non-native binary row to an SDDS dataset using MPI.

This function writes a specific row of data from the SDDS dataset in non-native binary format using MPI, handling byte swapping as necessary. It manages different column types, including strings with truncation based on the default string length. Optional write kludge delays and file synchronization can be applied based on configuration.

Parameters
SDDS_datasetPointer to the SDDS_DATASET structure.
rowThe row index to write.
Returns
1 on success, 0 on failure.

Definition at line 609 of file SDDS_MPI_binary.c.

609 {
610 int32_t size, type;
611 int64_t i;
612 SDDS_LAYOUT *layout;
613 /*char buff[defaultStringLength+1], format[256]; */
614 char *buff;
615 char format[256];
616 int32_t currentDefaultStringLength;
617 long writeKludgeUsleep;
618#if MPI_DEBUG
619 logDebug("SDDS_MPI_WriteNonNativeBinaryRow", SDDS_dataset);
620#endif
621
622 if (!SDDS_CheckDataset(SDDS_dataset, "SDDS_WriteBinaryRow"))
623 return (0);
624
625 layout = &SDDS_dataset->layout;
626 currentDefaultStringLength = SDDS_GetLockedDefaultStringLength();
627
628 if (currentDefaultStringLength < 0 || currentDefaultStringLength >= INT32_MAX) {
629 SDDS_SetError("Default string length is too large in SDDS_MPI_WriteNonNativeBinaryRow!");
630 return 0;
631 }
632 if (snprintf(format, sizeof(format), "%%-%" PRId32 "s", currentDefaultStringLength) >= (int)sizeof(format)) {
633 SDDS_SetError("Default string length is too large in SDDS_MPI_WriteNonNativeBinaryRow!");
634 return 0;
635 }
636 if (!(buff = malloc(sizeof(*buff) * ((size_t)currentDefaultStringLength + 1)))) {
637 SDDS_SetError("Can not allocate memory in SDDS_MPI_WriteNonNativeBinaryRow!");
638 return 0;
639 }
640 buff[currentDefaultStringLength] = 0;
641 for (i = 0; i < layout->n_columns; i++) {
642 type = layout->column_definition[i].type;
643 size = SDDS_type_size[type - 1];
644
645 if (type == SDDS_STRING) {
646 if (strlen(*((char **)SDDS_dataset->data[i] + row)) <= currentDefaultStringLength)
647 sprintf(buff, format, *((char **)SDDS_dataset->data[i] + row));
648 else {
649 strncpy(buff, *((char **)SDDS_dataset->data[i] + row), currentDefaultStringLength);
651 }
652 if (!SDDS_MPI_WriteNonNativeBinaryString(SDDS_dataset, buff)) {
653 free(buff);
654 return 0;
655 }
656 } else {
657 size = SDDS_type_size[type - 1];
658 if (!SDDS_MPI_BufferedWrite((char *)SDDS_dataset->data[i] + row * size, size, SDDS_dataset)) {
659 free(buff);
660 return 0;
661 }
662 }
663 }
664 free(buff);
665 writeKludgeUsleep = SDDS_MPI_GetLockedWriteKludgeUsleep();
666 if (writeKludgeUsleep)
667 usleepSystemIndependent(writeKludgeUsleep); /* This fixes write issue in test case. No data corruption observed. */
668 if (SDDS_MPI_GetLockedForceFileSync())
669 MPI_File_sync(SDDS_dataset->MPI_dataset->MPI_file); /* This also seems to fix it. */
670 return (1);
671}

◆ SDDS_MPI_WriteNonNativeBinaryString()

int32_t SDDS_MPI_WriteNonNativeBinaryString ( SDDS_DATASET * SDDS_dataset,
char * string )

Write a non-native binary string to an SDDS dataset using MPI.

This function writes a string to the SDDS dataset in non-native binary format using MPI, handling byte swapping as necessary. If the provided string is NULL, a dummy empty string is written instead.

Parameters
SDDS_datasetPointer to the SDDS_DATASET structure.
stringThe string to write. If NULL, an empty string is written.
Returns
1 on success, 0 on failure.

Definition at line 270 of file SDDS_MPI_binary.c.

270 {
271 int32_t length;
272
273#if MPI_DEBUG
274 logDebug("SDDS_MPI_WriteNonNativeBinaryString", SDDS_dataset);
275#endif
276
277 if (!string)
278 string = "";
279
280 length = strlen(string);
281 SDDS_SwapLong(&length);
282 if (!SDDS_MPI_BufferedWrite(&length, sizeof(length), SDDS_dataset))
283 return 0;
284 SDDS_SwapLong(&length);
285 if (length && !SDDS_MPI_BufferedWrite(string, sizeof(*string) * length, SDDS_dataset))
286 return 0;
287 return 1;
288}

◆ SDDS_SetDefaultReadBufferSize()

int32_t SDDS_SetDefaultReadBufferSize ( int32_t newSize)

Set the default read buffer size for SDDS.

This function updates the default buffer size used for reading SDDS binary data.

Parameters
newSizeThe new buffer size to set. Must be greater than zero. If newSize is less than or equal to zero, the current default read buffer size is returned without modifying it.
Returns
The previous default read buffer size.

Definition at line 112 of file SDDS_MPI_binary.c.

112 {
113 int32_t previous;
114 if (newSize <= 0)
115 return SDDS_GetLockedDefaultReadBufferSize();
116 mdb_thread_lock(&defaultReadBufferSizeLock);
117 previous = defaultReadBufferSize;
118 defaultReadBufferSize = newSize;
119 mdb_thread_unlock(&defaultReadBufferSizeLock);
120 return previous;
121}

◆ SDDS_SetDefaultStringLength()

int32_t SDDS_SetDefaultStringLength ( int32_t newValue)

Set the default string length for SDDS.

This function updates the default maximum length for string columns in SDDS.

Parameters
newValueThe new string length to set. Must be non-negative. If newValue is negative, the current default string length is returned without modifying it.
Returns
The previous default string length.

Definition at line 203 of file SDDS_MPI_binary.c.

203 {
204 int32_t previous;
205 if (newValue < 0)
206 return SDDS_GetLockedDefaultStringLength();
207 mdb_thread_lock(&defaultStringLengthLock);
208 previous = defaultStringLength;
209 defaultStringLength = newValue;
210 mdb_thread_unlock(&defaultStringLengthLock);
211 return previous;
212}

◆ SDDS_SetDefaultTitleBufferSize()

int32_t SDDS_SetDefaultTitleBufferSize ( int32_t newSize)

Set the default title buffer size for SDDS.

This function updates the default buffer size used for storing SDDS titles.

Parameters
newSizeThe new buffer size to set. Must be greater than zero. If newSize is less than or equal to zero, the current default title buffer size is returned without modifying it.
Returns
The previous default title buffer size.

Definition at line 154 of file SDDS_MPI_binary.c.

154 {
155 int32_t previous;
156 if (newSize <= 0)
157 return SDDS_GetLockedDefaultTitleBufferSize();
158 mdb_thread_lock(&defaultTitleBufferSizeLock);
159 previous = defaultTitleBufferSize;
160 defaultTitleBufferSize = newSize;
161 mdb_thread_unlock(&defaultTitleBufferSizeLock);
162 return previous;
163}

◆ SDDS_SetDefaultWriteBufferSize()

int32_t SDDS_SetDefaultWriteBufferSize ( int32_t newSize)

Set the default write buffer size for SDDS.

This function updates the default buffer size used for writing SDDS binary data.

Parameters
newSizeThe new buffer size to set. Must be greater than zero. If newSize is less than or equal to zero, the current default write buffer size is returned without modifying it.
Returns
The previous default write buffer size.

Definition at line 133 of file SDDS_MPI_binary.c.

133 {
134 int32_t previous;
135 if (newSize <= 0)
136 return SDDS_GetLockedDefaultWriteBufferSize();
137 mdb_thread_lock(&defaultWriteBufferSizeLock);
138 previous = defaultWriteBufferSize;
139 defaultWriteBufferSize = newSize;
140 mdb_thread_unlock(&defaultWriteBufferSizeLock);
141 return previous;
142}

◆ SDDS_StringTuncated()

void SDDS_StringTuncated ( void )

Increment the truncated strings counter.

This function increments the count of strings that have been truncated.

Definition at line 187 of file SDDS_MPI_binary.c.

187 {
188 mdb_thread_lock(&number_of_string_truncated_lock);
189 number_of_string_truncated++;
190 mdb_thread_unlock(&number_of_string_truncated_lock);
191}