Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ int main()

// TODO: allocate an array of 100 doubles using the HOST allocator

std::cout << "Address of data: " << data << std::endl;
// TODO: use the resource manager to memset your array to 0

// TODO: uncomment this print statement
//std::cout << "Allocated " << (100 * sizeof(double)) << " bytes and set to "
// << data[0] << " using the " << allocator.getName() << " allocator."
Copy link
Member

@rhornung67 rhornung67 Jul 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using memset to set an array of values to '0' and printing out the first value may not be convincing to some since sometimes memory allocations are initialized to zero by default. What do you think of doing an example like this https://www.geeksforgeeks.org/cpp/memset-in-cpp/ or something similar where the value is more convincing?

// << std::endl;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, what do you think about doing a realloc operation after the memset that grows the array and then show that the values set by memset are preserved, but the new array entries are uninitialized? I think it would make the example more interesting.


// TODO: deallocate the array

Expand Down
12 changes: 10 additions & 2 deletions Intro_Tutorial/lessons/03_umpire_allocator/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ deallocate memory.
The fundamental concept for accessing memory through Umpire is the
`umpire::Allocator`. An `umpire::Allocator` is a C++ object that can be used to
allocate and deallocate memory, as well as query a pointer to get
information about it.
information about it. (Note: in this lesson, we will see how to query the name of the Allocator!)

All `umpire::Allocator` objects are created and managed by Umpire’s
`umpire::ResourceManager`. To create an allocator, first obtain a handle to the
Expand All @@ -30,6 +30,14 @@ the desired size for your allocation:
void* memory = allocator.allocate(size in bytes);
```

Moving and modifying data in a heterogenous memory system can be annoying since you
have to keep track of the source and destination, and often use vendor-specific APIs
to perform the modifications. In Umpire, all data modification and movement, regardless
of memory resource or platform, is done using Operations.

Next, we will use the `memset` Operator provided by Umpire's Resource Manager to
set the memory we just allocated to zero.

Don't forget to deallocate your memory afterwards!

For more details, you can check out the Umpire documentation:
Expand All @@ -40,5 +48,5 @@ Once you have made your changes, you can compile and run the lesson:
```
$ make 03_umpire_allocator
$ ./bin/03_umpire_allocator
Address of data: 0x?????
Allocated 800 bytes and set to 0 using the HOST allocator.
```
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,13 @@ int main()
auto allocator = rm.getAllocator("HOST");
data = static_cast<double*>(allocator.allocate(100*sizeof(double)));

std::cout << "Address of data: " << data << std::endl;
// TODO: use the resource manager to memset your array to 0
rm.memset(data, 0);

// TODO: uncomment this print statement
std::cout << "Allocated " << (100 * sizeof(double)) << " bytes and set to "
<< data[0] << " using the " << allocator.getName() << " allocator."
<< std::endl;

// TODO: deallocate the array
allocator.deallocate(data);
Expand Down