Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calls to malloc/free from inside HIP kernels #175

Open
pvelesko opened this issue Oct 2, 2022 · 9 comments
Open

Calls to malloc/free from inside HIP kernels #175

pvelesko opened this issue Oct 2, 2022 · 9 comments
Labels
enhancement New feature or request

Comments

@pvelesko
Copy link
Collaborator

pvelesko commented Oct 2, 2022

ROCm/HIP#2975

How do we enable this? @pjaaskel @Kerilk

@pvelesko pvelesko added the enhancement New feature or request label Oct 2, 2022
@pjaaskel
Copy link
Collaborator

pjaaskel commented Oct 3, 2022

The basic plan so far has been to add a shadow buffer to the kernel which is basically the "heap" when the kernel calls malloc/free and implement dynamic memory management by returning chunks from the buffer.

@pvelesko
Copy link
Collaborator Author

pvelesko commented Oct 3, 2022

Can't we do this in SPIR-V?

@pjaaskel
Copy link
Collaborator

pjaaskel commented Oct 3, 2022

OpenCL (and thus SPIR-V in this case) doesn't support device-side dynamic memory allocation. We could define a new OpenCL extension that does, but it's better to provide a portable solution that works with the current Intel drivers.

@pvelesko
Copy link
Collaborator Author

pvelesko commented Oct 3, 2022

SPIR-V Specification
3.32.8 Memory Instructions
OpVariable
Allocate an object in memory, resulting in a pointer to it, which can be used with OpLoad and OpStore.

Why can't we use this?

@pjaaskel
Copy link
Collaborator

pjaaskel commented Oct 3, 2022

It's for static (compile time size known) memory allocation.

@pvelesko
Copy link
Collaborator Author

pvelesko commented Oct 3, 2022

Ah, I see.

@Kerilk
Copy link
Contributor

Kerilk commented Oct 3, 2022

Not much other way around this without an extension. The size of the buffer to allocate will be a problem though, and a hint (or upper bound) regarding the amount of memory involved would be very useful here, unfortunately in the general case this will be intractable.

Drivers that have device side enqueue must have the necessary functionalities already, so it may be an easy extension for them to implement if we define it right.

@Sarbojit2019
Copy link
Collaborator

I played around device malloc implementation in CUDA11 and here is my observation :

  1. malloc (heap size) is allocated once per device.
  2. Looks like default size is 8MB which user can increase/decrease by using cudaDeviceSetLimit(cudaLimitMallocHeapSize, size).
  3. Once kernel is launched heap size can't be changed.

With above observation I think as @pjaaskel mentioned in his response having buffer allocated a chunk of memory of fixed size will be a valid approach. Only point I have is this is device limit hence buffer/heap should be tied to per device not per kernel. Below is the test I used to check cuda behavior

#include <iostream>
#include <cuda_runtime.h>

__global__ void malloc__(int size) {
    int* ptr = (int*)malloc(size);
    if (ptr) {
        printf("1. Passed\n");
    } else {
        printf("1. Failed\n");
    }
}

__global__ void malloc__2(int size) {
    int* ptr = (int*)malloc(size);
    if (ptr) {
        printf("2. Passed\n");
    } else {
        printf("2. Failed\n");
    }
}
int main() {
    size_t limit_val =0;
    cudaError_t status = cudaDeviceGetLimit(&limit_val, cudaLimitMallocHeapSize);
    std::cout<<"Status : "<<cudaGetErrorName(status)<<std::endl;
    std::cout<<"limit_val = "<<limit_val<<std::endl;
    malloc__<<<1,1>>>((1024*1024*7));
    cudaDeviceSynchronize();

    // change the limit
    status = cudaDeviceSetLimit(cudaLimitMallocHeapSize, (limit_val*2));
    status = cudaDeviceGetLimit(&limit_val, cudaLimitMallocHeapSize);
    std::cout<<"Status : "<<cudaGetErrorName(status)<<std::endl;
    std::cout<<"limit_val = "<<limit_val<<std::endl;
    malloc__2<<<1,1>>>((1024*1024*8));
    cudaDeviceSynchronize();
    return 0;
}

@pjaaskel
Copy link
Collaborator

https://reviews.llvm.org/rGa6213088812f this seems like an interesting work to build upon for device side malloc/free and possibly other services. @linehill

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants