Code Samples and Examples#
Low-level C API Examples#
cache_flush#
/*******************************************************************************
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "dml/dml.h"
#include "examples_utils.h"
#define BUFFER_SIZE 1024u // 1 KB
/*
* This example demonstrates how to create and run a cache flush operation.
*/
int main(int argc, char **argv)
{
dml_path_t execution_path = DML_PATH_SW;
// Get path from input argument
int parse_ret = parse_execution_path(argc, argv, &execution_path);
if (parse_ret != 0) {
return 1;
}
printf("Starting cache flush job example.\n");
printf("Flushing 1KB of data from cache to memory.\n");
dml_job_t *dml_job_ptr = NULL;
uint32_t size = 0u;
uint8_t destination[BUFFER_SIZE];
dml_status_t status = dml_get_job_size(execution_path, &size);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during getting job size.\n", status);
return 1;
}
dml_job_ptr = (dml_job_t *)malloc(size);
status = dml_init_job(execution_path, dml_job_ptr);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during job initialization.\n", status);
free(dml_job_ptr);
return 1;
}
dml_job_ptr->operation = DML_OP_CACHE_FLUSH;
dml_job_ptr->destination_first_ptr = destination;
dml_job_ptr->destination_length = BUFFER_SIZE;
status = dml_execute_job(dml_job_ptr, DML_WAIT_MODE_BUSY_POLL);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during job execution.\n", status);
dml_finalize_job(dml_job_ptr);
free(dml_job_ptr);
return 1;
}
status = dml_finalize_job(dml_job_ptr);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during job finalization.\n", status);
free(dml_job_ptr);
return 1;
}
free(dml_job_ptr);
printf("Job Completed Successfully.\n");
return 0;
}
compare_pattern#
/*******************************************************************************
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "dml/dml.h"
#include "examples_utils.h"
#define BUFFER_SIZE 1024u // 1 KB
#define PATTERN_SIZE 8u // pattern size is always 8
/*
* This example demonstrates how to create and run a compare pattern operation.
*/
int main(int argc, char **argv)
{
dml_path_t execution_path = DML_PATH_SW;
// Get path from input argument
int parse_ret = parse_execution_path(argc, argv, &execution_path);
if (parse_ret != 0) {
return 1;
}
printf("Starting compare pattern job example.\n");
printf("Comparing data of size 1KB against pattern 0x0001020304050607.\n");
dml_job_t *dml_job_ptr = NULL;
uint32_t size = 0u;
uint8_t source [BUFFER_SIZE];
uint8_t pattern [PATTERN_SIZE] = {0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u};
for(int i = 0; i < BUFFER_SIZE; i++){
source[i] = pattern[i%8];
}
dml_status_t status = dml_get_job_size(execution_path, &size);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during getting job size.\n", status);
return 1;
}
dml_job_ptr = (dml_job_t *)malloc(size);
status = dml_init_job(execution_path, dml_job_ptr);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during job initialization.\n", status);
free(dml_job_ptr);
return 1;
}
dml_job_ptr->operation = DML_OP_COMPARE_PATTERN;
dml_job_ptr->source_first_ptr = source;
dml_job_ptr->source_length = BUFFER_SIZE;
for (uint8_t i = 0u; i < PATTERN_SIZE; i++)
{
dml_job_ptr->pattern[i] = pattern[i];
}
status = dml_execute_job(dml_job_ptr, DML_WAIT_MODE_BUSY_POLL);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during job execution.\n", status);
dml_finalize_job(dml_job_ptr);
free(dml_job_ptr);
return 1;
}
if(dml_job_ptr->result != 0){
printf("Error: Operation result is incorrect.\n");
dml_finalize_job(dml_job_ptr);
free(dml_job_ptr);
return 1;
}
status = dml_finalize_job(dml_job_ptr);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during job finalization.\n", status);
free(dml_job_ptr);
return 1;
}
free(dml_job_ptr);
printf("Job Completed Successfully.\n");
return 0;
}
compare#
/*******************************************************************************
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "dml/dml.h"
#include "examples_utils.h"
#define BUFFER_SIZE 1024u // 1 KB
/*
* This example demonstrates how to create and run a compare operation.
*/
int main(int argc, char **argv)
{
dml_path_t execution_path = DML_PATH_SW;
// Get path from input argument
int parse_ret = parse_execution_path(argc, argv, &execution_path);
if (parse_ret != 0) {
return 1;
}
printf("Starting compare job example.\n");
printf("Comparing equal memory regions of size 1KB.\n");
dml_job_t *dml_job_ptr = NULL;
uint32_t size = 0u;
uint8_t source1_ptr[BUFFER_SIZE];
uint8_t source2_ptr[BUFFER_SIZE];
for(int i = 0; i < BUFFER_SIZE; i++){
source1_ptr[i] = i % 256;
source2_ptr[i] = i % 256;
}
dml_status_t status = dml_get_job_size(execution_path, &size);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during getting job size.\n", status);
return 1;
}
dml_job_ptr = (dml_job_t *)malloc(size);
status = dml_init_job(execution_path, dml_job_ptr);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during job initialization.\n", status);
free(dml_job_ptr);
return 1;
}
dml_job_ptr->operation = DML_OP_COMPARE;
dml_job_ptr->source_first_ptr = source1_ptr;
dml_job_ptr->source_second_ptr = source2_ptr;
dml_job_ptr->source_length = BUFFER_SIZE;
status = dml_execute_job(dml_job_ptr, DML_WAIT_MODE_BUSY_POLL);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during job execution.\n", status);
dml_finalize_job(dml_job_ptr);
free(dml_job_ptr);
return 1;
}
if(dml_job_ptr->result != 0){
printf("Error: Operation result is incorrect.\n");
dml_finalize_job(dml_job_ptr);
free(dml_job_ptr);
return 1;
}
status = dml_finalize_job(dml_job_ptr);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during job finalization.\n", status);
free(dml_job_ptr);
return 1;
}
free(dml_job_ptr);
printf("Job Completed Successfully.\n");
return 0;
}
copy_crc#
/*******************************************************************************
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "dml/dml.h"
#include "examples_utils.h"
#define BUFFER_SIZE 1024 // 1 KB
/*
* This example demonstrates how to create and run a copy_crc operation.
*/
int main(int argc, char **argv)
{
dml_path_t execution_path = DML_PATH_SW;
// Get path from input argument
int parse_ret = parse_execution_path(argc, argv, &execution_path);
if (parse_ret != 0) {
return 1;
}
printf("Starting copy crc job example.\n");
printf("Copying and calculating CRC for region of size 1KB.\n");
dml_job_t *dml_job_ptr = NULL;
uint32_t size = 0u;
uint8_t source [BUFFER_SIZE];
uint8_t destination [BUFFER_SIZE];
for(int i = 0; i < BUFFER_SIZE; i++){
source[i] = i % 256;
}
dml_status_t status = dml_get_job_size(execution_path, &size);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during getting job size.\n", status);
return 1;
}
dml_job_ptr = (dml_job_t *)malloc(size);
status = dml_init_job(execution_path, dml_job_ptr);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during job initialization.\n", status);
free(dml_job_ptr);
return 1;
}
uint32_t crc = 1;
dml_job_ptr->operation = DML_OP_COPY_CRC;
dml_job_ptr->source_first_ptr = source;
dml_job_ptr->destination_first_ptr = destination;
dml_job_ptr->source_length = BUFFER_SIZE;
dml_job_ptr->crc_checksum_ptr = &crc;
dml_job_ptr->flags = DML_FLAG_CRC_READ_SEED; // read value from crc_checksum_ptr as crc seed
status = dml_execute_job(dml_job_ptr, DML_WAIT_MODE_BUSY_POLL);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during job execution.\n", status);
dml_finalize_job(dml_job_ptr);
free(dml_job_ptr);
return 1;
}
for(int i = 0; i < BUFFER_SIZE; i++){
if(destination[i] != source[i]){
printf("Error: Operation result is incorrect.\n");
dml_finalize_job(dml_job_ptr);
free(dml_job_ptr);
return 1;
}
}
printf("Calculated CRC is: 0x%08x\n", crc);
status = dml_finalize_job(dml_job_ptr);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during job finalization.\n", status);
free(dml_job_ptr);
return 1;
}
free(dml_job_ptr);
printf("Finished successfully.\n");
return 0;
}
crc#
/*******************************************************************************
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "dml/dml.h"
#include "examples_utils.h"
#define BUFFER_SIZE 1024 // 1 KB
/*
* This example demonstrates how to create and run a crc operation.
*/
int main(int argc, char **argv)
{
dml_path_t execution_path = DML_PATH_SW;
// Get path from input argument
int parse_ret = parse_execution_path(argc, argv, &execution_path);
if (parse_ret != 0) {
return 1;
}
printf("Starting CRC job example.\n");
printf("Calculating CRC for region of size 1KB.\n");
dml_job_t *dml_job_ptr = NULL;
uint32_t size = 0u;
uint8_t source [BUFFER_SIZE];
for(int i = 0; i < BUFFER_SIZE; i++){
source[i] = i % 256;
}
dml_status_t status = dml_get_job_size(execution_path, &size);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during getting job size.\n", status);
return 1;
}
dml_job_ptr = (dml_job_t *)malloc(size);
status = dml_init_job(execution_path, dml_job_ptr);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during job initialization.\n", status);
free(dml_job_ptr);
return 1;
}
uint32_t crc = 1;
dml_job_ptr->operation = DML_OP_CRC;
dml_job_ptr->source_first_ptr = source;
dml_job_ptr->source_length = BUFFER_SIZE;
dml_job_ptr->crc_checksum_ptr = &crc;
dml_job_ptr->flags = DML_FLAG_CRC_READ_SEED; // read value from crc_checksum_ptr as crc seed
status = dml_execute_job(dml_job_ptr, DML_WAIT_MODE_BUSY_POLL);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during job execution.\n", status);
dml_finalize_job(dml_job_ptr);
free(dml_job_ptr);
return 1;
}
printf("Calculated CRC is: 0x%08x\n", crc);
status = dml_finalize_job(dml_job_ptr);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during job finalization.\n", status);
free(dml_job_ptr);
return 1;
}
free(dml_job_ptr);
printf("Finished successfully.\n");
return 0;
}
delta#
/*******************************************************************************
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "dml/dml.h"
#include "examples_utils.h"
#define BUFFER_SIZE 1024 // 1 KB
#define DELTAS_PER_RECORD 8u // 8 Deltas Per record
#define DELTA_RECORD_SIZE 10u // Delta Record size 2 bytes (offset) + 8 bytes (Deltas)
#define DELTA_SIZE BUFFER_SIZE / DELTAS_PER_RECORD * DELTA_RECORD_SIZE // Deltas for 1 KB of data where 10 bytes is needed to store deltas for 8 bytes
/*
* This example demonstrates how to use the delta operations.
* It shows how to create and apply a delta.
*/
int main(int argc, char **argv)
{
dml_path_t execution_path = DML_PATH_SW;
// Get path from input argument
int parse_ret = parse_execution_path(argc, argv, &execution_path);
if (parse_ret != 0) {
return 1;
}
if (execution_path == DML_PATH_HW) {
printf("Delta operations are not supported on the hardware path.\n");
return 0;
}
printf("Starting delta job example.\n");
printf("Creating delta comparing data regions of size 1KB.\n");
dml_job_t *dml_job_ptr = NULL;
uint32_t size = 0u;
uint8_t source1 [BUFFER_SIZE];
uint8_t source2 [BUFFER_SIZE];
uint8_t delta [DELTA_SIZE];
for(int i = 0; i < BUFFER_SIZE; i++){
source1[i] = i % 256;
source2[i] = 0;
}
dml_status_t status = dml_get_job_size(execution_path, &size);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during getting job size.\n", status);
return 1;
}
dml_job_ptr = (dml_job_t *)malloc(size);
status = dml_init_job(execution_path, dml_job_ptr);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during job initialization.\n", status);
free(dml_job_ptr);
return 1;
}
dml_job_ptr->operation = DML_OP_DELTA_CREATE;
dml_job_ptr->source_first_ptr = source1;
dml_job_ptr->source_second_ptr = source2;
dml_job_ptr->destination_first_ptr = delta;
dml_job_ptr->source_length = BUFFER_SIZE;
dml_job_ptr->destination_length = DELTA_SIZE;
status = dml_execute_job(dml_job_ptr, DML_WAIT_MODE_BUSY_POLL);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during job execution.\n", status);
dml_finalize_job(dml_job_ptr);
free(dml_job_ptr);
return 1;
}
if(dml_job_ptr->result != 1){
printf("Error: Operation result is incorrect.\n");
dml_finalize_job(dml_job_ptr);
free(dml_job_ptr);
return 1;
}
printf("Completed creating delta.\n");
printf("Applying created delta to data region of size 1KB\n");
dml_job_ptr->operation = DML_OP_DELTA_APPLY;
dml_job_ptr->source_first_ptr = delta;
dml_job_ptr->source_length = dml_job_ptr->destination_length;
dml_job_ptr->destination_first_ptr = source1;
dml_job_ptr->destination_length = BUFFER_SIZE;
status = dml_execute_job(dml_job_ptr, DML_WAIT_MODE_BUSY_POLL);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during job execution.\n", status);
dml_finalize_job(dml_job_ptr);
free(dml_job_ptr);
return 1;
}
for(int i = 0; i < BUFFER_SIZE; i++){
if(source1[i] != source2[i]){
printf("Error: Operation result is incorrect.\n");
dml_finalize_job(dml_job_ptr);
free(dml_job_ptr);
return 1;
}
}
status = dml_finalize_job(dml_job_ptr);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during job finalization.\n", status);
free(dml_job_ptr);
return 1;
}
free(dml_job_ptr);
printf("Job Completed Successfully.\n");
return 0;
}
dualcast#
/*******************************************************************************
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "dml/dml.h"
#include "examples_utils.h"
#define BUFFER_SIZE 1024 // 1 KB
#define PADDING_SIZE 4096 // DML_OP_DUALCAST requirement "dst1 and dst2 address must bits 11:0 must be the same"
/*
* This example demonstrates how to create and run a dualcast operation.
*/
int main(int argc, char **argv)
{
dml_path_t execution_path = DML_PATH_SW;
// Get path from input argument
int parse_ret = parse_execution_path(argc, argv, &execution_path);
if (parse_ret != 0) {
return 1;
}
printf("Starting dualcast job example.\n");
printf("Dualcasting region of size 1KB.\n");
dml_job_t *dml_job_ptr = NULL;
uint32_t size = 0u;
uint8_t source [BUFFER_SIZE];
uint8_t destination [BUFFER_SIZE * 2 + PADDING_SIZE];
for(int i = 0; i < BUFFER_SIZE; i++){
source[i] = i % 256;
}
dml_status_t status = dml_get_job_size(execution_path, &size);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during getting job size.\n", status);
return 1;
}
dml_job_ptr = (dml_job_t *)malloc(size);
status = dml_init_job(execution_path, dml_job_ptr);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during job initialization.\n", status);
free(dml_job_ptr);
return 1;
}
dml_job_ptr->operation = DML_OP_DUALCAST;
dml_job_ptr->source_first_ptr = source;
dml_job_ptr->destination_first_ptr = destination;
dml_job_ptr->destination_second_ptr = destination+PADDING_SIZE;
dml_job_ptr->source_length = BUFFER_SIZE;
dml_job_ptr->destination_length = BUFFER_SIZE;
status = dml_execute_job(dml_job_ptr, DML_WAIT_MODE_BUSY_POLL);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during job execution.\n", status);
dml_finalize_job(dml_job_ptr);
free(dml_job_ptr);
return 1;
}
for(int i = 0; i < BUFFER_SIZE; i++){
if(destination[i] != source[i] || destination[i+PADDING_SIZE] != source[i]){
printf("Error: Operation result is incorrect.\n");
dml_finalize_job(dml_job_ptr);
free(dml_job_ptr);
return 1;
}
}
status = dml_finalize_job(dml_job_ptr);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during job finalization.\n", status);
free(dml_job_ptr);
return 1;
}
free(dml_job_ptr);
printf("Job Completed Successfully.\n");
return 0;
}
fill#
/*******************************************************************************
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "dml/dml.h"
#include "examples_utils.h"
#define BUFFER_SIZE 1024u // 1 KB
#define PATTERN_SIZE 8u // pattern size is always 8
/*
* This example demonstrates how to create and run a fill operation.
*/
int main(int argc, char **argv)
{
dml_path_t execution_path = DML_PATH_SW;
// Get path from input argument
int parse_ret = parse_execution_path(argc, argv, &execution_path);
if (parse_ret != 0) {
return 1;
}
printf("Starting fill job example.\n");
printf("Filling memory regions of size 1KB with pattern 0x0001020304050607.\n");
dml_job_t *dml_job_ptr = NULL;
uint32_t size = 0u;
uint8_t destination [BUFFER_SIZE];
uint8_t pattern [PATTERN_SIZE] = {0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u};
dml_status_t status = dml_get_job_size(execution_path, &size);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during getting job size.\n", status);
return 1;
}
dml_job_ptr = (dml_job_t *)malloc(size);
status = dml_init_job(execution_path, dml_job_ptr);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during job initialization.\n", status);
free(dml_job_ptr);
return 1;
}
dml_job_ptr->operation = DML_OP_FILL;
dml_job_ptr->destination_first_ptr = destination;
dml_job_ptr->destination_length = BUFFER_SIZE;
for (uint8_t i = 0u; i < PATTERN_SIZE; i++)
{
dml_job_ptr->pattern[i] = pattern[i];
}
status = dml_execute_job(dml_job_ptr, DML_WAIT_MODE_BUSY_POLL);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during job execution.\n", status);
free(dml_job_ptr);
return 1;
}
for(int i = 0; i < BUFFER_SIZE; i++){
if(destination[i] != pattern[i % 8]){
printf("Error: Operation result is incorrect.\n");
free(dml_job_ptr);
return 1;
}
}
status = dml_finalize_job(dml_job_ptr);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during job finalization.\n", status);
free(dml_job_ptr);
return 1;
}
free(dml_job_ptr);
printf("Job Completed Successfully.\n");
return 0;
}
mem_move#
/*******************************************************************************
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "dml/dml.h"
#include "examples_utils.h"
#define BUFFER_SIZE 1024 // 1 KB
/*
* This example demonstrates how to create and run a mem_move operation
*/
int main(int argc, char **argv)
{
dml_path_t execution_path = DML_PATH_SW;
// Get path from input argument
int parse_ret = parse_execution_path(argc, argv, &execution_path);
if (parse_ret != 0) {
return 1;
}
printf("Starting memory move job example.\n");
printf("Moving region of size 1KB.\n");
dml_job_t *dml_job_ptr = NULL;
uint32_t size = 0u;
uint8_t source [BUFFER_SIZE];
uint8_t destination [BUFFER_SIZE];
for(int i = 0; i < BUFFER_SIZE; i++){
source[i] = i % 256;
}
dml_status_t status = dml_get_job_size(execution_path, &size);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during getting job size.\n", status);
return 1;
}
dml_job_ptr = (dml_job_t *)malloc(size);
status = dml_init_job(execution_path, dml_job_ptr);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during job initialization.\n", status);
free(dml_job_ptr);
return 1;
}
dml_job_ptr->operation = DML_OP_MEM_MOVE;
dml_job_ptr->source_first_ptr = source;
dml_job_ptr->destination_first_ptr = destination;
dml_job_ptr->source_length = BUFFER_SIZE;
status = dml_execute_job(dml_job_ptr, DML_WAIT_MODE_BUSY_POLL);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during job execution.\n", status);
dml_finalize_job(dml_job_ptr);
free(dml_job_ptr);
return 1;
}
for(int i = 0; i < BUFFER_SIZE; i++){
if(destination[i] != source[i]){
printf("Error: Operation result is incorrect.\n");
dml_finalize_job(dml_job_ptr);
free(dml_job_ptr);
return 1;
}
}
status = dml_finalize_job(dml_job_ptr);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during job finalization.\n", status);
free(dml_job_ptr);
return 1;
}
free(dml_job_ptr);
printf("Job Completed Successfully.\n");
return 0;
}
batch#
/*******************************************************************************
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "dml/dml.h"
#include "examples_utils.h"
#define BUFFER_SIZE 1024 // 1 KB
#define PADDING_SIZE 4096 // DML_OP_DUALCAST requirement "dst1 and dst2 address bits 11:0 must be the same"
#define BATCH_COUNT 8u // 8 ops for this batch operation
#define PATTERN_SIZE 8u // pattern size is always 8
/*
* This example demonstrates how to create and run a batch operation with
* multiple operations including the nop operation used as a fence.
*/
int main(int argc, char **argv)
{
dml_path_t execution_path = DML_PATH_SW;
// Get path from input argument
int parse_ret = parse_execution_path(argc, argv, &execution_path);
if (parse_ret != 0) {
return 1;
}
printf("Starting batch job example.\n");
dml_job_t *dml_job_ptr = NULL;
uint32_t size = 0u;
uint8_t buffer_one [BUFFER_SIZE];
uint8_t buffer_two [BUFFER_SIZE];
uint8_t buffer_three [BUFFER_SIZE * 2 + PADDING_SIZE];
dml_status_t status = dml_get_job_size(execution_path, &size);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during getting job size.\n", status);
return 1;
}
dml_job_ptr = (dml_job_t *)malloc(size);
status = dml_init_job(execution_path, dml_job_ptr);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during job initialization.\n", status);
free(dml_job_ptr);
return 1;
}
uint32_t batch_buffer_length = 0u;
status = dml_get_batch_size(dml_job_ptr, BATCH_COUNT, &batch_buffer_length);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during getting batch size.\n", status);
goto cleanup;
}
uint8_t * batch_buffer_ptr = (uint8_t *) malloc(batch_buffer_length);
dml_job_ptr->operation = DML_OP_BATCH;
dml_job_ptr->destination_first_ptr = batch_buffer_ptr;
dml_job_ptr->destination_length = batch_buffer_length;
printf("Filling 1KB of data with 0x00ABCDEFABCDEF00 pattern\n");
uint8_t pattern [PATTERN_SIZE] = {0u, 1u, 2u, 3u, 4u, 5u, 6u, 7u};
status = dml_batch_set_fill_by_index(dml_job_ptr, 0, pattern, buffer_one, BUFFER_SIZE, DML_FLAG_PREFETCH_CACHE);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during setting of batch operation.\n", status);
goto cleanup;
}
printf("Fencing in batch to ensure fill completes before copying.\n");
status = dml_batch_set_nop_by_index(dml_job_ptr, 1, DML_FLAG_FENCE);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during setting of batch operation.\n", status);
goto cleanup;
}
printf("Moving 1KB of data\n");
status = dml_batch_set_mem_move_by_index(dml_job_ptr, 2, buffer_one, buffer_two, BUFFER_SIZE, DML_FLAG_PREFETCH_CACHE);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during setting of batch operation.\n", status);
goto cleanup;
}
printf("Dualcasting 1KB of data\n");
status = dml_batch_set_dualcast_by_index(dml_job_ptr, 3, buffer_one, buffer_three, buffer_three + PADDING_SIZE, BUFFER_SIZE, DML_FLAG_PREFETCH_CACHE);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during setting of batch operation.\n", status);
goto cleanup;
}
printf("Fencing in batch to ensure all moving completes.\n");
status = dml_batch_set_nop_by_index(dml_job_ptr, 4, DML_FLAG_FENCE);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during setting of batch operation.\n", status);
goto cleanup;
}
printf("Comparing 1KB of data to 0x00ABCDEFABCDEF00 pattern\n");
status = dml_batch_set_compare_pattern_by_index(dml_job_ptr, 5, buffer_three + PADDING_SIZE, pattern, BUFFER_SIZE, 0, 0x00);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during setting of batch operation.\n", status);
goto cleanup;
}
printf("Comparing two buffers of 1KB of data\n");
status = dml_batch_set_compare_by_index(dml_job_ptr, 6, buffer_three, buffer_two, BUFFER_SIZE, 0, 0x00);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during setting of batch operation.\n", status);
goto cleanup;
}
uint32_t crc_seed = 1;
printf("Calculating CRC buffers of 1KB of data\n");
status = dml_batch_set_crc_by_index(dml_job_ptr, 7, buffer_one, BUFFER_SIZE, &crc_seed, 0x00);
status = dml_execute_job(dml_job_ptr, DML_WAIT_MODE_BUSY_POLL);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during job execution.\n", status);
goto cleanup;
}
if(dml_job_ptr->result != 0){
printf("Error: Operation result is incorrect.\n");
goto cleanup;
}
uint32_t crc;
status = dml_batch_get_crc(dml_job_ptr, 7, &crc);
if (DML_STATUS_OK != status) {
printf("An error (%u) occured during getting crc result.\n", status);
goto cleanup;
}
printf("CRC result: 0x%08X\n", crc);
status = dml_finalize_job(dml_job_ptr);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during job finalization.\n", status);
free(dml_job_ptr);
return 1;
}
free(dml_job_ptr);
printf("Job Completed Successfully.\n");
return 0;
cleanup:
dml_finalize_job(dml_job_ptr);
free(dml_job_ptr);
return 1;
}
batch#
/*******************************************************************************
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "dml/dml.h"
#include "examples_utils.h"
#define BUFFER_SIZE 4096 // 4 KB
#define PROTECTED_SIZE 4104 // 4 KB data with DIF
/*
* This example demonstrates how to use the DIF operations.
* It shows how to insert, update, check, and strip a DIF.
*/
int main(int argc, char **argv)
{
dml_path_t execution_path = DML_PATH_SW;
// Get path from input argument
int parse_ret = parse_execution_path(argc, argv, &execution_path);
if (parse_ret != 0) {
return 1;
}
printf("Starting DIF job example.\n");
printf("Inserting DIF into data region of size 4KB.\n");
dml_job_t *dml_job_ptr = NULL;
uint32_t size = 0u;
uint8_t data [PROTECTED_SIZE]; // Same size is used because of DML_STATUS_DIF_STRIP_ADJACENT_ERROR
uint8_t protected_data [PROTECTED_SIZE];
uint8_t updated_protected_data [PROTECTED_SIZE];
for(int i = 0; i < BUFFER_SIZE; i++){
data[i] = i % 256;
}
dml_status_t status = dml_get_job_size(execution_path, &size);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during getting job size.\n", status);
return 1;
}
dml_job_ptr = (dml_job_t *)malloc(size);
status = dml_init_job(execution_path, dml_job_ptr);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during job initialization.\n", status);
free(dml_job_ptr);
return 1;
}
dml_job_ptr->operation = DML_OP_DIF_INSERT;
dml_job_ptr->source_first_ptr = data;
dml_job_ptr->source_length = BUFFER_SIZE;
dml_job_ptr->destination_first_ptr = protected_data;
dml_job_ptr->destination_length = PROTECTED_SIZE;
dml_job_ptr->dif_config.block_size = DML_DIF_BLOCK_SIZE_4096;
dml_job_ptr->dif_config.destination_application_tag_mask = 0x0u;
dml_job_ptr->dif_config.destination_application_tag_seed = 0x0100;
dml_job_ptr->dif_config.destination_reference_tag_seed = 0u;
dml_job_ptr->dif_config.flags = DML_DIF_FLAG_INVERT_CRC_SEED
| DML_DIF_FLAG_INVERT_CRC_RESULT
| DML_DIF_FLAG_DST_INC_APP_TAG
| DML_DIF_FLAG_DST_FIX_REF_TAG;
status = dml_execute_job(dml_job_ptr, DML_WAIT_MODE_BUSY_POLL);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during job execution.\n", status);
dml_finalize_job(dml_job_ptr);
free(dml_job_ptr);
return 1;
}
if(dml_job_ptr->result != 0){
printf("Error: Operation result is incorrect.\n");
dml_finalize_job(dml_job_ptr);
free(dml_job_ptr);
return 1;
}
printf("Completed inserting DIF.\n");
printf("Checking DIF on protected region of size 4104 bytes\n");
dml_job_ptr->operation = DML_OP_DIF_CHECK;
dml_job_ptr->source_first_ptr = protected_data;
dml_job_ptr->source_length = PROTECTED_SIZE;
dml_job_ptr->dif_config.block_size = DML_DIF_BLOCK_SIZE_4096;
dml_job_ptr->dif_config.source_application_tag_mask = 0x0u;
dml_job_ptr->dif_config.source_application_tag_seed = 0x0100;
dml_job_ptr->dif_config.source_reference_tag_seed = 0u;
dml_job_ptr->dif_config.flags = DML_DIF_FLAG_INVERT_CRC_SEED
| DML_DIF_FLAG_INVERT_CRC_RESULT
| DML_DIF_FLAG_DST_INC_APP_TAG
| DML_DIF_FLAG_DST_FIX_REF_TAG;
status = dml_execute_job(dml_job_ptr, DML_WAIT_MODE_BUSY_POLL);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during job execution.\n", status);
dml_finalize_job(dml_job_ptr);
free(dml_job_ptr);
return 1;
}
if(dml_job_ptr->result != 0){
printf("Error: Operation result is incorrect.\n");
dml_finalize_job(dml_job_ptr);
free(dml_job_ptr);
return 1;
}
printf("Completed checking DIF.\n");
printf("Updating DIF on protected region of size 4104 bytes\n");
dml_job_ptr->operation = DML_OP_DIF_UPDATE;
dml_job_ptr->source_first_ptr = protected_data;
dml_job_ptr->source_length = PROTECTED_SIZE;
dml_job_ptr->destination_first_ptr = updated_protected_data;
dml_job_ptr->destination_length = PROTECTED_SIZE;
dml_job_ptr->dif_config.block_size = DML_DIF_BLOCK_SIZE_4096;
dml_job_ptr->dif_config.source_application_tag_mask = 0x0u;
dml_job_ptr->dif_config.source_application_tag_seed = 0x0100;
dml_job_ptr->dif_config.source_reference_tag_seed = 0u;
dml_job_ptr->dif_config.destination_application_tag_mask = 0xFF00u;
dml_job_ptr->dif_config.destination_application_tag_seed = 0x0200u;
dml_job_ptr->dif_config.destination_reference_tag_seed = 0u;
dml_job_ptr->dif_config.flags = DML_DIF_FLAG_INVERT_CRC_SEED
| DML_DIF_FLAG_INVERT_CRC_RESULT
| DML_DIF_FLAG_SRC_GUARD_CHECK_DISABLE
| DML_DIF_FLAG_SRC_REF_TAG_CHECK_DISABLE
| DML_DIF_FLAG_DST_INC_APP_TAG
| DML_DIF_FLAG_DST_FIX_REF_TAG;
status = dml_execute_job(dml_job_ptr, DML_WAIT_MODE_BUSY_POLL);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during job execution.\n", status);
dml_finalize_job(dml_job_ptr);
free(dml_job_ptr);
return 1;
}
if(dml_job_ptr->result != 0){
printf("Error: Operation result is incorrect.\n");
dml_finalize_job(dml_job_ptr);
free(dml_job_ptr);
return 1;
}
printf("Completed updating DIF.\n");
printf("Stripping DIF from protected region of size 4104 bytes\n");
dml_job_ptr->operation = DML_OP_DIF_STRIP;
dml_job_ptr->source_first_ptr = updated_protected_data;
dml_job_ptr->source_length = PROTECTED_SIZE;
dml_job_ptr->destination_first_ptr = data;
dml_job_ptr->destination_length = BUFFER_SIZE;
dml_job_ptr->dif_config.block_size = DML_DIF_BLOCK_SIZE_4096;
dml_job_ptr->dif_config.source_application_tag_mask = 0xFF00u;
dml_job_ptr->dif_config.source_application_tag_seed = 0x0200u;
dml_job_ptr->dif_config.source_reference_tag_seed = 0u;
dml_job_ptr->dif_config.flags = DML_DIF_FLAG_INVERT_CRC_SEED
| DML_DIF_FLAG_INVERT_CRC_RESULT
| DML_DIF_FLAG_DST_INC_APP_TAG
| DML_DIF_FLAG_DST_FIX_REF_TAG;
status = dml_execute_job(dml_job_ptr, DML_WAIT_MODE_BUSY_POLL);
if (DML_STATUS_OK != status) {
printf("An error %i occurred during job execution.\n", status);
dml_finalize_job(dml_job_ptr);
free(dml_job_ptr);
return 1;
}
for(int i = 0; i < BUFFER_SIZE; i++){
if(data[i] != i % 256){
printf("Error: Operation result is incorrect.\n");
dml_finalize_job(dml_job_ptr);
free(dml_job_ptr);
return 1;
}
}
status = dml_finalize_job(dml_job_ptr);
if (DML_STATUS_OK != status) {
printf("An error (%u) occurred during job finalization.\n", status);
free(dml_job_ptr);
return 1;
}
free(dml_job_ptr);
printf("Job Completed Successfully.\n");
return 0;
}
Multi-Socket Library Usage#
This sample shows how to utilize several sockets on the system using manual numa_id
setting in the dml_job_t
structure. Thus, the memory_move
operation can be applied
to one data array using several sockets at the same time.
/*******************************************************************************
* Copyright (C) 2022 Intel Corporation
*
* SPDX-License-Identifier: MIT
******************************************************************************/
#include <dml/dml.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SOCKET_COUNT 4u
// 1 MB per socket
static const uint32_t transfer_size = 1024u * 1024 * SOCKET_COUNT;
int main()
{
int exit_status = EXIT_SUCCESS;
dml_job_t *jobs = NULL;
uint8_t *src = NULL;
uint8_t *dst = NULL;
printf("Starting example for multi-socket memory move:\n");
uint32_t job_size = 0;
dml_status_t status = dml_get_job_size(DML_PATH_AUTO, &job_size);
if (status != DML_STATUS_OK)
{
printf("Failed to get job size\n");
exit_status = EXIT_FAILURE;
goto finish;
}
jobs = (dml_job_t*)malloc(job_size * SOCKET_COUNT);
if (jobs == NULL)
{
printf("Failed to allocate memory for jobs\n");
exit_status = EXIT_FAILURE;
goto finish;
}
for (uint32_t i = 0; i < SOCKET_COUNT; ++i)
{
status = dml_init_job(DML_PATH_AUTO, (dml_job_t*)((uint8_t*)jobs + (job_size * i)));
if (status != DML_STATUS_OK)
{
printf("Failed to initialize job %d\n", i);
exit_status = EXIT_FAILURE;
goto finish;
}
}
src = (uint8_t*)malloc(transfer_size);
if (src == NULL)
{
exit_status = EXIT_FAILURE;
printf("Failed to allocate source memory\n");
goto cleanup;
}
dst = (uint8_t*)malloc(transfer_size);
if (dst == NULL)
{
exit_status = EXIT_FAILURE;
printf("Failed to allocate destination memory\n");
goto cleanup;
}
memset(src, 1, transfer_size);
memset(dst, 0, transfer_size);
for (uint32_t i = 0; i < SOCKET_COUNT; ++i)
{
const uint32_t chunk_size = transfer_size / SOCKET_COUNT;
dml_job_t* current_job = (dml_job_t*)((uint8_t*)jobs + (job_size * i));
current_job->operation = DML_OP_MEM_MOVE;
current_job->source_first_ptr = src + (chunk_size * i);
current_job->destination_first_ptr = dst + (chunk_size * i);
current_job->source_length = chunk_size;
current_job->flags = DML_FLAG_PREFETCH_CACHE;
current_job->numa_id = i;
}
for (uint32_t i = 0; i < SOCKET_COUNT; ++i)
{
status = dml_submit_job((dml_job_t*)((uint8_t*)jobs + (job_size * i)));
if (status != DML_STATUS_OK)
{
printf("Failed to submit to node %d", i);
exit_status = EXIT_FAILURE;
goto cleanup;
}
}
for (uint32_t i = 0; i < SOCKET_COUNT; ++i)
{
status = dml_wait_job((dml_job_t*)((uint8_t*)jobs + (job_size * i)), DML_WAIT_MODE_BUSY_POLL);
if (status != DML_STATUS_OK)
{
printf("Operation status is %d", status);
exit_status = EXIT_FAILURE;
goto cleanup;
}
}
if (memcmp(src, dst, transfer_size) != 0)
{
printf("Fail!");
exit_status = EXIT_FAILURE;
}
else
{
printf("Success!");
exit_status = EXIT_SUCCESS;
}
cleanup:
for (uint32_t i = 0; i < SOCKET_COUNT; ++i)
{
status = dml_finalize_job((dml_job_t*)((uint8_t*)jobs + (job_size * i)));
if (status != DML_STATUS_OK)
{
printf("Failed to finalize job, status is %d", status);
exit_status = EXIT_FAILURE;
}
}
finish:
if (jobs)
{
free(jobs);
}
if (src)
{
free(src);
}
if (dst)
{
free(dst);
}
return exit_status;
}
High-level C++ API Examples#
cache_flush#
/*******************************************************************************
* Copyright (C) 2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
******************************************************************************/
#include <dml/dml.hpp>
#include <numeric>
#include <vector>
#include <iostream>
constexpr auto size = 1024u; // 1 KB
template <typename path>
int execute_cache_flush(){
std::cout << "Starting dml::cache_flush example..." << std::endl;
std::cout << "Flush 1KB of data from the cache to the memory..." << std::endl;
// Prepare data
auto dst = std::vector<std::uint8_t>(size, 0u);
// Run operation
auto result = dml::execute<path>(dml::cache_flush, dml::make_view(dst));
// Check result
if (result.status == dml::status_code::ok) {
std::cout << "Finished successfully" << std::endl;
return 0;
}
else {
std::cout << "Failure occurred" << std::endl;
return -1;
}
return 0;
}
int main(int argc, char **argv)
{
if (argc < 2) {
std::cout << "Missing the execution path as the first parameter."
<< "Use hardware_path, software_path or automatic_path." << std::endl;
return 1;
}
std::string path = argv[1];
if (path == "hardware_path") {
std::cout << "Executing using dml::hardware path" << std::endl;
return execute_cache_flush<dml::hardware>();
}
else if (path == "software_path") {
std::cout << "Executing using dml::software path" << std::endl;
return execute_cache_flush<dml::software>();
}
else if (path == "auto_path") {
std::cout << "Executing using dml::automatic path" << std::endl;
return execute_cache_flush<dml::automatic>();
}
else {
std::cout << "Unrecognized value for parameter."
<< "Use hardware_path, software_path or automatic_path." << std::endl;
return 1;
}
}
compare_pattern#
/*******************************************************************************
* Copyright (C) 2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
******************************************************************************/
#include <dml/dml.hpp>
#include <iostream>
#include <numeric>
#include <vector>
constexpr auto size = 1024u; // 1 KB
template <typename path>
int execute_compare_pattern() {
std::cout << "Starting dml::compare_pattern example..." << std::endl;
std::cout << "Compare 1KB memory region with a 0x00ABCDEFABCDEF00 pattern..." << std::endl;
// Prepare data
auto pattern = 0x00ABCDEFABCDEF00;
auto src = std::vector<std::uint8_t>(size);
auto src_data = reinterpret_cast<std::uint64_t *>(src.data());
std::fill_n(src_data, size / sizeof(std::uint64_t), pattern);
// Run operation
auto result = dml::execute<path>(dml::compare_pattern, pattern, dml::make_view(src));
// Check result
if (result.status == dml::status_code::ok) {
std::cout << "Finished successfully." << std::endl;
}
else {
std::cout << "Failure occurred." << std::endl;
return -1;
}
if (result.result != dml::comparison_result::equal) {
std::cout << "Operation result is incorrect" << std::endl;
return -1;
}
return 0;
}
int main(int argc, char **argv)
{
if (argc < 2) {
std::cout << "Missing the execution path as the first parameter."
<< "Use hardware_path, software_path or automatic_path." << std::endl;
return 1;
}
std::string path = argv[1];
if (path == "hardware_path") {
std::cout << "Executing using dml::hardware path" << std::endl;
return execute_compare_pattern<dml::hardware>();
}
else if (path == "software_path") {
std::cout << "Executing using dml::software path" << std::endl;
return execute_compare_pattern<dml::software>();
}
else if (path == "auto_path") {
std::cout << "Executing using dml::automatic path" << std::endl;
return execute_compare_pattern<dml::automatic>();
}
else {
std::cout << "Unrecognized value for parameter."
<< "Use hardware_path, software_path or automatic_path." << std::endl;
return 1;
}
}
compare#
/*******************************************************************************
* Copyright (C) 2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
******************************************************************************/
#include <dml/dml.hpp>
#include <numeric>
#include <vector>
#include <iostream>
constexpr auto size = 1024u; // 1 KB
template <typename path>
int execute_compare(){
std::cout << "Starting dml::compare example..." << std::endl;
std::cout << "Compare equal memory regions with size of 1KB..." << std::endl;
// Prepare data
auto src1 = std::vector<std::uint8_t>(size);
std::iota(src1.begin(), src1.end(), 0u);
auto src2 = src1;
// Run operation
auto result = dml::execute<path>(dml::compare, dml::make_view(src1), dml::make_view(src2));
// Check result
if (result.status == dml::status_code::ok) {
std::cout << "Finished successfully" << std::endl;
}
else {
std::cout << "Failure occurred" << std::endl;
return -1;
}
if (result.result != dml::comparison_result::equal) {
std::cout << "Operation result is incorrect" << std::endl;
return -1;
}
return 0;
}
int main(int argc, char **argv)
{
if (argc < 2) {
std::cout << "Missing the execution path as the first parameter."
<< "Use hardware_path, software_path or automatic_path." << std::endl;
return 1;
}
std::string path = argv[1];
if (path == "hardware_path") {
std::cout << "Executing using dml::hardware path" << std::endl;
return execute_compare<dml::hardware>();
}
else if (path == "software_path") {
std::cout << "Executing using dml::software path" << std::endl;
return execute_compare<dml::software>();
}
else if (path == "auto_path") {
std::cout << "Executing using dml::automatic path" << std::endl;
return execute_compare<dml::automatic>();
}
else {
std::cout << "Unrecognized value for parameter."
<< "Use hardware_path, software_path or automatic_path." << std::endl;
return 1;
}
}
copy_crc#
/*******************************************************************************
* Copyright (C) 2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
******************************************************************************/
#include <dml/dml.hpp>
#include <iostream>
#include <string>
#include <vector>
constexpr auto string = "Calculate CRC value for this string...\n";
template <typename path>
int execute_copy_crc(){
std::cout << "Starting dml::copy_crc example...\n";
std::cout << string;
// Prepare data
auto crc_seed = std::uint32_t(0u);
auto src = std::basic_string<std::uint8_t>(reinterpret_cast<const std::uint8_t *>(string));
auto dst = std::basic_string<std::uint8_t>(src.size(), '0');
// Run operation
auto result = dml::execute<path>(dml::copy_crc, dml::make_view(src), dml::make_view(dst), crc_seed);
// Check result
if (result.status == dml::status_code::ok) {
std::cout << "Finished successfully. Calculated CRC is: 0x" << std::hex << result.crc_value << std::dec << std::endl;
}
else {
std::cout << "Failure occurred." << std::endl;
return -1;
}
if (src != dst) {
std::cout << "Operation result is incorrect" << std::endl;
return -1;
}
return 0;
}
int main(int argc, char **argv)
{
if (argc < 2) {
std::cout << "Missing the execution path as the first parameter."
<< "Use hardware_path, software_path or automatic_path." << std::endl;
return 1;
}
std::string path = argv[1];
if (path == "hardware_path") {
std::cout << "Executing using dml::hardware path" << std::endl;
return execute_copy_crc<dml::hardware>();
}
else if (path == "software_path") {
std::cout << "Executing using dml::software path" << std::endl;
return execute_copy_crc<dml::software>();
}
else if (path == "auto_path") {
std::cout << "Executing using dml::automatic path" << std::endl;
return execute_copy_crc<dml::automatic>();
}
else {
std::cout << "Unrecognized value for parameter."
<< "Use hardware_path, software_path or automatic_path." << std::endl;
return 1;
}
}
crc#
/*******************************************************************************
* Copyright (C) 2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
******************************************************************************/
#include <dml/dml.hpp>
#include <iostream>
#include <string>
#include <vector>
constexpr auto string = "Calculate CRC value for this string...\n";
template <typename path>
int execute_crc() {
std::cout << "Starting dml::crc example...\n";
std::cout << string;
// Prepare data
auto crc_seed = std::uint32_t(0u);
auto src = std::basic_string<std::uint8_t>(reinterpret_cast<const std::uint8_t *>(string));
// Run operation
auto result = dml::execute<path>(dml::crc, dml::make_view(src), crc_seed);
// Check result
if (result.status == dml::status_code::ok) {
std::cout << "Finished successfully. Calculated CRC is: 0x" << std::hex << result.crc_value << std::dec << std::endl;
}
else {
std::cout << "Failure occurred." << std::endl;
return -1;
}
return 0;
}
int main(int argc, char **argv)
{
if (argc < 2) {
std::cout << "Missing the execution path as the first parameter."
<< "Use hardware_path, software_path or automatic_path." << std::endl;
return 1;
}
std::string path = argv[1];
if (path == "hardware_path") {
std::cout << "Executing using dml::hardware path" << std::endl;
return execute_crc<dml::hardware>();
}
else if (path == "software_path") {
std::cout << "Executing using dml::software path" << std::endl;
return execute_crc<dml::software>();
}
else if (path == "auto_path") {
std::cout << "Executing using dml::automatic path" << std::endl;
return execute_crc<dml::automatic>();
}
else {
std::cout << "Unrecognized value for parameter."
<< "Use hardware_path, software_path or automatic_path." << std::endl;
return 1;
}
}
delta#
/*******************************************************************************
* Copyright (C) 2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
******************************************************************************/
#include <dml/dml.hpp>
#include <iostream>
#include <numeric>
#include <vector>
constexpr auto size = 1024u; // 1 KB
constexpr auto delta_record_size = size * 10u / 8u;
template <typename path>
int execute_delta() {
std::cout << "Starting dml::create_delta and dml::apply_delta example..." << std::endl;
std::cout << "Create delta record of two 1KB memory_regions..." << std::endl;
// Prepare data
auto src1 = std::vector<std::uint8_t>(size);
std::iota(src1.begin(), src1.end(), 0u);
auto src2 = std::vector<std::uint8_t>(size);
std::iota(src2.begin(), src2.end(), 1u);
auto delta = std::vector<std::uint8_t>(delta_record_size, 0u);
// Run operation
auto create_result = dml::execute<path>(
dml::create_delta, dml::make_view(src1), dml::make_view(src2), dml::make_view(delta));
// Check result
if (create_result.status == dml::status_code::ok) {
std::cout << "Done. Next step..." << std::endl;
}
else {
std::cout << "Failure occurred!" << std::endl;
return -1;
}
std::cout << "Apply delta record to the first 1KB memory_region..." << std::endl;
auto apply_result = dml::execute<path>(
dml::apply_delta, dml::make_view(delta), dml::make_view(src1), create_result);
// Check result
if (apply_result.status == dml::status_code::ok) {
std::cout << "Finished successfully!" << std::endl;
}
else {
std::cout << "Failure occurred!" << std::endl;
return -1;
}
if (src1 != src2) {
std::cout << "But operation was done wrongly." << std::endl;
return -1;
}
return 0;
}
int main(int argc, char **argv)
{
if (argc < 2) {
std::cout << "Missing the execution path as the first parameter."
<< "Use hardware_path, software_path or automatic_path." << std::endl;
return 1;
}
std::string path = argv[1];
if (path == "hardware_path") {
std::cout << "Executing using dml::hardware path is currently not supported for Delta Record operations" << std::endl;
return 0;
}
else if (path == "software_path") {
std::cout << "Executing using dml::software path" << std::endl;
return execute_delta<dml::software>();
}
else if (path == "auto_path") {
std::cout << "Executing using dml::automatic path" << std::endl;
return execute_delta<dml::automatic>();
}
else {
std::cout << "Unrecognized value for parameter."
<< "Use hardware_path, software_path or automatic_path." << std::endl;
return 1;
}
}
dualcast#
/*******************************************************************************
* Copyright (C) 2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
******************************************************************************/
#include <dml/dml.hpp>
#include <iostream>
#include <numeric>
#include <vector>
constexpr auto size = 1024u; // 1 KB
constexpr auto padding = 0x1000; // dml::dualcast requirement, see documentation
template <typename path>
int execute_dualcast() {
std::cout << "Starting dml::dualcast example..." << std::endl;
std::cout << "Copy 1KB of data from source into two destinations..." << std::endl;
// Prepare data
auto src = std::vector<std::uint8_t>(size);
std::iota(src.begin(), src.end(), 0u);
auto dst_data = std::vector<std::uint8_t>(size + padding, 0u);
auto dst1_ptr = dst_data.data();
auto dst2_ptr = dst1_ptr + padding;
// Run operation
auto result = dml::execute<path>(
dml::dualcast, dml::make_view(src), dml::make_view(dst1_ptr, size), dml::make_view(dst2_ptr, size));
// Check result
if (result.status == dml::status_code::ok) {
std::cout << "Finished successfully." << std::endl;
}
else {
std::cout << "Failure occurred." << std::endl;
return -1;
}
if (src != std::vector<uint8_t>(dst1_ptr, dst1_ptr + size) || src != std::vector<uint8_t>(dst2_ptr, dst2_ptr + size)) {
std::cout << "Operation result is incorrect." << std::endl;
return -1;
}
return 0;
}
int main(int argc, char **argv)
{
if (argc < 2) {
std::cout << "Missing the execution path as the first parameter."
<< "Use hardware_path, software_path or automatic_path." << std::endl;
return 1;
}
std::string path = argv[1];
if (path == "hardware_path") {
std::cout << "Executing using dml::hardware path" << std::endl;
return execute_dualcast<dml::hardware>();
}
else if (path == "software_path") {
std::cout << "Executing using dml::software path" << std::endl;
return execute_dualcast<dml::software>();
}
else if (path == "auto_path") {
std::cout << "Executing using dml::automatic path" << std::endl;
return execute_dualcast<dml::automatic>();
}
else {
std::cout << "Unrecognized value for parameter."
<< "Use hardware_path, software_path or automatic_path." << std::endl;
return 1;
}
}
fill#
/*******************************************************************************
* Copyright (C) 2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
******************************************************************************/
#include <dml/dml.hpp>
#include <vector>
#include <algorithm>
#include <iostream>
constexpr auto size = 1024u; // 1 KB
template <typename path>
int execute_fill() {
std::cout << "Starting dml::fill example..." << std::endl;;
std::cout << "Fill 1KB of data with a 0x00ABCDEFABCDEF00 pattern" << std::endl;;
// Prepare data
auto pattern = 0x00ABCDEFABCDEF00;
auto dst = std::vector<std::uint8_t>(size, 0u);
// Run operation
auto result = dml::execute<path>(dml::fill, pattern, dml::make_view(dst));
// Check result
if (result.status == dml::status_code::ok) {
std::cout << "Finished successfully." << std::endl;;
}
else {
std::cout << "Failure occurred." << std::endl;;
return -1;
}
auto ref = std::vector<std::uint8_t>(size);
auto ref_data = reinterpret_cast<std::uint64_t*>(ref.data());
std::fill_n(ref_data, size / sizeof(std::uint64_t), pattern);
if (ref != dst)
{
std::cout << "Operation result is incorrect" << std::endl;
return -1;
}
return 0;
}
int main(int argc, char **argv)
{
if (argc < 2) {
std::cout << "Missing the execution path as the first parameter."
<< "Use hardware_path, software_path or automatic_path." << std::endl;
return 1;
}
std::string path = argv[1];
if (path == "hardware_path") {
std::cout << "Executing using dml::hardware path" << std::endl;
return execute_fill<dml::hardware>();
}
else if (path == "software_path") {
std::cout << "Executing using dml::software path" << std::endl;
return execute_fill<dml::software>();
}
else if (path == "auto_path") {
std::cout << "Executing using dml::automatic path" << std::endl;
return execute_fill<dml::automatic>();
}
else {
std::cout << "Unrecognized value for parameter."
<< "Use hardware_path, software_path or automatic_path." << std::endl;
return 1;
}
}
mem_move#
/*******************************************************************************
* Copyright (C) 2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
******************************************************************************/
#include <dml/dml.hpp>
#include <numeric>
#include <vector>
#include <iostream>
constexpr auto size = 1024u; // 1 KB
template <typename path>
int execute_mem_move() {
std::cout << "Starting dml::mem_move example..." << std::endl;
std::cout << "Copy 1KB of data from source into destination..." << std::endl;
// Prepare data
auto src = std::vector<std::uint8_t>(size);
std::iota(src.begin(), src.end(), 0u);
auto dst = std::vector<std::uint8_t>(size, 0u);
// Run operation
auto result = dml::execute<path>(dml::mem_move, dml::make_view(src), dml::make_view(dst));
// Check result
if (result.status == dml::status_code::ok) {
std::cout << "Finished successfully." << std::endl;
}
else {
std::cout << "Failure occurred." << std::endl;
return -1;
}
if (src != dst) {
std::cout << "Operation result is incorrect" << std::endl;
return -1;
}
return 0;
}
int main(int argc, char **argv)
{
if (argc < 2) {
std::cout << "Missing the execution path as the first parameter."
<< "Use hardware_path, software_path or automatic_path." << std::endl;
return 1;
}
std::string path = argv[1];
if (path == "hardware_path") {
std::cout << "Executing using dml::hardware path" << std::endl;
return execute_mem_move<dml::hardware>();
}
else if (path == "software_path") {
std::cout << "Executing using dml::software path" << std::endl;
return execute_mem_move<dml::software>();
}
else if (path == "auto_path") {
std::cout << "Executing using dml::automatic path" << std::endl;
return execute_mem_move<dml::automatic>();
}
else {
std::cout << "Unrecognized value for parameter."
<< "Use hardware_path, software_path or automatic_path." << std::endl;
return 1;
}
}
batch#
/*******************************************************************************
* Copyright (C) 2023 Intel Corporation
*
* SPDX-License-Identifier: MIT
******************************************************************************/
#include <dml/dml.hpp>
#include <numeric>
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
constexpr auto size = 1024u; // 1 KB
constexpr auto delta_record_size = size * 10u / 8u;
template <typename path>
int execute_batch() {
std::cout << "Starting dml::batch example..." << std::endl;
// Prepare data
auto pattern = 0x00ABCDEFABCDEF00;
auto src = std::vector<std::uint8_t>(size);
auto dst1 = std::vector<std::uint8_t>(size, 0u);
auto dst2 = std::vector<std::uint8_t>(size, 0u);
auto dst3 = std::vector<std::uint8_t>(size);
auto delta = std::vector<std::uint8_t>(delta_record_size, 0u);
constexpr auto count = 7u;
auto sequence = dml::sequence(count, std::allocator<dml::byte_t>());
std::cout << "Fill 1KB of data with a 0x00ABCDEFABCDEF00 pattern" << std::endl;
sequence.add(dml::fill, pattern, dml::make_view(src));
std::cout << "Add No-op to batch to ensure fill completes before copying..." << std::endl;
sequence.add(dml::nop);
std::cout << "Copy 1KB of data from source into destination..." << std::endl;
sequence.add(dml::mem_move, dml::make_view(src), dml::make_view(dst1));
std::cout << "Copy 1KB of data from source1 into two destinations..." << std::endl;
sequence.add(dml::dualcast, dml::make_view(src), dml::make_view(dst2), dml::make_view(dst3));
std::cout << "Add No-op to batch to ensure all copies complete..." << std::endl;
sequence.add(dml::nop);
std::cout << "Compare 1KB memory region with a 0x00ABCDEFABCDEF00 pattern..." << std::endl;
sequence.add(dml::compare_pattern, pattern, dml::make_view(dst1));
std::cout << "Compare equal memory regions with size of 1KB..." << std::endl;
sequence.add(dml::compare, dml::make_view(dst2), dml::make_view(dst3));
// Run operation
auto result = dml::execute<path>(dml::batch, sequence);
// Check result
if (result.status == dml::status_code::ok) {
std::cout << "Finished successfully." << std::endl;;
}
else {
std::cout << "Failure occurred." << std::endl;;
return -1;
}
return 0;
}
int main(int argc, char **argv)
{
if (argc < 2) {
std::cout << "Missing the execution path as the first parameter."
<< "Use hardware_path, software_path or automatic_path." << std::endl;
return 1;
}
std::string path = argv[1];
if (path == "hardware_path") {
std::cout << "Executing using dml::hardware path" << std::endl;
return execute_batch<dml::hardware>();
}
else if (path == "software_path") {
std::cout << "Executing using dml::software path" << std::endl;
return execute_batch<dml::software>();
}
else if (path == "auto_path") {
std::cout << "Executing using dml::automatic path" << std::endl;
return execute_batch<dml::automatic>();
}
else {
std::cout << "Unrecognized value for parameter."
<< "Use hardware_path, software_path or automatic_path." << std::endl;
return 1;
}
}
Multi-Socket Library Usage#
This sample shows how to utilize several sockets on the system.
Thus, the memory_move
operation can be applied
to one data array using several sockets at the same time.
/*******************************************************************************
* Copyright (C) 2022 Intel Corporation
*
* SPDX-License-Identifier: MIT
******************************************************************************/
#include <dml/dml.hpp>
#include <iostream>
#include <vector>
constexpr auto socket_count = 4u;
// 1 MB per socket
constexpr auto transfer_size = 1024u * 1024 * socket_count;
int main()
{
std::cout << "Starting example for multi-socket memory move:\n";
auto src = std::vector<std::uint8_t>(transfer_size, 1);
auto dst = std::vector<std::uint8_t>(transfer_size, 0);
auto handlers =
std::vector<dml::handler<dml::mem_move_operation, std::allocator<std::uint8_t>>>();
handlers.reserve(socket_count);
auto results = std::vector<dml::mem_move_result>();
for (auto i = 0u; i < socket_count; ++i)
{
auto execution_interface = dml::default_execution_interface<dml::automatic>();
handlers.emplace_back(dml::submit<dml::automatic>(dml::mem_move,
dml::make_view(src),
dml::make_view(dst),
execution_interface,
i));
}
for (auto& handler : handlers)
{
results.emplace_back(handler.get());
}
if (src != dst)
{
std::cout << "Fail!\n";
return EXIT_FAILURE;
}
else
{
std::cout << "Success!\n";
return EXIT_SUCCESS;
}
}