int adios_transform_isobar_apply(struct adios_file_struct *fd, struct adios_var_struct *var, uint64_t *transformed_len, int use_shared_buffer, int *wrote_to_shared_buffer) { // Get the input data and data length const uint64_t input_size = adios_transform_get_pre_transform_var_size(var); const void *input_buff = var->data; // parse the compressiong parameter /* pre-specparse code int compress_level = ISOBAR_SPEED; if(var->transform_type_param && strlen(var->transform_type_param) > 0 && is_digit_str(var->transform_type_param)) { compress_level = atoi(var->transform_type_param); if(compress_level > 9 || compress_level < 1) { compress_level = ISOBAR_SPEED; } } */ int compress_level = ISOBAR_SPEED; if (var->transform_spec->param_count > 0) { compress_level = atoi(var->transform_spec->params[0].key); if (compress_level < 1 || compress_level > 9) compress_level = ISOBAR_SPEED; } // decide the output buffer uint64_t output_size = input_size; //adios_transform_isobar_calc_vars_transformed_size(adios_transform_isobar, input_size, 1); void* output_buff = NULL; if (use_shared_buffer) // If shared buffer is permitted, serialize to there { *wrote_to_shared_buffer = 1; if (!shared_buffer_reserve(fd, output_size)) { log_error("Out of memory allocating %llu bytes for %s for isobar transform\n", output_size, var->name); return 0; } // Write directly to the shared buffer output_buff = fd->buffer + fd->offset; } else // Else, fall back to var->data memory allocation { *wrote_to_shared_buffer = 0; output_buff = malloc(output_size); if (!output_buff) { log_error("Out of memory allocating %llu bytes for %s for isobar transform\n", output_size, var->name); return 0; } } uint64_t actual_output_size = output_size; char compress_ok = 1; // compress it int rtn = compress_isobar_pre_allocated(input_buff, input_size, output_buff, &actual_output_size, compress_level); if(0 != rtn // compression failed for some reason, then just copy the buffer || actual_output_size > input_size) // or size after compression is even larger (not likely to happen since compression lib will return non-zero in this case) { // printf("compression failed, fall back to memory copy\n"); memcpy(output_buff, input_buff, input_size); actual_output_size = input_size; compress_ok = 0; // succ sign set to 0 } // Wrap up, depending on buffer mode if (use_shared_buffer) { shared_buffer_mark_written(fd, actual_output_size); } else { var->data = output_buff; var->data_size = actual_output_size; var->free_data = adios_flag_yes; } // copy the metadata, simply the original size before compression if(var->transform_metadata && var->transform_metadata_len > 0) { memcpy((char*)var->transform_metadata, &input_size, sizeof(uint64_t)); memcpy((char*)var->transform_metadata + sizeof(uint64_t), &compress_ok, sizeof(char)); } *transformed_len = actual_output_size; // Return the size of the data buffer return 1; }
int adios_transform_aplod_apply(struct adios_file_struct *fd, struct adios_var_struct *var, uint64_t *transformed_len, int use_shared_buffer, int *wrote_to_shared_buffer) { // Get the input data and data length const uint64_t input_size = adios_transform_get_pre_transform_var_size(var); const void *input_buff = var->data; // max size supported is long double int32_t componentVector[MAX_COMPONENTS]; int8_t numComponents = 0; int32_t componentTotals = 0; // printf ("[%s] byte = %d, real = %d, double = %d, this = %d\n", var->name, adios_byte, adios_real, adios_double, var->pre_transform_type); // parse the aplod component vector parameters /* Old, pre-specparse parameter parsing if(var->transform_type_param) { char transform_param [1024]; char *transform_param_ptr = 0; uint16_t transform_param_length = 0; char transform_param_option [256]; uint16_t idx = 0; strcpy (transform_param, var->transform_type_param); transform_param_ptr = transform_param; transform_param_length = strlen (transform_param); // Get the key char *key = strtok (transform_param, "="); if (strcmp (key, "CV") == 0) { char *value = strtok (key, ","); int32_t componentID = 0; while (value) { int32_t component = atoi (value); if (component <= 0) { numComponents = 0; break ; } componentVector [componentID] = component; componentTotals += component; componentID ++; } } } */ int i; int paramError = 0; for (i = 0; i < var->transform_spec->param_count; i++) { const char *comp = var->transform_spec->params[i].key; int compInt = atoi(comp); // Error if any component is non-positive if (compInt <= 0 || numComponents >= MAX_COMPONENTS) { numComponents = 0; paramError = 1; break; } componentVector[numComponents++] = compInt; componentTotals += compInt; } uint32_t pre_transform_type_size = bp_get_type_size (var->pre_transform_type, ""); // Error if components were specified, and the components don't sum to the type size if ((numComponents > 0) && (componentTotals != pre_transform_type_size)) { paramError = 1; } if (paramError) { fprintf(stderr, "Warning: at least one APLOD byte component is a non-positive integer, or all components do not sum to the type size (%d) for variable %s/%s. Using default APLOD configuration instead.\n", bp_get_type_size (var->pre_transform_type, ""), var->path, var->name); } if ((numComponents == 0) || (componentTotals != pre_transform_type_size)) { if (var->pre_transform_type == adios_double) { componentVector [0] = 2; componentVector [1] = 2; componentVector [2] = 2; componentVector [3] = 2; numComponents = 4; } else if (var->pre_transform_type == adios_real) { componentVector [0] = 2; componentVector [1] = 2; numComponents = 2; } else { numComponents = 0; while (componentTotals < pre_transform_type_size - 2) { componentVector [numComponents ++] = 2; componentTotals += 2; } componentVector [numComponents ++] = pre_transform_type_size - componentTotals; } } // decide the output buffer uint64_t output_size = input_size; void* output_buff = NULL; if (use_shared_buffer) { // If shared buffer is permitted, serialize to there assert(shared_buffer_reserve(fd, output_size)); // Write directly to the shared buffer output_buff = fd->buffer + fd->offset; } else { // Else, fall back to var->adata memory allocation output_buff = malloc(output_size); assert(output_buff); } *wrote_to_shared_buffer = use_shared_buffer; // APLOD specific code - Start uint32_t numElements = input_size / bp_get_type_size (var->pre_transform_type, ""); APLODConfig_t *config; if (var->pre_transform_type == adios_double) { config = APLODConfigure (componentVector, numComponents, APLOD_DOUBLE, APLOD_LITTLE_E); } else if (var->pre_transform_type == adios_real) { config = APLODConfigure (componentVector, numComponents, APLOD_FLOAT, APLOD_LITTLE_E); } // config->blockLengthElts = numElements; // Bug workaround, disable chunking config->blockLengthElts = (numElements >= 65536 ? 65536: numElements); APLODShuffleComponents (config, numElements, 0, numComponents, input_buff, output_buff); // APLOD specific code - End // Wrap up, depending on buffer mode if (*wrote_to_shared_buffer) { shared_buffer_mark_written(fd, output_size); } else { var->adata = output_buff; var->data_size = output_size; var->free_data = adios_flag_yes; } *transformed_len = output_size; // Return the size of the data buffer // Do I copy the PLODHandle_t object as the metadata or do I serialize it into the buffer as well if(var->transform_metadata && var->transform_metadata_len > 0) { memcpy ((char*)var->transform_metadata, &input_size, sizeof(uint64_t)); memcpy ((char*)var->transform_metadata + sizeof (uint64_t), &numComponents, sizeof (numComponents)); memcpy ((char*)var->transform_metadata + sizeof (uint64_t) + sizeof (numComponents), componentVector, numComponents * sizeof (int32_t)); } // Cleanup time APLODDestroy(config); return 1; }