| 17 | */ |
| 18 | |
| 19 | void execute_example(char* input_data, const size_t in_bytes) |
| 20 | { |
| 21 | cudaStream_t stream; |
| 22 | cudaStreamCreate(&stream); |
| 23 | |
| 24 | // First, initialize the data on the host. |
| 25 | |
| 26 | // compute chunk sizes |
| 27 | size_t* host_uncompressed_bytes; |
| 28 | const size_t chunk_size = 65536; |
| 29 | const size_t batch_size = (in_bytes + chunk_size - 1) / chunk_size; |
| 30 | |
| 31 | char* device_input_data; |
| 32 | cudaMalloc(&device_input_data, in_bytes); |
| 33 | cudaMemcpyAsync(device_input_data, input_data, in_bytes, cudaMemcpyHostToDevice, stream); |
| 34 | |
| 35 | cudaMallocHost(&host_uncompressed_bytes, sizeof(size_t)*batch_size); |
| 36 | for (size_t i = 0; i < batch_size; ++i) { |
| 37 | if (i + 1 < batch_size) { |
| 38 | host_uncompressed_bytes[i] = chunk_size; |
| 39 | } else { |
| 40 | // last chunk may be smaller |
| 41 | host_uncompressed_bytes[i] = in_bytes - (chunk_size*i); |
| 42 | } |
| 43 | } |
| 44 | |
| 45 | // Setup an array of pointers to the start of each chunk |
| 46 | void ** host_uncompressed_ptrs; |
| 47 | cudaMallocHost(&host_uncompressed_ptrs, sizeof(size_t)*batch_size); |
| 48 | for (size_t ix_chunk = 0; ix_chunk < batch_size; ++ix_chunk) { |
| 49 | host_uncompressed_ptrs[ix_chunk] = device_input_data + chunk_size*ix_chunk; |
| 50 | } |
| 51 | |
| 52 | size_t* device_uncompressed_bytes; |
| 53 | void ** device_uncompressed_ptrs; |
| 54 | cudaMalloc(&device_uncompressed_bytes, sizeof(size_t) * batch_size); |
| 55 | cudaMalloc(&device_uncompressed_ptrs, sizeof(size_t) * batch_size); |
| 56 | |
| 57 | cudaMemcpyAsync(device_uncompressed_bytes, host_uncompressed_bytes, sizeof(size_t) * batch_size, cudaMemcpyHostToDevice, stream); |
| 58 | cudaMemcpyAsync(device_uncompressed_ptrs, host_uncompressed_ptrs, sizeof(size_t) * batch_size, cudaMemcpyHostToDevice, stream); |
| 59 | |
| 60 | // Then we need to allocate the temporary workspace and output space needed by the compressor. |
| 61 | size_t temp_bytes; |
| 62 | nvcompBatchedLZ4CompressGetTempSize(batch_size, chunk_size, nvcompBatchedLZ4DefaultOpts, &temp_bytes); |
| 63 | void* device_temp_ptr; |
| 64 | cudaMalloc(&device_temp_ptr, temp_bytes); |
| 65 | |
| 66 | // get the maxmimum output size for each chunk |
| 67 | size_t max_out_bytes; |
| 68 | nvcompBatchedLZ4CompressGetMaxOutputChunkSize(chunk_size, nvcompBatchedLZ4DefaultOpts, &max_out_bytes); |
| 69 | |
| 70 | // Next, allocate output space on the device |
| 71 | void ** host_compressed_ptrs; |
| 72 | cudaMallocHost(&host_compressed_ptrs, sizeof(size_t) * batch_size); |
| 73 | for(size_t ix_chunk = 0; ix_chunk < batch_size; ++ix_chunk) { |
| 74 | cudaMalloc(&host_compressed_ptrs[ix_chunk], max_out_bytes); |
| 75 | } |
| 76 | |