@@ -71,16 +71,18 @@ namespace genesia::sdxl::kernels {
7171 if (threadIdx .x * 4 + j < 1000 ) training[threadIdx .x * 4 + j] = sqrtf (expm1f (-values[j]));
7272 }
7373
74- __global__ void schedule_kernel (SamplingStep* output, float * times, const float * training, const int steps) {
74+ __global__ void schedule_kernel (SamplingStep* output, float * times, const float * training, const int steps, const int total ) {
7575 const int i = blockIdx .x * blockDim .x + threadIdx .x ;
7676 if (i > steps) return ;
77- const float sigma = i == steps ? 0 .0F : training[999 - i * 1000 / steps];
78- const float next = i + 1 >= steps ? 0 .0F : training[999 - (i + 1 ) * 1000 / steps];
77+ const int position = total - steps + i;
78+ const int time = 999 - int (static_cast <long long >(position) * 1000 / total);
79+ const float sigma = i == steps ? 0 .0F : training[time];
80+ const float next = i + 1 >= steps ? 0 .0F : training[999 - int (static_cast <long long >(position + 1 ) * 1000 / total)];
7981 output[i] = {sigma, next - sigma, rsqrtf (fmaf (sigma, sigma, 1 .0F ))};
80- if (i < steps) times[i] = float (999 - i * 1000 / steps );
82+ if (i < steps) times[i] = float (time );
8183 }
8284
83- __global__ void initialize_kernel (float * state, __half* input, int * step, const std::uint64_t * seed, const SamplingStep* schedule, const int count) {
85+ __global__ void initialize_kernel (float * state, __half* input, int * step, const std::uint64_t * seed, const SamplingStep* schedule, const int count, const float * source, const bool full_noise ) {
8486 const int i = blockIdx .x * blockDim .x + threadIdx .x ;
8587 if (i >= count / 4 ) return ;
8688 uint4 counter{static_cast <unsigned >(i), 0 , 0 , 0 };
@@ -98,8 +100,15 @@ namespace genesia::sdxl::kernels {
98100 sincosf (float (counter.w ) * 0x1p-32F * 6 .283185307179586F , &sine1, &cosine1);
99101 const float radius0 = sqrtf (-2 .0F * logf ((float (counter.x ) + 1 .0F ) * 0x1p-32F ));
100102 const float radius1 = sqrtf (-2 .0F * logf ((float (counter.z ) + 1 .0F ) * 0x1p-32F ));
101- const float scale = sqrtf (fmaf (schedule[0 ].sigma , schedule[0 ].sigma , 1 .0F ));
102- const float4 values{radius0 * sine0 * scale, radius0 * cosine0 * scale, radius1 * sine1 * scale, radius1 * cosine1 * scale};
103+ const float scale = full_noise ? sqrtf (fmaf (schedule[0 ].sigma , schedule[0 ].sigma , 1 .0F )) : schedule[0 ].sigma ;
104+ float4 values{radius0 * sine0 * scale, radius0 * cosine0 * scale, radius1 * sine1 * scale, radius1 * cosine1 * scale};
105+ if (source) {
106+ const float4 original = reinterpret_cast <const float4 *>(source)[i];
107+ values.x += original.x ;
108+ values.y += original.y ;
109+ values.z += original.z ;
110+ values.w += original.w ;
111+ }
103112 reinterpret_cast <float4 *>(state)[i] = values;
104113 const float data[4 ]{values.x , values.y , values.z , values.w };
105114#pragma unroll
@@ -148,6 +157,24 @@ namespace genesia::sdxl::kernels {
148157 if (stopped || completed == count) ::cuda::atomic_ref<std::uint32_t , ::cuda::thread_scope_system>{control->stage }.store (static_cast <std::uint32_t >(stopped ? Stage::cancelled : Stage::decoding), ::cuda::memory_order_release);
149158 }
150159
160+ __global__ void image_encode_kernel (__nv_bfloat16* output, const std::uint8_t * input, const int count) {
161+ const int i = blockIdx .x * blockDim .x + threadIdx .x ;
162+ if (i < count) output[i] = __nv_bfloat16 (float (input[i]) * (2 .0F / 255 .0F ) - 1 .0F );
163+ }
164+
165+ __global__ void encoder_pad_kernel (__nv_bfloat16* output, const __nv_bfloat16* input, const int height, const int width, const int channels) {
166+ const int i = blockIdx .x * blockDim .x + threadIdx .x ;
167+ if (i >= (height + 1 ) * (width + 1 ) * channels) return ;
168+ const int x = i / channels % (width + 1 );
169+ const int y = i / channels / (width + 1 );
170+ output[i] = x < width && y < height ? input[(y * width + x) * channels + i % channels] : __nv_bfloat16 (0 .0F );
171+ }
172+
173+ __global__ void latent_encode_kernel (float * output, const __nv_bfloat16* moments, const int count) {
174+ const int i = blockIdx .x * blockDim .x + threadIdx .x ;
175+ if (i < count) output[i] = float (moments[i / 4 * 8 + i % 4 ]) * 0 .13025F ;
176+ }
177+
151178 __global__ void latent_decode_kernel (__nv_bfloat16* output, const float * input, const int count) {
152179 const int i = blockIdx .x * blockDim .x + threadIdx .x ;
153180 if (i < count) output[i] = __nv_bfloat16 (input[i] / 0 .13025F );
@@ -184,11 +211,11 @@ namespace genesia::sdxl::kernels {
184211 void training_sigmas (const ::cuda::stream_ref stream, float * output) {
185212 ::cuda::launch (stream, ::cuda::make_config(::cuda::make_hierarchy(::cuda::grid_dims(1 ), ::cuda::block_dims(256 ))), training_kernel, output);
186213 }
187- void prepare_schedule (const ::cuda::stream_ref stream, SamplingStep* output, float * times, const float * training, const int steps) {
188- ::cuda::launch (stream, ::cuda::make_config(::cuda::make_hierarchy(::cuda::grid_dims((steps + 256 ) / 256), ::cuda::block_dims(256 ))), schedule_kernel, output, times, training, steps);
214+ void prepare_schedule (const ::cuda::stream_ref stream, SamplingStep* output, float * times, const float * training, const int steps, const float denoise ) {
215+ ::cuda::launch (stream, ::cuda::make_config(::cuda::make_hierarchy(::cuda::grid_dims((steps + 256 ) / 256), ::cuda::block_dims(256 ))), schedule_kernel, output, times, training, steps, static_cast<int>(steps / double (denoise)) );
189216 }
190- void initialize (const ::cuda::stream_ref stream, float * state, void * input, int * step, const std::uint64_t * seed, const SamplingStep* schedule, const int count) {
191- ::cuda::launch (stream, ::cuda::make_config(::cuda::make_hierarchy(::cuda::grid_dims((count / 4 + 255 ) / 256), ::cuda::block_dims(256 ))), initialize_kernel, state, static_cast<__half*>(input), step, seed, schedule, count);
217+ void initialize (const ::cuda::stream_ref stream, float * state, void * input, int * step, const std::uint64_t * seed, const SamplingStep* schedule, const int count, const float * source, const bool full_noise ) {
218+ ::cuda::launch (stream, ::cuda::make_config(::cuda::make_hierarchy(::cuda::grid_dims((count / 4 + 255 ) / 256), ::cuda::block_dims(256 ))), initialize_kernel, state, static_cast<__half*>(input), step, seed, schedule, count, source, full_noise );
192219 }
193220 void snapshot_begin (const ::cuda::stream_ref stream, int * selected, SnapshotSlot* slots) {
194221 ::cuda::launch (stream, ::cuda::make_config(::cuda::make_hierarchy(::cuda::grid_dims(1 ), ::cuda::block_dims(1 ))), snapshot_begin_kernel, selected, slots);
@@ -206,6 +233,15 @@ namespace genesia::sdxl::kernels {
206233 void advance (const ::cuda::stream_ref stream, int * step, const int count, const cudaGraphConditionalHandle loop, const cudaGraphConditionalHandle decode, Control* control) {
207234 ::cuda::launch (stream, ::cuda::make_config(::cuda::make_hierarchy(::cuda::grid_dims(1 ), ::cuda::block_dims(1 ))), advance_kernel, step, count, loop, decode, control);
208235 }
236+ void image_encode (const ::cuda::stream_ref stream, void * output, const std::uint8_t * pixels, const int count) {
237+ ::cuda::launch (stream, ::cuda::make_config(::cuda::make_hierarchy(::cuda::grid_dims((count + 255 ) / 256), ::cuda::block_dims(256 ))), image_encode_kernel, static_cast<__nv_bfloat16*>(output), pixels, count);
238+ }
239+ void encoder_pad (const ::cuda::stream_ref stream, void * output, const void * input, const int height, const int width, const int channels) {
240+ ::cuda::launch (stream, ::cuda::make_config(::cuda::make_hierarchy(::cuda::grid_dims(((height + 1 ) * (width + 1 ) * channels + 255) / 256), ::cuda::block_dims(256 ))), encoder_pad_kernel, static_cast<__nv_bfloat16*>(output), static_cast<const __nv_bfloat16*>(input), height, width, channels);
241+ }
242+ void latent_encode (const ::cuda::stream_ref stream, float * output, const void * moments, const int count) {
243+ ::cuda::launch (stream, ::cuda::make_config(::cuda::make_hierarchy(::cuda::grid_dims((count + 255 ) / 256), ::cuda::block_dims(256 ))), latent_encode_kernel, output, static_cast<const __nv_bfloat16*>(moments), count);
244+ }
209245 void latent_decode (const ::cuda::stream_ref stream, void * output, const float * latent, const int count) {
210246 ::cuda::launch (stream, ::cuda::make_config(::cuda::make_hierarchy(::cuda::grid_dims((count + 255 ) / 256), ::cuda::block_dims(256 ))), latent_decode_kernel, static_cast<__nv_bfloat16*>(output), latent, count);
211247 }
0 commit comments